Close

Uitgebreid Git log

Elk versiebeheersysteem is bedoeld om wijzigingen in je code vast te leggen. Dit geeft je de mogelijkheid om terug te gaan in de geschiedenis van je project om te zien wie wat heeft bijgedragen, om uit te zoeken waar bugs zijn geïntroduceerd en om problematische wijzigingen terug te draaien. Maar al deze geschiedenis beschikbaar hebben is nutteloos als je niet weet hoe je ermee moet navigeren. Dat is waar de opdracht git log van pas komt.

Je zou de basisopdracht git log nu al moeten kennen voor het weergeven van commits. Maar je kunt deze output wijzigen door veel verschillende parameters aan git log door te geven.

De geavanceerde functies van git log kunnen in twee categorieën worden opgedeeld: het opmaken van hoe elke commit wordt weergegeven en het filteren van de commits worden opgenomen in de uitvoer. Samen geven deze twee vaardigheden je de mogelijkheid om terug te gaan naar je project en alle informatie te vinden die je ooit nodig zou kunnen hebben.


Log-uitvoer opmaken


Allereerst wordt in dit artikel gekeken naar de vele manieren waarop de uitvoer van git log kan worden geformatteerd. De meeste manieren zijn in de vorm van vlaggen waarmee je meer of minder informatie kunt opvragen via git log.

Als je niet tevreden bent met de standaardopmaak van git-log, kun je met de aliasfunctie van git config een sneltoets te maken voor een van de opmaakopties die hierna worden besproken. In de opdracht git config lees je hoe je een alias instelt.

Oneline

De vlag --oneline condenseert elke commit tot één regel. Standaard worden alleen de commit-ID en de eerste regel van het commitbericht weergegeven. Je normale uitvoer van git-log --oneline ziet er ongeveer zo uit:

0e25143 Merge branch 'feature'
ad8621a Fix a bug in the feature
16b36c6 Add a new feature
23ad9ad Add the initial code base

Dit is erg handig om een algemeen overzicht van je project te krijgen.

Databases
gerelateerd materiaal

Een volledige Git-repository verplaatsen

Logo Bitbucket
Oplossing bekijken

Git leren met Bitbucket Cloud

Decorate

Vaak is het nuttig om te weten aan welke branch of tag elke commit is gekoppeld. De vlag --decorate zorgt ervoor dat git log alle referenties weergeeft (bijv. branches, tags enz.) die naar elke commit verwijzen.

Dit kan gecombineerd worden met andere configuratieopties. Als je bijvoorbeeld git log --oneline --decorate uitvoert, wordt de commit-geschiedenis als volgt ingedeeld:

0e25143 (HEAD, main) Merge branch 'feature'
ad8621a (feature) Fix a bug in the feature
16b36c6 Add a new feature
23ad9ad (tag: v0.9) Add the initial code base

Dit laat je weten dat de bovenste commit ook is uitgecheckt (aangeduid met HEAD) en dat het ook het tip van de main-branch is. De tweede commit heeft een andere branch die ernaar verwijst, genaamd feature, en tot slot is de 4e commit getagd als v0.9.

Branches, tags, HEAD en de commit-geschiedenis zijn bijna alle informatie in je Git-repository, dus dit geeft je een vollediger beeld van de logische structuur van je repository.

Diff's

De opdracht git log bevat veel opties om diff's weer te geven bij elke commit. Twee van de meest gebruikte opties zijn --stat en -p.

De optie --stat geeft het aantal invoegingen en verwijderingen weer in elk bestand dat door elke commit is gewijzigd (merk op dat het wijzigen van een regel wordt voorgesteld als 1 invoeging en 1 verwijdering). Dit is handig als je een korte samenvatting wilt van de wijzigingen die door elke commit zijn geïntroduceerd. De volgende commit heeft bijvoorbeeld 67 regels aan het bestand hello.py toegevoegd en 38 regels verwijderd:

commit f2a238924e89ca1d4947662928218a06d39068c3
Author: John <john@example.com>
Date:   Fri Jun 25 17:30:28 2014 -0500

    Add a new feature

 hello.py | 105 ++++++++++++++++++++++++-----------------
 1 file changed, 67 insertion(+), 38 deletions(-)

Het aantal tekens + en - naast de bestandsnaam geeft het relatieve aantal wijzigingen aan in elk bestand dat door de commit is gewijzigd. Dit geeft je een idee waar de wijzigingen voor elke commit te vinden zijn.

Als je de daadwerkelijke wijzigingen wilt zien die door elke commit zijn geïntroduceerd, kun je de -p optie aan git log toevoegen. Dit geeft de volledige patch weer die die commit vertegenwoordigt:

commit 16b36c697eb2d24302f89aa22d9170dfe609855b
Author: Mary <mary@example.com>
Date:   Fri Jun 25 17:31:57 2014 -0500

    Fix a bug in the feature

diff --git a/hello.py b/hello.py
index 18ca709..c673b40 100644
--- a/hello.py
+++ b/hello.py
@@ -13,14 +13,14 @@ B
-print("Hello, World!")
+print("Hello, Git!")

Voor commits met veel veranderingen kan de resulterende output behoorlijk lang en omslachtig zijn. Als je een volledige patch weergeeft, ben je meestal op zoek naar een specifieke wijziging. Hiervoor wil je een doelgerichte optie gebruiken.

De shortlog

De opdracht git shortlog is een speciale versie van git log, bedoeld voor het maken van releaseaankondigingen. Elke commit wordt gegroepeerd op auteur en de eerste regel van elk commit-bericht wordt weergegeven. Dit is een makkelijke manier om te zien wie aan wat heeft gewerkt.

Als twee ontwikkelaars bijvoorbeeld 5 commits aan een project hebben bijgedragen, kan de output van git shortlog er als volgt uitzien:

Mary (2):
      Fix a bug in the feature
      Fix a serious security hole in our framework

John (3):
      Add the initial code base
      Add a new feature
      Merge branch 'feature'

Git shortlog sorteert de output standaard op auteursnaam, maar je kunt ook de optie -n gebruiken om te sorteren op het aantal commits per auteur.

grafieken

De optie --graph tekent een ASCII-grafiek die de branchestructuur van de commit-geschiedenis weergeeft. Dit wordt vaak gebruikt in combinatie met de opdrachten --oneline en --decorate om gemakkelijker te kunnen zien welke commit bij welke branch hoort:

git log --graph --oneline --decorate

Voor een eenvoudige repository met slechts 2 branches levert dit het volgende op:

*   0e25143 (HEAD, main) Merge branch 'feature'
|\  
| * 16b36c6 Fix a bug in the new feature
| * 23ad9ad Start a new feature
* | ad8621a Fix a critical security issue
|/  
* 400e4b7 Fix typos in the documentation
* 160e224 Add the initial code base

Het sterretje geeft aan in welke branch de commit was. De bovenstaande grafiek laat ons dus zien dat de commits 23ad9ad en 16b36c6 betrekking hebben op een topic-branch en de rest op de main-branch.

Hoewel dit een leuke optie is voor eenvoudige repository's, ben je waarschijnlijk beter af met een volledigere visualisatietool zoals gitk of Sourcetree voor projecten met veel branches.

Aangepaste opmaak

Voor al je andere behoeften op het gebied van de opmaak van git log kun je de optie --pretty=format:"" gebruiken. Zo kun je elke commit weergeven zoals je wilt, met behulp van tijdelijke aanduidingen in printf stijl.

De tekens %cn, %h en %cd in de volgende opdracht worden bijvoorbeeld vervangen door respectievelijk de naam van de committer, de afgekorte commithash en de datum van de committer.

git log --pretty=format:"%cn committed %h on %cd"

Dit resulteert in de volgende opmaak voor elke commit:

John committed 400e4b7 on Fri Jun 24 12:30:04 2014 -0500 John committed 89ab2cf on Thu Jun 23 17:09:42 2014 -0500 Mary committed 180e223 on Wed Jun 22 17:21:19 2014 -0500 John committed f12ca28 on Wed Jun 22 13:50:31 2014 -0500

De volledige lijst met tijdelijke aanduidingen is te vinden in het gedeelte Pretty Formats op de pagina git Llog van de handleiding.

Behalve dat je alleen de informatie kunt weergeven waarin je geïnteresseerd bent, is de optie --pretty=format:"" vooral handig als je de output van git log met een pipe probeert door te geven naar een andere opdracht.

De commit-geschiedenis filteren


De opmaak van de manier waarop elke commit wordt weergegeven, is slechts de helft van de opgave om git log te leren. De andere helft is begrijpen hoe je door de commit-geschiedenis moet navigeren. In de rest van dit artikel worden enkele geavanceerde manieren beschreven om specifieke commits uit je projectgeschiedenis te selecteren met behulp van git log. Deze kunnen allemaal worden gecombineerd met elk van de hierboven besproken opmaakopties.

Op aantal

De meest eenvoudige filteroptie voor git log is het beperken van het aantal commits dat wordt weergegeven. Als je alleen geïnteresseerd bent in de laatste paar commits, bespaart dit je de moeite om alle commits op een pagina te bekijken.

Je kunt de output van git log beperken door de optie -- toe te voegen. Met de volgende opdracht worden bijvoorbeeld alleen de drie meest recente commits weergegeven.

git log -3

Op datum

Als je op zoek bent naar een commit voor een bepaald tijdsbestek, kun je de vlaggen --after of --before gebruiken om commits op datum te filteren. Beide accepteren verschillende datumnotaties als parameter. De volgende opdracht toont bijvoorbeeld alleen commits die zijn aangemaakt na 1 juli 2014 (inclusief):

git log --after="2014-7-1"

Je kunt ook relatieve referenties invoeren, zoals "1 week ago" en "yesterday":

git log --after="yesterday"

Om te zoeken naar commits die zijn gemaakt tussen twee datums, kun je zowel een --before als --after datum opgeven. Om bijvoorbeeld alle commits weer te geven die zijn toegevoegd tussen 1 juli 2014 en 4 juli 2014, zou je het volgende gebruiken:

git log --after="2014-7-1" --before="2014-7-4"

Voor commits met veel veranderingen kan de resulterende output behoorlijk lang en omslachtig zijn. Als je een volledige patch weergeeft, ben je meestal op zoek naar een specifieke wijziging. Hiervoor wil je een doelgerichte optie gebruiken.

Op auteur

Als je alleen op zoek bent naar commits die door een bepaalde gebruiker zijn gemaakt, gebruik dan de vlag --author. Dit accepteert een reguliere expressie en retourneert alle commits waarvan de auteur met dat patroon overeenkomt. Als je precies weet naar wie je op zoek bent, kun je een gewone tekenreeks gebruiken in plaats van een reguliere expressie:

git log --author="John"

Hiermee worden alle commits weergegeven waarvan de auteursnaam John bevat. De naam van de auteur hoeft niet exact overeen te komen, maar moet alleen de gespecificeerde zin bevatten.

Je kunt ook reguliere expressies gebruiken om complexere zoekopdrachten uit te voeren. Met de volgende opdracht wordt bijvoorbeeld gezocht naar commits van Mary of John.

git log --author="John\|Mary"

Let op: het e-mailadres van de auteur staat ook bij de naam van de auteur. Je kunt deze optie dus ook gebruiken om op e-mail te zoeken.

Als in je workflow een onderscheid wordt gemaakt tussen committers en auteurs, dan werkt de vlag van --committer op dezelfde manier.

Op bericht

Gebruik de vlag --grep om commits te filteren op basis van hun commit-bericht. Dit werkt precies zoals de hiervoor besproken vlag --author, maar matcht tegen het commit-bericht in plaats van de auteur.

Als je team bijvoorbeeld relevante issuenummers opneemt in elk commit-bericht, kun je zoiets als het volgende gebruiken om alle commits met betrekking tot dat issue te pullen:

git log --grep="JRA-224:"

Je kunt de parameter -i ook doorgeven aan git log om ervoor te zorgen dat verschillen tussen hoofdletters en kleine letters worden genegeerd tijdens het matchen van patronen.

Op bestand

Vaak ben je alleen geïnteresseerd in wijzigingen die in een bepaald bestand zijn aangebracht. Om de geschiedenis van een bestand weer te geven, hoef je alleen maar het bestandspad door te geven. Het volgende retourneert bijvoorbeeld alle commits die betrekking hadden op het bestand foo.py of bar.py:

git log -- foo.py bar.py

De parameter -- wordt gebruikt om bij git log aan te geven dat de volgende argumenten bestandspaden zijn en niet branchnamen. Als er geen kans op verwarring met een branch bestaat, kun je -- weglaten.

Op inhoud

Het is ook mogelijk te zoeken naar commits die een bepaalde regel broncode invoeren of verwijderen. Dit wordt een pickaxe genoemd en heeft de vorm -S-"". Als je bijvoorbeeld wilt weten wanneer de string Hello, World! is toegevoegd aan een bestand in het project, zou je de volgende opdracht kunnen gebruiken:

git log -S"Hello, World!"

Als je wilt zoeken met een reguliere expressie in plaats van met een string, kun je in plaats daarvan de vlag -G"" gebruiken.

Dit is een zeer krachtige tool voor foutopsporing, omdat je hiermee alle commits kunt vinden die betrekking hebben op een bepaalde regel code. Het kan je zelfs laten zien wanneer een regel is gekopieerd of verplaatst naar een ander bestand.

Op bereik

Je kunt een bereik aan commits aan git log doorgeven om alleen de commits in dat bereik weer te geven. Het bereik wordt gespecificeerd in de volgende indeling, waarbij en commitreferenties zijn:

git log ..

Deze opdracht is vooral handig als je branchingreferenties gebruikt als parameter. Het is een eenvoudige manier om de verschillen tussen twee branches te laten zien. Bekijk de volgende opdracht:

git log main..feature

Het bereik main..feature bevat alle commits die in de feature-branch staan, maar niet in de main-branch. Met andere woorden, dit is hoe ver deze feature is gevorderd sinds ze is afgetakt van de main. Je kunt dit als volgt visualiseren:

Een vertakking in de geschiedenis detecteren met behulp van bereiken

Let op: als je de volgorde van het bereik wijzigt (feature..main), krijg je in main alle commits, maar niet in feature. Als git log voor beide versies commits uitvoert, dan betekent dit dat je geschiedenis uiteegelopen is.

Commits filteren en samenvoegen

Git log bevat standaard commits voor samenvoegen in de uitvoer. Maar als je team een beleid hanteert dat altijd samenvoegt (dat wil zeggen dat je upstream-wijzigingen samenvoegt in topic-branches in plaats van de topic-branch te rebaseren naar de upstream-branch), dan heb je veel externe commits voor samenvoeging in je projectgeschiedenis.

Je kunt voorkomen dat git log deze samenvoegingscommits weergeeft door de vlag --no-merges toe te voegen:

git log --no-merges

Aan de andere kant, als je alleen geïnteresseerd bent in de samenvoegcommits, kun je de vlag --merges gebruiken:

git log --merges

Dit is het resultaat van alle commits die minstens twee bovenliggende elementen hebben.

Samenvatting


Je zou het nu vrij gemakkelijk moeten vinden om de geavanceerde parameters van git log te gebruiken om de uitvoer op te maken en te selecteren welke commits je wilt weergeven. Dit geeft je de mogelijkheid om precies uit je projectgeschiedenis te pullen wat je nodig hebt.

Deze nieuwe vaardigheden vormen een belangrijk onderdeel van je Git-toolkit, maar vergeet niet dat git log vaak wordt gebruikt in combinatie met andere Git-opdrachten. Als je eenmaal de commit hebt gevonden die je zoekt, geef je die meestal door aan git checkout, git revert of een andere tool om je commitgeschiedenis te manipuleren. Zorg er dus voor dat je op de hoogte blijft van de geavanceerde functies van Git.


Deel dit artikel
Volgend onderwerp

Aanbevolen artikelen

Bookmark deze resources voor meer informatie over soorten DevOps-teams of voor voortdurende updates over DevOps bij Atlassian.

Mensen die samenwerken met een muur vol tools

Bitbucket-blog

Toelichting DevOps

DevOps-leertraject

Demo Den Feature-demo's met Atlassian-experts

Hoe Bitbucket Cloud werkt met Atlassian Open DevOps

Meld je aan voor onze DevOps-nieuwsbrief

Thank you for signing up