Cum să scrieți un mesaj Git Commit

Contenit: Introducere | Cele șapte reguli | Sfaturi

Introducere: De ce contează mesajele de confirmare bune

Dacă răsfoiți jurnalul oricărui depozit Git la întâmplare, veți descoperi probabil că mesajele sale de confirmare sunt mai mult sau mai puțin dezordonate. De exemplu, aruncați o privire la aceste bijuterii din primele mele zile de comitere pentru Spring:

$ git log --oneline -5 --author cbeams --before "Fri Mar 26 2009"e5f4b49 Re-adding ConfigurationPostProcessorTests after its brief removal in r814. @Ignore-ing the testCglibClassesAreLoadedJustInTimeForEnhancement() method as it turns out this was one of the culprits in the recent build breakage. The classloader hacking causes subtle downstream effects, breaking unrelated tests. The test method is still useful, but should only be run on a manual basis to ensure CGLIB is not prematurely classloaded, and should not be run as part of the automated build.2db0f12 fixed two build-breaking issues: + reverted ClassMetadataReadingVisitor to revision 794 + eliminated ConfigurationPostProcessorTests until further investigation determines why it causes downstream tests to fail (such as the seemingly unrelated ClassPathXmlApplicationContextTests)147709f Tweaks to package-info.java files22b25e0 Consolidated Util and MutableAnnotationUtils classes into existing AsmUtils7f96f57 polishing

Yikes. Comparați-le cu aceste comenzi mai recente din același depozit:

$ git log --oneline -5 --author pwebb --before "Sat Aug 30 2014"5ba3db6 Fix failing CompositePropertySourceTests84564a0 Rework @PropertySource early parsing logice142fd1 Add tests for ImportSelector meta-data887815f Update docbook dependency and generate epubac8326d Polish mockito usage

Ce ați prefera să citiți?

Primul variază în lungime și formă; al doilea este concis și consistent.
Primul este ceea ce se întâmplă în mod implicit; al doilea nu se întâmplă niciodată din greșeală.

În timp ce jurnalele multor depozite arată ca primul, există și excepții. Kernelul Linux și Git însuși sunt exemple excelente. Uitați-vă la Spring Boot sau la orice depozit administrat de Tim Pope.

Contributorii acestor depozite știu că un mesaj de confirmare Git bine redactat este cea mai bună modalitate de a comunica contextul despre o schimbare colegilor dezvoltatori (și, într-adevăr, celor care vor veni). Un diff vă va spune ce s-a schimbat, dar numai mesajul de confirmare vă poate spune corect de ce. Peter Hutterer punctează bine acest aspect:

Restabilirea contextului unei bucăți de cod este o risipă. Nu o putem evita complet, așa că eforturile noastre ar trebui să se îndrepte spre reducerea ei pe cât posibil. Mesajele de confirmare pot face exact acest lucru și, ca urmare, un mesaj de confirmare arată dacă un dezvoltator este un bun colaborator.

Dacă nu v-ați gândit prea mult la ceea ce face un mesaj de confirmare Git grozav, s-ar putea să fie cazul că nu ați petrecut prea mult timp folosind git log și instrumentele aferente. Există un cerc vicios aici: deoarece istoricul de confirmare este nestructurat și inconsistent, nu se petrece prea mult timp folosind sau având grijă de el. Și pentru că nu se folosește sau nu se are grijă de el, rămâne nestructurat și inconsistent.

Dar un jurnal bine îngrijit este un lucru frumos și util. git blame, revert, rebase, log, shortlog și alte subcomandate prind viață. Revizuirea comenzilor și a cererilor pull ale altora devine ceva ce merită făcut și, dintr-o dată, poate fi făcut independent. Înțelegerea motivului pentru care ceva s-a întâmplat cu luni sau ani în urmă devine nu numai posibilă, ci și eficientă.

Succesul pe termen lung al unui proiect se bazează (printre altele) pe mentenabilitatea sa, iar un mentenitor are puține instrumente mai puternice decât jurnalul proiectului său. Merită să vă faceți timp pentru a învăța cum să aveți grijă de unul în mod corespunzător. Ceea ce poate fi o bătaie de cap la început devine în curând obișnuință și, în cele din urmă, o sursă de mândrie și productivitate pentru toți cei implicați.

În această postare, abordez doar cel mai element de bază al menținerii unui istoric de confirmare sănătos: cum să scrieți un mesaj de confirmare individual. Există și alte practici importante, cum ar fi „commit squashing”, pe care nu le abordez aici. Poate voi face acest lucru într-o postare ulterioară.

Majoritatea limbajelor de programare au convenții bine stabilite cu privire la ceea ce constituie un stil idiomatic, adică denumirea, formatarea și așa mai departe. Există variații asupra acestor convenții, bineînțeles, dar majoritatea dezvoltatorilor sunt de acord că alegerea uneia și respectarea ei este mult mai bună decât haosul care rezultă atunci când fiecare își face propriul lucru.

Abordarea de către o echipă a jurnalului său de confirmare nu ar trebui să fie diferită. Pentru a crea un istoric de revizie util, echipele ar trebui mai întâi să cadă de acord asupra unei convenții a mesajelor de confirmare care să definească cel puțin următoarele trei lucruri:

Stil. Sintaxa de marcare, margini de înfășurare, gramatică, capitalizare, punctuație. Spuneți clar aceste lucruri, eliminați presupunerile și faceți totul cât mai simplu posibil. Rezultatul final va fi un jurnal remarcabil de consistent, care nu numai că este o plăcere să fie citit, dar care chiar este citit în mod regulat.

Contenit. Ce fel de informații ar trebui să conțină corpul mesajului de confirmare (dacă există)? Ce nu ar trebui să conțină?

Metadate. Cum ar trebui să se facă referire la ID-urile de urmărire a problemelor, numerele solicitărilor de extragere, etc.?

Din fericire, există convenții bine stabilite cu privire la ceea ce constituie un mesaj de confirmare Git idiomatic. Într-adevăr, multe dintre ele sunt asumate în modul în care funcționează anumite comenzi Git. Nu este nimic ce trebuie să reinventați. Urmați doar cele șapte reguli de mai jos și veți fi pe cale să comiteți ca un profesionist.

Cele șapte reguli ale unui mesaj de comitere Git excelent

Țineți minte: Toate acestea au mai fost spuse înainte.

  1. Separați subiectul de corp cu o linie goală
  2. Limitați linia subiectului la 50 de caractere
  3. Capitalizați linia subiectului
  4. Nu terminați linia subiectului cu un punct
  5. Utilizați modul imperativ în linia subiectului
  6. Încadrați corpul la 72 de caractere
  7. Utilizați corpul pentru a explica ce și de ce vs. cum

De exemplu:

Summarize changes in around 50 characters or lessMore detailed explanatory text, if necessary. Wrap it to about 72characters or so. In some contexts, the first line is treated as thesubject of the commit and the rest of the text as the body. Theblank line separating the summary from the body is critical (unlessyou omit the body entirely); various tools like `log`, `shortlog`and `rebase` can get confused if you run the two together.Explain the problem that this commit is solving. Focus on why youare making this change as opposed to how (the code explains that).Are there side effects or other unintuitive consequences of thischange? Here's the place to explain them.Further paragraphs come after blank lines. - Bullet points are okay, too - Typically a hyphen or asterisk is used for the bullet, preceded by a single space, with blank lines in between, but conventions vary hereIf you use an issue tracker, put references to them at the bottom,like this:Resolves: #123See also: #456, #789

Separați subiectul de corp cu o linie goală

Din pagina de manual git commit:

Deși nu este obligatoriu, este o idee bună să începeți mesajul de confirmare cu o singură linie scurtă (mai puțin de 50 de caractere) care să rezume modificarea, urmată de o linie goală și apoi de o descriere mai amănunțită. Textul până la prima linie goală dintr-un mesaj de confirmare este tratat ca titlu al confirmării, iar acest titlu este utilizat în tot Git. De exemplu, Git-format-patch(1) transformă o confirmare în e-mail, și folosește titlul de pe linia Subiect și restul confirmării în corp.

În primul rând, nu orice confirmare necesită atât un subiect cât și un corp. Uneori, o singură linie este bună, mai ales atunci când modificarea este atât de simplă încât nu este necesar un context suplimentar. De exemplu:

Fix typo in introduction to user guide

Nu mai trebuie spus nimic; dacă cititorul se întreabă care a fost greșeala de tipar, poate pur și simplu să arunce o privire la modificarea în sine, adică să folosească git show sau git diff sau git log -p.

Dacă confirmați ceva de genul acesta în linia de comandă, este ușor să folosiți opțiunea -m la git commit:

$ git commit -m"Fix typo in introduction to user guide"

Dar, atunci când o confirmare merită un pic de explicații și context, trebuie să scrieți un corp. De exemplu:

Derezz the master control programMCP turned out to be evil and had become intent on world domination.This commit throws Tron's disc into MCP (causing its deresolution)and turns it back into a chess game.

Mesajele de confirmare cu corpuri nu sunt atât de ușor de scris cu opțiunea -m. Este mai bine să scrieți mesajul într-un editor de text adecvat. Dacă nu aveți deja un editor configurat pentru a fi utilizat cu Git la linia de comandă, citiți această secțiune din Pro Git.

În orice caz, separarea subiectului de corp dă roade atunci când răsfoiți jurnalul. Iată intrarea completă din jurnal:

$ git logcommit 42e769bdf4894310333942ffc5a15151222a87beAuthor: Kevin Flynn <[email protected]>Date: Fri Jan 01 00:00:00 1982 -0200 Derezz the master control program MCP turned out to be evil and had become intent on world domination. This commit throws Tron's disc into MCP (causing its deresolution) and turns it back into a chess game.

Și acum git log --oneline, care tipărește doar subiectul:

$ git log --oneline42e769 Derezz the master control program

Sau, git shortlog, care grupează comenzi în funcție de utilizator, arătând din nou doar subiectul pentru concizie:

$ git shortlogKevin Flynn (1): Derezz the master control programAlan Bradley (1): Introduce security program "Tron"Ed Dillinger (3): Rename chess program to "MCP" Modify chess program Upgrade chess programWalter Gibbs (1): Introduce protoype chess program

Există o serie de alte contexte în Git în care intervine distincția dintre subiect și corp – dar niciuna dintre ele nu funcționează corect fără linia goală dintre ele.

Limitați linia subiectului la 50 de caractere

50 de caractere nu este o limită strictă, ci doar o regulă de bază. Menținerea liniilor de subiect la această lungime asigură faptul că acestea sunt lizibile și forțează autorul să se gândească pentru o clipă la cel mai concis mod de a explica ce se întâmplă.

Tip: Dacă vă este greu să rezumați, este posibil să comiteți prea multe modificări deodată. Străduiți-vă să faceți comenzi atomice (un subiect pentru o postare separată).

Interfața de utilizare a lui GitHub este pe deplin conștientă de aceste convenții. Vă va avertiza dacă depășiți limita de 50 de caractere:

Și va trunchia orice linie de subiect mai lungă de 72 de caractere cu o elipsă:

Așa că încercați să obțineți 50 de caractere, dar considerați 72 ca fiind limita dură.

Capitalizați linia de subiect

Acest lucru este la fel de simplu pe cât pare. Începeți toate liniile de subiect cu majusculă.

De exemplu:

  • Accelerați până la 88 de mile pe oră

În loc de:

  • Accelerați până la 88 de mile pe oră

Nu încheiați linia de subiect cu un punct

Ponctuația de urmărire nu este necesară în liniile de subiect. În plus, spațiul este prețios atunci când încerci să le limitezi la 50 de caractere sau mai puțin.

Exemplu:

  • Deschideți ușile compartimentului de capsule

În loc de:

  • Deschideți ușile compartimentului de capsule.

Utilizați modul imperativ în linia subiectului

Modul imperativ înseamnă doar „vorbit sau scris ca și cum ar da o comandă sau o instrucțiune”. Câteva exemple:

  • Curăță-ți camera
  • Închide ușa
  • Scoate gunoiul

Câteva dintre cele șapte reguli despre care citești acum sunt scrise la imperativ („Înfășurați corpul la 72 de caractere”, etc.).

Imperativul poate suna puțin nepoliticos; de aceea nu îl folosim des. Dar este perfect pentru liniile de subiect pentru comiterea Git. Unul dintre motive este că Git însuși folosește imperativul ori de câte ori creează un commit în numele dumneavoastră.

De exemplu, mesajul implicit creat atunci când folosiți git merge sună:

Merge branch 'myfeature'

Și atunci când folosiți git revert:

Revert "Add the thing with the stuff"This reverts commit cc87791524aedd593cff5a74532befe7ab69ce9d.

Ou atunci când faceți clic pe butonul „Merge” pe o cerere GitHub pull request:

Merge pull request #123 from someuser/somebranch

Așa că atunci când vă scrieți mesajele de confirmare în imperativ, urmați propriile convenții încorporate de Git. De exemplu:

  • Refaceți subsistemul X pentru mai multă lizibilitate
  • Actualizați documentația de început
  • Îndepărtați metodele depreciate
  • Lansați versiunea 1.0.0

Scrierea în acest mod poate fi puțin ciudată la început. Suntem mai obișnuiți să vorbim la modul indicativ, care se referă la raportarea faptelor. De aceea, mesajele de confirmare sfârșesc adesea prin a se citi astfel:

  • Aparat o eroare cu Y
  • Schimbarea comportamentului lui X

Și uneori mesajele de confirmare sunt scrise ca o descriere a conținutului lor:

  • Mai multe corecturi pentru chestii stricate
  • Mai multe metode API noi și drăguțe

Pentru a elimina orice confuzie, iată o regulă simplă pentru a face totul corect de fiecare dată.

Un subiect de commit Git corect format ar trebui să poată completa întotdeauna următoarea propoziție:

  • Dacă se aplică, acest commit va subject line-ul tău aici

De exemplu:

De exemplu:

  • Dacă se aplică, acest commit va refactoriza subsistemul X pentru lizibilitate
  • Dacă se aplică, acest commit va actualiza documentația de inițiere
  • Dacă se aplică, acest commit va elimina metodele depreciate
  • Dacă se aplică, acest commit va lansa versiunea 1.0.0
  • Dacă se aplică, acest commit va unifica cererea pull request #123 de la user/branch

Observați cum acest lucru nu funcționează pentru celelalte forme neimperative:

  • Dacă se aplică, acest commit va rezolva un bug cu Y
  • Dacă se aplică, acest commit va schimba comportamentul lui X
  • Dacă se aplică, acest commit va aduce mai multe corecturi pentru chestii rupte
  • Dacă se aplică, acest commit va îndulci noi metode API

Amintiți-vă: Utilizarea imperativului este importantă doar în linia de subiect. Puteți relaxa această restricție atunci când scrieți corpul.

Înfășurați corpul la 72 de caractere

Git nu înfășoară niciodată textul automat. Când scrieți corpul unui mesaj de confirmare, trebuie să țineți cont de marja sa dreaptă și să înfășurați manual textul.

Recomandarea este să faceți acest lucru la 72 de caractere, astfel încât Git să aibă suficient spațiu pentru a indenta textul, păstrând în același timp totul sub 80 de caractere în total.

Un editor de text bun vă poate ajuta aici. Este ușor de configurat Vim, de exemplu, pentru a împacheta textul la 72 de caractere atunci când scrieți un commit Git. Cu toate acestea, în mod tradițional, IDE-urile au fost teribile în ceea ce privește furnizarea unui suport inteligent pentru împachetarea textului în mesajele de confirmare (deși în versiunile recente, IntelliJ IDEA a devenit în sfârșit mai bun în această privință).

Utilizați corpul pentru a explica ce și de ce vs. cum

Acest commit de la Bitcoin Core este un exemplu excelent de explicare a ceea ce s-a schimbat și de ce:

commit eb0b56b19017ab5c16c745e6da39c53126924ed6Author: Pieter Wuille <[email protected]>Date: Fri Aug 1 22:57:55 2014 +0200 Simplify serialize.h's exception handling Remove the 'state' and 'exceptmask' from serialize.h's stream implementations, as well as related methods. As exceptmask always included 'failbit', and setstate was always called with bits = failbit, all it did was immediately raise an exception. Get rid of those variables, and replace the setstate with direct exception throwing (which also removes some dead code). As a result, good() is never reached after a failure (there are only 2 calls, one of which is in tests), and can just be replaced by !eof(). fail(), clear(n) and exceptions() are just never called. Delete them.

Aruncă o privire la diff-ul complet și gândește-te cât de mult timp economisește autorul colegilor și viitorilor commiteri prin faptul că își face timp să ofere acest context aici și acum. Dacă nu ar fi făcut-o, probabil că s-ar fi pierdut pentru totdeauna.

În cele mai multe cazuri, puteți omite detalii despre cum a fost făcută o modificare. Codul este, în general, auto-explicativ în această privință (și dacă codul este atât de complex încât trebuie explicat în proză, pentru asta sunt comentariile sursei). Concentrează-te doar pe explicarea clară a motivelor pentru care ai făcut modificarea în primul rând – modul în care funcționau lucrurile înainte de modificare (și ce era în neregulă cu asta), modul în care funcționează acum și de ce ai decis să rezolvi problema în felul în care ai făcut-o.

Fostul responsabil cu mentenanța care îți mulțumește s-ar putea să fii tu însuți!

Tips

Învață să iubești linia de comandă. Lăsați IDE-ul în urmă.

Pentru tot atâtea motive câte subcomandă Git există, este înțelept să îmbrățișați linia de comandă. Git este nebunește de puternic; IDE-urile sunt și ele, dar fiecare în moduri diferite. Folosesc un IDE în fiecare zi (IntelliJ IDEA) și am folosit altele în mod extensiv (Eclipse), dar nu am văzut niciodată o integrare IDE pentru Git care ar putea începe să egaleze ușurința și puterea liniei de comandă (odată ce o cunoști).

Certe funcții IDE legate de Git sunt neprețuite, cum ar fi apelarea git rm atunci când ștergeți un fișier și să faceți ceea ce trebuie cu git atunci când redenumiți unul. Acolo unde totul se prăbușește este atunci când începeți să încercați să comiteți, să fuzionați, să rebazați sau să faceți o analiză sofisticată a istoricului prin intermediul IDE.

Când vine vorba de mânuirea întregii puteri a Git, este linia de comandă până la capăt.

Amintește-ți că, indiferent dacă folosești Bash sau Zsh sau Powershell, există scripturi de completare a tabulației care te scutesc de o mare parte din durerea de a reține subcomandațiile și comutatoarele.

Citește Pro Git

Cartea Pro Git este disponibilă online gratuit și este fantastică. Profitați de ea!

Credit imagine antet: xkcd

>.

Lasă un răspuns

Adresa ta de email nu va fi publicată.