Kapitel ▾ 2. Auflage

2.3 Git-Grundlagen - Anzeigen der Commit-Historie

Anzeigen der Commit-Historie

Nachdem Sie mehrere Commits erstellt haben oder wenn Sie ein Repository mit einer bestehenden Commit-Historie geklont haben, möchten Sie wahrscheinlich zurückblicken, um zu sehen, was passiert ist. Das grundlegendste und mächtigste Werkzeug dafür ist der Befehl git log.

Diese Beispiele verwenden ein sehr einfaches Projekt namens „simplegit“. Um das Projekt zu erhalten, führen Sie Folgendes aus:

$ git clone https://github.com/schacon/simplegit-progit

Wenn Sie git log in diesem Projekt ausführen, sollten Sie eine Ausgabe erhalten, die ungefähr so aussieht:

$ git log
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    Change version number

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    Remove unnecessary test

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 10:31:28 2008 -0700

    Initial commit

Standardmäßig listet git log ohne Argumente die Commits in diesem Repository in umgekehrter chronologischer Reihenfolge auf. Das bedeutet, die neuesten Commits werden zuerst angezeigt. Wie Sie sehen, listet dieser Befehl jeden Commit mit seiner SHA-1-Prüfsumme, dem Namen und der E-Mail des Autors, dem Erstellungsdatum und der Commit-Nachricht auf.

Eine riesige Anzahl und Vielfalt von Optionen für den Befehl git log ist verfügbar, um Ihnen genau das zu zeigen, wonach Sie suchen. Hier zeigen wir Ihnen einige der beliebtesten.

Eine der hilfreicheren Optionen ist -p oder --patch, die die mit jedem Commit eingeführte Änderung (die Patch-Ausgabe) anzeigt. Sie können auch die Anzahl der angezeigten Log-Einträge begrenzen, z. B. mit -2, um nur die letzten beiden Einträge anzuzeigen.

$ git log -p -2
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    Change version number

diff --git a/Rakefile b/Rakefile
index a874b73..8f94139 100644
--- a/Rakefile
+++ b/Rakefile
@@ -5,7 +5,7 @@ require 'rake/gempackagetask'
 spec = Gem::Specification.new do |s|
     s.platform  =   Gem::Platform::RUBY
     s.name      =   "simplegit"
-    s.version   =   "0.1.0"
+    s.version   =   "0.1.1"
     s.author    =   "Scott Chacon"
     s.email     =   "schacon@gee-mail.com"
     s.summary   =   "A simple gem for using Git in Ruby code."

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    Remove unnecessary test

diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index a0a60ae..47c6340 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -18,8 +18,3 @@ class SimpleGit
     end

 end
-
-if $0 == __FILE__
-  git = SimpleGit.new
-  puts git.show
-end

Diese Option zeigt dieselben Informationen an, aber mit einem Diff, der jedem Eintrag direkt folgt. Dies ist sehr hilfreich für die Code-Überprüfung oder um schnell zu sehen, was während einer Reihe von Commits passiert ist, die ein Mitarbeiter hinzugefügt hat. Sie können auch eine Reihe von zusammenfassenden Optionen mit git log verwenden. Wenn Sie beispielsweise einige zusammengefasste Statistiken für jeden Commit sehen möchten, können Sie die Option --stat verwenden.

$ git log --stat
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    Change version number

 Rakefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    Remove unnecessary test

 lib/simplegit.rb | 5 -----
 1 file changed, 5 deletions(-)

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 10:31:28 2008 -0700

    Initial commit

 README           |  6 ++++++
 Rakefile         | 23 +++++++++++++++++++++++
 lib/simplegit.rb | 25 +++++++++++++++++++++++++
 3 files changed, 54 insertions(+)

Wie Sie sehen, gibt die Option --stat unter jedem Commit-Eintrag eine Liste der geänderten Dateien, die Anzahl der geänderten Dateien und die Anzahl der hinzugefügten und entfernten Zeilen in diesen Dateien aus. Sie fügt auch eine Zusammenfassung der Informationen am Ende hinzu.

Eine weitere sehr nützliche Option ist --pretty. Diese Option ändert die Log-Ausgabe in andere Formate als das Standardformat. Es stehen einige vordefinierte Optionswerte zur Verfügung. Der Wert oneline für diese Option gibt jeden Commit in einer einzigen Zeile aus, was nützlich ist, wenn Sie viele Commits betrachten. Darüber hinaus zeigen die Werte short, full und fuller die Ausgabe in ungefähr demselben Format, aber mit weniger bzw. mehr Informationen an.

$ git log --pretty=oneline
ca82a6dff817ec66f44342007202690a93763949 Change version number
085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 Remove unnecessary test
a11bef06a3f659402fe7563abf99ad00de2209e6 Initial commit

Der interessanteste Optionswert ist format, mit dem Sie Ihr eigenes Log-Ausgabeformat angeben können. Dies ist besonders nützlich, wenn Sie Ausgaben für die maschinelle Verarbeitung generieren – da Sie das Format explizit angeben, wissen Sie, dass es sich bei Updates von Git nicht ändert.

$ git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 6 years ago : Change version number
085bb3b - Scott Chacon, 6 years ago : Remove unnecessary test
a11bef0 - Scott Chacon, 6 years ago : Initial commit

Nützliche Spezifizierer für git log --pretty=format listet einige der nützlichsten Spezifizierer auf, die format akzeptiert.

Tabelle 1. Nützliche Spezifizierer für git log --pretty=format
Spezifizierer Beschreibung der Ausgabe

%H

Commit-Hash

%h

Abgekürzter Commit-Hash

%T

Tree-Hash

%t

Abgekürzter Tree-Hash

%P

Eltern-Hashes

%p

Abgekürzte Eltern-Hashes

%an

Autorname

%ae

Autoren-E-Mail

%ad

Datum des Autors (Format respektiert die --date=option)

%ar

Datum des Autors, relativ

%cn

Name des Committer

%ce

E-Mail des Committer

%cd

Datum des Committer

%cr

Datum des Committer, relativ

%s

Betreff

Sie fragen sich vielleicht, was der Unterschied zwischen Autor und Committer ist. Der Autor ist die Person, die die Arbeit ursprünglich geschrieben hat, während der Committer die Person ist, die die Arbeit zuletzt angewendet hat. Wenn Sie also einen Patch an ein Projekt senden und eines der Kernmitglieder den Patch anwendet, erhalten Sie beide Anerkennung – Sie als Autor und das Kernmitglied als Committer. Wir werden diesen Unterschied in Distributed Git noch etwas weiter behandeln.

Die Optionswerte oneline und format sind besonders nützlich mit einer weiteren log-Option namens --graph. Diese Option fügt einen schönen kleinen ASCII-Graphen hinzu, der Ihre Branch- und Merge-Historie zeigt.

$ git log --pretty=format:"%h %s" --graph
* 2d3acf9 Ignore errors from SIGCHLD on trap
*  5e3ee11 Merge branch 'master' of https://github.com/dustin/grit.git
|\
| * 420eac9 Add method for getting the current branch
* | 30e367c Timeout code and tests
* | 5a09431 Add timeout protection to grit
* | e1193f8 Support for heads with slashes in them
|/
* d6016bc Require time for xmlschema
*  11d191e Merge branch 'defunkt' into local

Diese Art von Ausgabe wird interessanter, wenn wir uns im nächsten Kapitel mit Branching und Merging beschäftigen.

Dies sind nur einige einfache Ausgabeformatierungsoptionen für git log – es gibt noch viele mehr. Gängige Optionen für git log listet die bisher behandelten Optionen sowie einige andere gängige Formatierungsoptionen auf, die nützlich sein können, und wie sie die Ausgabe des log-Befehls ändern.

Tabelle 2. Gängige Optionen für git log
Option Beschreibung

-p

Zeigt den mit jedem Commit eingeführten Patch an.

--stat

Zeigt Statistiken für geänderte Dateien in jedem Commit an.

--shortstat

Zeigt nur die Zeile mit den geänderten/eingefügten/gelöschten Dateien aus dem Befehl --stat an.

--name-only

Zeigt nach den Commit-Informationen eine Liste der geänderten Dateien an.

--name-status

Zeigt eine Liste der betroffenen Dateien mit Informationen über hinzugefügt/geändert/gelöscht an.

--abbrev-commit

Zeigt nur die ersten paar Zeichen der SHA-1-Prüfsumme anstelle aller 40.

--relative-date

Zeigt das Datum in einem relativen Format an (z. B. „vor 2 Wochen“) anstelle des vollständigen Datumsformats.

--graph

Zeigt einen ASCII-Graphen der Branch- und Merge-Historie neben der Log-Ausgabe an.

--pretty

Zeigt Commits in einem alternativen Format an. Optionswerte sind oneline, short, full, fuller und format (wobei Sie Ihr eigenes Format angeben).

--oneline

Abkürzung für --pretty=oneline --abbrev-commit zusammen verwendet.

Begrenzen der Log-Ausgabe

Zusätzlich zu den Optionen zur Ausgabeformatierung nimmt git log eine Reihe nützlicher begrenzender Optionen entgegen, d. h. Optionen, mit denen Sie nur eine Teilmenge von Commits anzeigen können. Eine solche Option haben Sie bereits gesehen – die Option -2, die nur die letzten beiden Commits anzeigt. Tatsächlich können Sie -<n> verwenden, wobei n eine beliebige Ganzzahl ist, um die letzten n Commits anzuzeigen. In Wirklichkeit werden Sie dies wahrscheinlich nicht oft verwenden, da Git standardmäßig die gesamte Ausgabe über einen Pager leitet, sodass Sie immer nur eine Seite der Log-Ausgabe auf einmal sehen.

Die zeitbegrenzenden Optionen wie --since und --until sind jedoch sehr nützlich. Dieser Befehl ruft beispielsweise die Liste der Commits ab, die in den letzten zwei Wochen gemacht wurden.

$ git log --since=2.weeks

Dieser Befehl funktioniert mit vielen Formaten – Sie können ein bestimmtes Datum wie "2008-01-15" oder ein relatives Datum wie "vor 2 Jahren 1 Tag 3 Minuten" angeben.

Sie können die Liste auch auf Commits filtern, die bestimmten Suchkriterien entsprechen. Die Option --author ermöglicht Ihnen das Filtern nach einem bestimmten Autor, und die Option --grep ermöglicht Ihnen die Suche nach Schlüsselwörtern in den Commit-Nachrichten.

Hinweis

Sie können mehr als eine Instanz sowohl für die --author- als auch für die --grep-Suchkriterien angeben, was die Commit-Ausgabe auf Commits beschränkt, die irgendeinem der --author-Muster und irgendeinem der --grep-Muster entsprechen. Die Hinzufügung der Option --all-match beschränkt die Ausgabe jedoch weiter auf nur jene Commits, die allen --grep-Mustern entsprechen.

Eine weitere wirklich hilfreiche Filteroption ist die Option -S (umgangssprachlich als Git's „Pickaxe“-Option bezeichnet), die eine Zeichenkette annimmt und nur diejenigen Commits anzeigt, die die Anzahl der Vorkommen dieser Zeichenkette geändert haben. Wenn Sie beispielsweise den letzten Commit finden möchten, der eine Referenz auf eine bestimmte Funktion hinzugefügt oder entfernt hat, können Sie Folgendes aufrufen:

$ git log -S function_name

Die letzte wirklich nützliche Option, die Sie als Filter an git log übergeben können, ist ein Pfad. Wenn Sie ein Verzeichnis oder einen Dateinamen angeben, können Sie die Log-Ausgabe auf Commits beschränken, die eine Änderung an diesen Dateien eingeführt haben. Dies ist immer die letzte Option und wird im Allgemeinen von doppelten Bindestrichen (--) begleitet, um die Pfade von den Optionen zu trennen.

$ git log -- path/to/file

In Optionen zur Begrenzung der Ausgabe von git log listen wir diese und einige andere gängige Optionen zu Ihrer Information auf.

Tabelle 3. Optionen zur Begrenzung der Ausgabe von git log
Option Beschreibung

-<n>

Zeigt nur die letzten n Commits an.

--since, --after

Begrenzt die Commits auf diejenigen, die nach dem angegebenen Datum erstellt wurden.

--until, --before

Begrenzt die Commits auf diejenigen, die vor dem angegebenen Datum erstellt wurden.

--author

Zeigt nur Commits an, bei denen der Autoren-Eintrag mit der angegebenen Zeichenkette übereinstimmt.

--committer

Zeigt nur Commits an, bei denen der Committer-Eintrag mit der angegebenen Zeichenkette übereinstimmt.

--grep

Zeigt nur Commits an, deren Commit-Nachricht die Zeichenkette enthält.

-S

Zeigt nur Commits an, die Code hinzufügen oder entfernen, der mit der Zeichenkette übereinstimmt.

Wenn Sie beispielsweise sehen möchten, welche Commits, die Testdateien in der Git-Quellcode-Historie modifizieren, von Junio Hamano im Oktober 2008 committet wurden und keine Merge-Commits sind, können Sie Folgendes ausführen:

$ git log --pretty="%h - %s" --author='Junio C Hamano' --since="2008-10-01" \
   --before="2008-11-01" --no-merges -- t/
5610e3b - Fix testcase failure when extended attributes are in use
acd3b9e - Enhance hold_lock_file_for_{update,append}() API
f563754 - demonstrate breakage of detached checkout with symbolic link HEAD
d1a43f2 - reset --hard/read-tree --reset -u: remove unmerged new paths
51a94af - Fix "checkout --track -b newbranch" on detached HEAD
b0ad11e - pull: allow "git pull origin $something:$current_branch" into an unborn branch

Von den fast 40.000 Commits in der Git-Quellcode-Historie zeigt dieser Befehl die 6 an, die diesen Kriterien entsprechen.

Tipp
Verhindern der Anzeige von Merge-Commits

Abhängig vom im Repository verwendeten Workflow ist es möglich, dass ein erheblicher Prozentsatz der Commits in Ihrer Log-Historie nur Merge-Commits sind, die in der Regel nicht sehr informativ sind. Um zu verhindern, dass Merge-Commits Ihre Log-Historie verstopfen, fügen Sie einfach die log-Option --no-merges hinzu.