Hogyan írjunk Git Commit üzenetet

Contents: Bevezetés | A hét szabály | Tippek

Bevezetés:

Ha bármely tetszőleges Git-tárhely naplóját böngészed, valószínűleg azt fogod tapasztalni, hogy a commit-üzenetek többé-kevésbé kuszák. Vessünk például egy pillantást ezekre a gyöngyszemekre a Springhez való commitolásom korai napjaiból:

$ 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. Hasonlítsd össze ezekkel az újabb commitokkal ugyanabból a tárolóból:

$ 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

Melyiket olvasnád inkább?

Az előbbi változó hosszúságú és formájú; az utóbbi tömör és következetes.
Az előbbi alapértelmezés szerint történik; az utóbbi soha nem történik véletlenül.

Míg sok tároló naplója úgy néz ki, mint az előbbi, vannak kivételek. A Linux kernel és maga a Git remek példa erre. Nézzük meg a Spring Bootot, vagy bármelyik Tim Pope által kezelt tárolót.

Ezeknek a tárolóknak a közreműködői tudják, hogy egy jól megfogalmazott Git commit üzenet a legjobb módja annak, hogy egy változással kapcsolatos kontextust közöljenek a fejlesztőtársakkal (és valóban a jövőbeli önmagukkal). A diff megmondja, hogy mi változott, de csak a commit üzenet tudja megfelelően megmondani, hogy miért. Peter Hutterer jól megfogalmazza ezt a pontot:

Egy kódrészlet kontextusának újbóli megállapítása pazarlás. Teljesen elkerülni nem tudjuk, ezért az erőfeszítéseinket arra kell fordítanunk, hogy a lehető legjobban csökkentsük. A commit üzenetek pontosan erre képesek, és ennek eredményeképpen a commit üzenet megmutatja, hogy egy fejlesztő jó munkatárs-e.

Ha még nem gondolkodtál sokat azon, hogy mitől lesz egy jó Git commit üzenet, akkor lehet, hogy nem töltöttél sok időt a git log és a kapcsolódó eszközök használatával. Itt egy ördögi kör van: mivel a commit-előzmények strukturálatlanok és következetlenek, az ember nem tölt sok időt a használatukkal vagy a gondozásukkal. És mivel nem használják vagy nem törődnek vele, strukturálatlan és következetlen marad.

De egy jól gondozott napló gyönyörű és hasznos dolog. git blame, revert, rebase, log, shortlog és más alparancsok életre kelnek. Mások commitjainak és pull requestjeinek átnézése olyanná válik, amit érdemes csinálni, és hirtelen önállóan is elvégezhetővé válik. Annak megértése, hogy valami miért történt hónapokkal vagy évekkel ezelőtt, nem csak lehetségessé, de hatékonnyá is válik.

Egy projekt hosszú távú sikere (többek között) a karbantarthatóságán múlik, és a karbantartónak kevés erősebb eszköze van, mint a projekt naplója. Érdemes időt szánni arra, hogy megtanuljuk, hogyan kell megfelelően gondozni egyet. Ami eleinte gondot okozhat, hamarosan szokássá válik, és végül minden érintett számára a büszkeség és a termelékenység forrása lesz.

Ebben a bejegyzésben csak az egészséges commit-előzmények vezetésének legalapvetőbb elemével foglalkozom: hogyan írjunk egyedi commit-üzenetet. Vannak más fontos gyakorlatok is, mint például a commit squashing, amelyekkel itt nem foglalkozom. Talán majd egy következő bejegyzésben foglalkozom vele.

A legtöbb programozási nyelvnek jól bevált konvenciói vannak arra vonatkozóan, hogy mi számít idiomatikus stílusnak, azaz a megnevezések, a formázás és így tovább. Ezeknek a konvencióknak persze vannak variációi, de a legtöbb fejlesztő egyetért abban, hogy az egyiket kiválasztani és betartani sokkal jobb, mint az a káosz, ami akkor keletkezik, amikor mindenki a saját dolgát csinálja.

A csapat commit naplójához való hozzáállása sem lehet más. A hasznos revíziós előzmények létrehozásához a csapatoknak először is meg kell állapodniuk egy commit üzenet konvencióban, amely legalább a következő három dolgot határozza meg:

Stílus. Jelölési szintaxis, margók, nyelvtan, nagybetűs írásmód, írásjelek. Írja ki ezeket a dolgokat, szüntesse meg a találgatásokat, és tegye az egészet a lehető legegyszerűbbé. A végeredmény egy figyelemre méltóan egységes napló lesz, amelyet nem csak öröm olvasni, de valóban rendszeresen el is olvassák.

Tartalom. Milyen információkat kell tartalmaznia a commit üzenet testének (ha van ilyen)? Mit ne tartalmazzon?

Metaadatok. Hogyan kell hivatkozni az issue tracking ID-kre, pull request számokra, stb.?

Szerencsére vannak jól bevált konvenciók arra vonatkozóan, hogy mitől lesz egy idiomatikus Git commit üzenet. Sőt, ezek közül sokat bizonyos Git-parancsok működésében is feltételeznek. Semmit sem kell újra feltalálnod. Csak kövesse az alábbi hét szabályt, és máris úton van ahhoz, hogy profiként végezze el a commitot.

A nagyszerű Git commit üzenet hét szabálya

Tartsd észben: Mindez már elhangzott korábban.

  1. Válaszd el a tárgyat a testtől egy üres sorral
  2. Limitáld a tárgy sort 50 karakterre
  3. A tárgy sort nagybetűvel írd
  4. Ne fejezd be a tárgy sort ponttal
  5. A tárgy sorban használj felszólító módot
  6. A testet 72 karakterre tekerd
  7. A testet használd arra, hogy megmagyarázd, mit és miért vs. hogyan

Például:

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

Válaszd el a tárgyat a törzstől egy üres sorral

A git commit manpage-ból:

Bár nem kötelező, jó ötlet a commit üzenetet egyetlen rövid (kevesebb mint 50 karakteres), a változtatást összefoglaló sorral kezdeni, amelyet egy üres sor, majd egy alaposabb leírás követ. A commit üzenetben az első üres sorig terjedő szöveget commit címként kezeljük, és ezt a címet használjuk az egész Gitben. Például a Git-format-patch(1) egy commitot e-mailbe alakít át, és a Subject sorban a címet, a bodyban pedig a commit többi részét használja.

Először is, nem minden commithoz szükséges a subject és a body is. Néha egyetlen sor is elegendő, különösen, ha a változás olyan egyszerű, hogy nincs szükség további kontextusra. Például:

Fix typo in introduction to user guide

Nem kell többet mondani; ha az olvasó kíváncsi, hogy mi volt az elírás, egyszerűen megnézheti magát a módosítást, azaz használhatja a git show vagy git diff vagy git log -p.

Ha valami ilyesmit a parancssorból commitolsz, könnyű használni a -m opciót a git commit:

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

Ha azonban egy commit megérdemel egy kis magyarázatot és kontextust, akkor testet kell írnod. Például:

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.

A testet tartalmazó commit üzeneteket nem olyan könnyű megírni a -m opcióval. Jobban jársz, ha az üzenetet egy megfelelő szövegszerkesztővel írod meg. Ha még nincs a Git parancssori használatára beállított szerkesztője, olvassa el a Pro Git ezen részét.

A tárgy és a test szétválasztása mindenesetre kifizetődő a napló böngészésekor. Itt a teljes naplóbejegyzés:

$ 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.

És most a git log --oneline, amely csak a tárgysort írja ki:

$ git log --oneline42e769 Derezz the master control program

Vagy a git shortlog, amely a commitokat felhasználó szerint csoportosítja, és ismét csak a tárgysort mutatja a tömörség kedvéért:

$ 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

A Gitben számos más kontextus van, ahol a tárgysor és a test közötti különbségtétel működik – de egyik sem működik megfelelően a közte lévő üres sor nélkül.

Limitáld a tárgysor 50 karakterre

Az 50 karakter nem egy kemény korlát, csak egy ökölszabály. A tárgysorok ilyen hosszúságban tartása biztosítja az olvashatóságot, és arra kényszeríti a szerzőt, hogy egy pillanatra elgondolkodjon azon, hogyan lehetne a legtömörebben elmagyarázni, miről van szó.

Tipp: Ha nehezen tudod összefoglalni, lehet, hogy túl sok változtatást vállalsz egyszerre. Törekedj az atomi commitokra (ez egy külön bejegyzés témája).

A GitHub felhasználói felülete teljesen tisztában van ezekkel a konvenciókkal. Figyelmeztetni fog, ha túlléped az 50 karakteres korlátot:

És a 72 karakternél hosszabb tárgysorokat ellipszissel rövidíti meg:

Szóval törekedj az 50 karakterre, de tekintsd a 72 karaktert kemény határnak.

Kezd nagybetűvel a tárgysorokat

Ez olyan egyszerű, mint amilyennek hangzik. Kezdje minden tárgysorát nagybetűvel.

Például:

  • Gyorsítson 88 mérföld per órára

Ahelyett:

  • gyorsítson 88 mérföld per órára

Ne zárja a tárgysorát ponttal

A tárgysoroknál nincs szükség írásjelekre. Ráadásul a hely is értékes, ha 50 karakterben vagy annál kevesebbben próbálod tartani őket.

Példa:

  • Nyisd ki a kapszulafedélzet ajtaját

Ahelyett, hogy:

  • Nyisd ki a kapszulafedélzet ajtaját.

A felszólító módot használd a tárgysorozatban

A felszólító mód csak annyit jelent, hogy “kimondva vagy leírva, mintha parancsot vagy utasítást adnál”. Néhány példa:

  • Takarítsd ki a szobádat
  • Zárd be az ajtót
  • Vidd ki a szemetet

A hét szabály, amiről most olvasol, mindegyike felszólító módban van írva (“Tekerd be a testet 72 karakterrel” stb.).

A felszólító mód kissé durván hangozhat; ezért nem használjuk gyakran. De tökéletes a Git commitok tárgysoraihoz. Ennek egyik oka, hogy maga a Git is használja az imperatívuszt, amikor commitot hoz létre az Ön nevében.

Az git merge használatakor létrehozott alapértelmezett üzenet például így szól:

Merge branch 'myfeature'

És a git revert használatakor:

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

Vagy amikor a “Merge” gombra kattintasz egy GitHub pull request-en:

Merge pull request #123 from someuser/somebranch

Az imperatívuszban írt commit üzenetekkel tehát a Git saját beépített konvencióit követed. Például:

  • Refactor subsystem X for readability
  • Update getting started documentation
  • Remove deprecated methods
  • Release version 1.0.0

Az ilyen módon való írás eleinte kicsit körülményes lehet. Jobban hozzászoktunk ahhoz, hogy jelzős hangnemben beszéljünk, ami a tények közléséről szól. Ezért végződnek a commit üzenetek gyakran így:

  • Fixed bug with Y
  • Changing behavior of X

És néha a commit üzeneteket a tartalmuk leírásaként írják:

  • Még több javítás elromlott dolgokhoz
  • Cukros új API-módszerek

Azért, hogy minden félreértés megszűnjön, itt egy egyszerű szabály, hogy minden alkalommal jól csináld.

Egy helyesen megformált Git commit tárgysorának mindig ki kell tudnia egészíteni a következő mondatot:

  • Ha alkalmazzák, ez a commit a tárgysorod itt lesz

Például:

  • Ha alkalmazzák, ez a commit az X alrendszert refaktorálja az olvashatóság érdekében
  • Ha alkalmazzák, ez a commit frissíti a kezdeti dokumentációt
  • Ha alkalmazzák, ez a commit eltávolítja az elavult módszereket
  • Ha alkalmazzák, ez a commit kiadja az 1. verziót.0.0
  • Ha alkalmazzuk, ez a commit beolvasztja a user/branch #123-as pull requestjét

Figyeljük meg, hogy ez nem működik a többi, nem imperatív formára:

  • Ha alkalmazzák, ez a commit javítja az Y hibáját
  • Ha alkalmazzák, ez a commit megváltoztatja az X viselkedését
  • Ha alkalmazzák, ez a commit több hibás dolgot javít
  • Ha alkalmazzák, ez a commit édes új API módszereket

Emlékezz: Az imperatívusz használata csak a tárgysorban fontos. Ezt a korlátozást lazíthatod, amikor a testet írod.

A testet 72 karakternél tekerd fel

A Git soha nem tekeri fel automatikusan a szöveget. Amikor a commit üzenet testét írja, figyelnie kell a jobb oldali margóra, és a szöveget kézzel kell becsomagolnia.

Az ajánlás szerint ezt 72 karakternél kell megtennie, hogy a Gitnek elegendő helye legyen a szöveg behúzásához, miközben összességében minden 80 karakter alatt marad.

Egy jó szövegszerkesztő segíthet ebben. Könnyen beállítható például a Vim, hogy a szöveget 72 karakternél tekerje be, amikor Git commitot ír. Hagyományosan azonban az IDE-k szörnyűek voltak abban, hogy intelligens támogatást nyújtsanak a szövegcsomagoláshoz a commit üzenetekben (bár a legújabb verziókban az IntelliJ IDEA végre jobb lett ebben a tekintetben).

A testet használd arra, hogy elmagyarázd, mit és miért vs. hogyan

Ez a Bitcoin Core-ból származó commit remek példa arra, hogy megmagyarázzuk, mi és miért változott:

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.

Vess egy pillantást a teljes diff-re, és gondolj csak bele, mennyi időt takarít meg a szerző azzal, hogy időt szakít arra, hogy itt és most megadja ezt a kontextust. Ha nem tenné, valószínűleg örökre elveszne.

A legtöbb esetben kihagyhatod a változtatás módjára vonatkozó részleteket. A kód ebből a szempontból általában önmagyarázó (és ha a kód annyira összetett, hogy prózában kell elmagyarázni, akkor erre szolgálnak a forráskommentárok). Csak arra koncentrálj, hogy világossá tedd, miért is hajtottad végre a változtatást – hogyan működtek a dolgok a változtatás előtt (és mi volt a baj vele), hogyan működnek most, és miért döntöttél úgy, hogy ezt a megoldást választod.

A leendő karbantartó, aki megköszöni neked, talán te magad leszel!

Tippek

Tanuld meg szeretni a parancssort. Hagyd magad mögött az IDE-t.

Ahány okból kifolyólag, ahány Git alparancs van, annyi okból bölcs dolog elfogadni a parancssort. A Git őrülten erős; az IDE-k is azok, de mindegyik más-más módon. Minden nap használok egy IDE-t (IntelliJ IDEA), és másokat is sokat használtam (Eclipse), de még sosem láttam olyan IDE-integrációt a Git-hez, amely megközelítené a parancssor egyszerűségét és erejét (ha már ismered).

A Git-hez kapcsolódó IDE egyes funkciói felbecsülhetetlenek, például a git rm hívása, amikor törölsz egy fájlt, és a git megfelelő használata, amikor átnevezel egy fájlt. Ahol minden szétesik, az az, amikor az IDE-n keresztül próbálsz commitolni, egyesíteni, újraalapozni, vagy kifinomult előzményelemzést végezni.

Ha a Git teljes erejének kihasználásáról van szó, akkor a parancssor az egyetlen megoldás.

Ne feledje, hogy akár a Bash-t, akár a Zsh-t vagy a Powershell-t használja, léteznek olyan lapkakiegészítő szkriptek, amelyek nagyban megkönnyítik az alparancsok és kapcsolók megjegyzését.

Read Pro Git

A Pro Git könyv online ingyenesen elérhető, és fantasztikus. Használd ki!

header image credit: xkcd

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.