Git-Protokoll für Fortgeschrittene
Der Zweck eines jeden Versionskontrollsystems ist die Dokumentierung von Änderungen an deinem Code. Dies ermöglicht dir, in deinem Projektverlauf zurückzublicken und herauszufinden, wer was beigetragen hat und wo Fehler eingeführt wurden, damit du problematische Änderungen rückgängig machen kannst. Die Verfügbarkeit dieses ganzen Verlaufs ist jedoch nutzlos, wenn du nicht weißt, wie du dich darin zurechtfindest. Hierfür gibt es den Befehl "git log".
Inzwischen solltest du bereits den grundlegenden Befehl zum Anzeigen von Commits "git log"kennen. Du kannst diese Anzeige jedoch ändern, indem du git log mit verschiedenen Parametern kombinierst.
Die erweiterten Features des Git-Protokolls können in zwei Kategorien unterteilt werden: Formatierung der Anzeige der einzelnen Commits und Filtern der anzuzeigenden Commits. Mithilfe dieser beiden Möglichkeiten bist du in der Lage, jegliche benötigten Informationen in deinem Projekt zu finden.
Protokollausgabe formatieren
In diesem Artikel behandeln wir zunächst die zahlreichen Möglichkeiten zur Formatierung des git log
-Outputs. Das geschieht hauptsächlich mithilfe von Flags. Durch Flags kannst du die mit git log
angefragten Informationen einschränken oder erweitern.
Wenn dir das Standardformat von git log
nicht gefällt, kannst du die Alias-Funktion von git config
nutzen, um eine Kurzform für eine der unten beschriebene Formatierungsoptionen festzulegen. Unter Der Befehl "git config" erfährst du, wie du einen Alias einrichtest.
Oneline
Der Zusatz --oneline
fasst einen Commit in einer einzigen Zeile zusammen. In der Standardeinstellung wird nur die Commit-ID und die erste Zeile der Commit-Nachricht angezeigt. Normalerweise sieht eine git log --oneline
-Ausgabe in etwa folgendermaßen aus:
0e25143 Merge branch 'feature'
ad8621a Fix a bug in the feature
16b36c6 Add a new feature
23ad9ad Add the initial code base
Dies ist äußerst hilfreich, um einen groben Überblick über das Projekt zu erhalten.
Zugehöriges Material
Verschieben eines vollständigen Git-Repositorys
Lösung anzeigen
Git kennenlernen mit Bitbucket Cloud
Decorate
Oft ist es sinnvoll zu wissen, welche Branches oder Tags mit Commits assoziiert sind. --decorate
weist git log
an, alle Referenzen (also Branches, Tags usw.) anzuzeigen, die auf den jeweiligen Commit verweisen.
Dies kann mit anderen Konfigurationsoptionen kombiniert werden. Der Befehl git log --oneline --decorate
formatiert den Commit-Verlauf z. B. folgendermaßen:
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
Hierdurch erfährst du, dass der oberste Commit ausgecheckt ist (indiziert durch HEAD
) und dass er sich an der Spitze des main
-Branch befindet. Der zweite Commit hat einen anderen Branch namens feature
, der auf ihn verweist, und der vierte Commit ist mit v0.9
getaggt.
Branches, Tags, HEAD
und der Commit-Verlauf machen nahezu alle Informationen in deinem Git-Repository aus. Darüber kannst du einen umfassenderen Einblick in den logischen Aufbau deines Repositorys erhalten.
Diffs
Der Befehl git log
umfasst viele Optionen für die Anzeige von Diffs für jeden Commit. Zwei der gebräuchlichsten Optionen sind --stat
und -p
.
Mit der Option --stat
werden die Anzahl von Einfügungen und Löschungen für jede einzelne Datei, die bei dem jeweiligen Commit geändert werden, angezeigt. (Beachte, dass die Bearbeitung einer Zeile als eine Einfügung und eine Löschung gezählt wird.) Dies ist hilfreich, wenn du eine kurze Zusammenfassung der Änderungen benötigst, die mit jedem Commit hinzukamen. Im folgenden Commit wurden z. B. 67 Zeilen zur Datei hello.py
hinzugefügt und 38 Zeilen entfernt.
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(-)
Die Anzahl an Zeichen (+
und -
) neben dem Dateinamen zeigt dir die relative Anzahl der Änderungen an, die mit einem Commit an einer Datei vorgenommen wurden. Das kann ein Hinweis darauf sein, wo die Änderungen eines Commits zu finden sind.
Wenn du die tatsächlichen Änderungen sehen möchtest, die mit jedem einzelnen Commit hinzukamen, kannst du die Option -p
an git log
anfügen. Dies gibt den gesamten Patch, der diesen Commit repräsentiert, zurück:
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!")
Bei Commits mit vielen Änderungen kann die Ausgabe recht lang und unübersichtlich sein. Meistens wirst du nach einer bestimmten Änderung suchen, wenn du dir einen vollständigen Patch anzeigen lässt. Hierfür solltest du die Option "Pickaxe" verwenden.
Shortlog
Der Befehl git shortlog
ist eine Spezialversion von git log
zum Erstellen von Release-Ankündigungen. Es gruppiert alle Commits nach Autoren und zeigt die erste Zeile einer jeden Commit-Nachricht an. So kannst du bequem sehen, wer woran gearbeitet hat.
Wenn z. B. zwei Entwickler fünf Commits zu einem Projekt beigesteuert haben, könnte die Ausgabe vn git shortlog
in etwa so aussehen:
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'
Standardmäßig sortiert git shortlog
den Output nach Name des Autors. Mit der Option -n
kannst du aber auch nach Anzahl der Commits pro Autor sortieren.
Diagramme
Mit der Option --graph
wird eine ASCII-Grafik zur Branch-Struktur des Commit-Verlaufs erstellt. Das wird oft zusammen mit den Befehlen --oneline
und --decorate
genutzt, um besser zu erkennen, welcher Commit zu welchem Branch gehört:
git log --graph --oneline --decorate
Bei einem einfachen Repository mit nur zwei Branches ergibt sich hierdurch Folgendes:
* 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
Das Sternsymbol zeigt, in welchem Branch sich der Commit befand. Dem obigen Graphen entnehmen wir also, dass die Commits 23ad9ad
und 16b36c6
sich auf einem Themen-Branch und die übrigen Commits sich auf dem main
-Branch befinden.
Für einfache Repositorys ist das zwar eine nette Option, doch bei Projekten mit sehr vielen Branches ist ein Virtualisierungstool mit großem Funktionsumfang wie gitk
oder SourceTree vermutlich die bessere Wahl.
Benutzerdefinierte Formatierung
Für alle anderen git log
-Formatierungen gibt es die Option --pretty=format:"
. Damit kannst du die Anzeige einzelner Commits individuell definieren. Wir empfehlen jedoch Platzhalter im printf
-Stil.
Die Zeichen %cn
, %h
und %cd
werden im folgenden Befehl z. B. jeweils mit dem Committer-Namen, dem abgekürzten Commit-Hash und dem Commit-Durchführungsdatum ersetzt.
git log --pretty=format:"%cn committed %h on %cd"
Hieraus ergibt sich das folgende Format für die einzelnen Commits:
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
Eine vollständige Liste der Platzhalter findest du auf der git log-Anleitungsseite im Abschnitt zu schönen Formaten
.
Abgesehen davon, dass dir nur die Informationen angezeigt werden, die dich interessieren, ist die Option --pretty=format:"
besonders hilfreich, wenn du die Ausgabe von git log
mit einem anderen Befehl kombinierst.
Commit-Verläufe filtern
Wenn du weißt, wie du die Commit-Anzeige formatieren kannst, hast du schon die Hälfte aller Vorteile von git log
kennengelernt. Wenn du auch weißt, wie du durch den Commit-Verlauf navigieren kannst, hast du aus dem Befehl alles herausgekitzelt. Im Folgenden zeigen wir einige erweiterte Methoden, um mit git log
bestimmte Commits in deinem Projektverlauf zu finden. Diese Möglichkeiten kannst du mit allen bereits vorgestellten Formatierungsoptionen kombinieren.
Nach Anzahl
Die grundlegendste Filteroption für git log
ist das Einschränken der Anzahl angezeigter Commits. Wenn du nur die letzten Commits sehen möchtest, musst du dich nicht damit abmühen, alle Commits auf einer Seite zu lesen.
Du kannst die Ausgabe von git log
beschränken, indem du die Option -
hinzufügst. Mit dem folgenden Befehl werden beispielsweise nur die drei neuesten Commits angezeigt.
git log -3
Nach Datum
Wenn du nach einem Commit von einem bestimmten Zeitrahmen suchst, kannst du die Zusätze --after
oder --before
verwenden, um die Commits nach Datum zu filtern. Beide akzeptieren verschiedene Datumsformate als Parameter. Mit dem folgenden Befehl werden beispielsweise nur Commits angezeigt, die nach (inklusive) dem 1. Juli 2014 erstellt wurden.
git log --after="2014-7-1"
Du kannst auch relative Referenzen wie "1 week ago"
und "yesterday"
anfügen:
git log --after="yesterday"
Um nach Commits zu suchen, die in einem bestimmten Zeitraum erstellt wurden, kannst du jeweils ein Datum --before
(vor) und --after
(nach) dem Zeitraum angeben. Wenn du beispielsweise alle Commits anzeigen möchtest, die zwischen dem 1. Juli 2014 und dem 4. Juli 2014 hinzugefügt wurden, gibst du Folgendes ein:
git log --after="2014-7-1" --before="2014-7-4"
Bei Commits mit vielen Änderungen kann die Ausgabe recht lang und unübersichtlich sein. Meistens wirst du nach einer bestimmten Änderung suchen, wenn du dir einen vollständigen Patch anzeigen lässt. Hierfür solltest du die Option "Pickaxe" verwenden.
Nach Autor
Wenn du nach Commits suchst, die von einem bestimmten Benutzer erstellt wurden, kannst du die Kennzeichnung --author
verwenden. Mithilfe eines regulären Ausdrucks werden alle Commits angezeigt, deren Autor diesem Muster entspricht. Falls du genau weißt, nach wem du suchst, kannst du statt eines regulären Ausdrucks auch einen ganz einfachen String verwenden.
git log --author="John"
Hiermit werden alle Commits angezeigt, die den Autorennamen John enthalten. Der Autorenname muss nicht genau übereinstimmen, er muss nur den angegebenen Ausdruck enthalten.
Mit regulären Ausdrücken kannst du eine komplexere Suche durchführen. Zum Beispiel wird mit folgendem Befehl nach Commits gesucht, die entweder von Mary oder von John stammen.
git log --author="John\|Mary"
Zusätzlich zum Autorennamen ist auch dessen E-Mail-Adresse enthalten, sodass du bei dieser Option auch nach E-Mail-Adressen suchen kannst.
Wenn in deinem Workflow Committer von Autoren getrennt werden, funktioniert die Option --committer
auf dieselbe Weise.
Nach Nachricht
Zum Filtern nach einer Commit-Nachricht bietet sich die Option --grep
an. Sie funktioniert wie die oben besprochene Option --author
, sucht aber Übereinstimmungen mit der Commit-Nachricht statt mit dem Autorennamen.
Wenn dein Team beispielsweise in jeder Commit-Nachricht relevante Issue-Nummern angibt, kannst du mit einem Befehl folgender Art alle Commits im Zusammenhang mit diesem Issue herausfiltern:
git log --grep="JRA-224:"
Außerdem kannst du den Parameter -i
auf git log
anwenden, um Unterschiede in der Groß- und Kleinschreibung beim Abgleich der Muster zu ignorieren.
Nach Datei
Oftmals sind nur die Änderungen an einer spezifischen Datei von Interesse. Um einen dateibezogenen Verlauf anzuzeigen, musst du nur den Dateipfad angeben. Wenn du alle Commits anzeigen möchtest, die entweder foo.py
oder bar.py
tangieren, gibst du den folgenden Befehl ein:
git log -- foo.py bar.py
Der Parameter --
teilt git log
mit, dass die nachfolgenden Argumente Dateipfade und keine Branch-Namen sind. Falls keine Gefahr besteht, diese zu vermischen, kann --
auch weggelassen werden.
Nach Inhalt
Es ist auch möglich, nach Commits zu suchen, die eine bestimmte Zeile Quellcode einführen oder entfernen. Diese Funktion wird Pickaxe genannt und hat die Form -S"
. Wenn du z. B. wissen möchtest, wann der String Hallo Welt! zu Dateien des Projekts hinzugefügt wurde, fragst du dies folgendermaßen ab:
git log -S"Hello, World!"
Um die Suche mithilfe eines regulären Ausdrucks statt mit einem String durchzuführen, kannst du stattdessen -G"
verwenden.
Das ist ein sehr leistungsstarkes Debugging-Tool, da du auf diese Weise alle Commits lokalisieren kannst, die eine bestimmte Codezeile betreffen. Du kannst dir sogar anzeigen lassen, wann eine Zeile kopiert oder in eine andere Datei verschoben wurde.
Nach Bereich
Du kannst git log
mit einem Bereich kombinieren, sodass nur dir Commits, die in diesen Bereich fallen, angezeigt werden. Der Bereich wird mit
und
als Commit-Referenzen spezifiziert:
git log ..
Dieser Befehl ist besonders wertvoll, wenn wir Branch-Referenzen als Parameter verwenden. So lassen sich die Unterschiede zwischen zwei Branches mühelos abzurufen. Nehmen wir den folgenden Befehl:
git log main..feature
Der Bereich main..feature
enthält alle Commits, die im feature
-Branch, aber nicht im main
-Branch enthalten sind. Anders gesagt: Hier sehen wir, wie weit sich der feature
-Branch entwickelt hat, seit er vom main
-Branch abgezweigt wurde. Dies kann folgendermaßen visuell dargestellt werden:
Hinweis: Wenn du die Reihenfolge umkehrst (feature..main
), werden dir alle Commits angezeigt, die sich im main
-Branch, aber nicht im feature
-Branch befinden. Wenn git log
Commits für beide Versionen ausgibt, weißt du, dass der Verlauf voneinander abweicht.
Filtern von Merge-Commits
Standardmäßig enthält git log
Merge Commits in der Ausgabe. Manche Teams verfolgen jedoch eine Always-merge-Strategie: Sie mergen Upstream-Änderungen in Themen-Branches, statt den Themen-Branch auf den Upstream-Branch zu rebasen. Das resultiert in einer großen Menge an Merge-Commits im Projektverlauf.
Wenn du nicht möchtest, dass git log
diese Merge-Commits anzeigt, kannst du --no-merges
verwenden:
git log --no-merges
Wenn du aber nur an den Merge-Commits interessiert bist, kannst du --merges
verwenden:
git log --merges
Hiermit werden alle Commits ausgegeben, für die mindestens zwei Parents vorhanden sind.
Zusammenfassung
Nun solltest du in der Lage sein, die erweiterten git log
-Parameter zur Formatierung der Ausgabe und Auswahl der anzuzeigenden Commits zu verwenden. Du kannst also genau die Informationen aus deinem Projektverlauf entnehmen, die du benötigst.
Diese Fähigkeit ist ein wichtiger Bestandteil im Git-Toolkit, aber git log
wird häufig auch in Verbindung mit anderen Befehlen genutzt. Nachdem du den gewünschten Commit gefunden hast, wirst du ihn höchstwahrscheinlich mit git checkout
, git revert
oder einem anderen Tool weiter manipulieren. Deshalb solltest du dich unbedingt auch in die erweiterten Features von Git einlesen.
Diesen Artikel teilen
Nächstes Thema
Lesenswert
Füge diese Ressourcen deinen Lesezeichen hinzu, um mehr über DevOps-Teams und fortlaufende Updates zu DevOps bei Atlassian zu erfahren.