W3docs

git diff

Erfahren Sie, wie der Befehl git diff funktioniert, wie man seine Ausgabe liest und Änderungen zwischen Dateien, Commits und Branches vergleicht.

Was git diff macht

Der Befehl git diff zeigt Ihnen genau, was sich zwischen zwei Quellen in Ihrem Projekt geändert hat – Zeile für Zeile. Er nimmt zwei Datensätze und gibt die Unterschiede als Patch aus.

Diese zwei Quellen können beliebige Paare aus folgenden Elementen sein: Ihr Working Tree (die Dateien, die Sie gerade bearbeiten), der Staging-Bereich (der Index, was git add erfasst hat) und jeder festgeschriebene Snapshot. Da jeder andere Git-Befehl Ihnen nur sagt, dass sich etwas geändert hat, ist git diff das Werkzeug, das Ihnen sagt, was sich geändert hat, bevor Sie es stagen oder committen.

Er wird häufig zusammen mit git status und git log verwendet, um den Zustand eines Git-Repositorys zu überprüfen: git status listet auf, welche Dateien geändert wurden, und git diff zeigt den Inhalt dieser Änderungen.

gitdiff

Welche zwei Quellen verglichen werden

Die Form des Befehls bestimmt, was verglichen wird:

BefehlVergleicht
git diffWorking Tree vs. Staging-Bereich (nicht gestagte Änderungen)
git diff --stagedStaging-Bereich vs. letzter Commit (was git commit aufzeichnen würde)
git diff HEADWorking Tree vs. letzter Commit (alle nicht committeten Änderungen)
git diff <commit> <commit>Ein Commit vs. ein anderer
git diff <branch> <branch>Die Spitzen zweier Branches

Ein einfaches git diff zeigt nur, was Sie noch nicht mit git add gestagt haben. Das ist die häufigste Falle: Wenn Sie bereits git add ausgeführt haben, sieht git diff leer aus, obwohl Sie Änderungen haben – verwenden Sie git diff --staged, um sie zu sehen.

Die Diff-Ausgabe lesen

Ein Diff besteht aus mehreren unterschiedlichen Teilen. Die folgenden Abschnitte bauen einen auf und erklären jede Zeile.

Rohausgabe-Format

Sehen Sie sich die folgenden Befehle an, um ein einfaches Repository zu erstellen:

mkdir test_repo
cd test_repo
touch test.txt
echo "this is a git diff test example" > test.txt
git init .
#Initialized empty Git repository in /Users/kev/code/test/.git/
git add test.txt
git commit -am "add diff test file"
#[master (root-commit) 9e2dcac] add diff test file
#1 file changed, 1 insertion(+)
#create mode 100644 test.txt

Damit git diff eine Ausgabe erzeugt, müssen Sie den Inhalt von test.txt nach dem Committen ändern. Führen Sie den folgenden Befehl aus:

echo "this is a diff example" > test.txt

Erst jetzt können wir einen Diff anzeigen und die Ausgabe besprechen. Die Ausführung von git diff erzeugt folgendes:

diff --git a/test.txt b/test.txt
index 6b0c6cf..b37e70a 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

Diff-Eingabequellen

Die erste Zeile benennt die zwei verglichenen Quellen. Hier werden a/test.txt (die „Vorher"-Version) und b/test.txt (die „Nachher"-Version) an den Diff übergeben. Die Präfixe a/ und b/ markieren immer die beiden Seiten, auch wenn es sich um dieselbe Datei handelt.

diff --git a/test.txt b/test.txt

Metadaten

Diese Zeile zeigt interne Git-Metadaten. Die zwei Zahlen sind die abgekürzten Objekt-(Blob-)Hashes der Datei vor und nach der Änderung, und 100644 ist der Dateimodus (eine gewöhnliche, nicht ausführbare Datei).

index 6b0c6cf..b37e70a 100644

Symbole für Änderungen

Diese Zeilen weisen jeder Diff-Eingabequelle ein Symbol zu. Zeilen aus a/test.txt (das Original) werden mit --- markiert, und Zeilen aus b/test.txt (die neue Version) werden mit +++ markiert.

--- a/test.txt
+++ b/test.txt

Diff-Chunks

Ein Diff zeigt nicht die gesamte Datei – nur die geänderten Bereiche. Jeder solche Bereich wird Chunk (oder Hunk) genannt. Chunks enthalten einige unveränderte Zeilen des umgebenden Kontexts, damit Sie sehen können, wo die Änderung liegt.

@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

Die erste Zeile ist der Chunk-Header, eingerahmt durch @@-Symbole. Er fasst die betroffenen Zeilenbereiche zusammen: -1 bedeutet „beginnend bei Zeile 1 der alten Datei" und +1 bedeutet „beginnend bei Zeile 1 der neuen Datei". Unterhalb des Headers markiert ein führendes - eine entfernte Zeile und ein führendes + eine hinzugefügte Zeile. Eine geänderte Zeile erscheint daher als Entfernung gefolgt von einer Hinzufügung.

Häufige Flags

Git bietet mehrere nützliche Flags für verschiedene Workflows:

  • --staged (oder --cached): Vergleicht die gestagten Änderungen im Index mit dem HEAD-Commit – was ein git commit aufzeichnen würde.
  • --stat: Zeigt eine kompakte Zusammenfassung der geänderten Dateien (Einfügungen/Löschungen pro Datei) anstelle des vollständigen Diffs.
  • --name-only: Gibt nur die Namen der geänderten Dateien aus.
  • --name-status: Wie --name-only, aber stellt jeder Datei ihren Statusbuchstaben voran (M geändert, A hinzugefügt, D gelöscht).
  • -w (oder --ignore-all-space): Ignoriert Änderungen, die nur aus Leerzeichen bestehen, was praktisch ist, wenn Einrückungen die eigentlichen Änderungen verdecken.

Um zum Beispiel einen schnellen Überblick zu erhalten, wie viel sich in jeder Datei geändert hat:

git diff --stat
# test.txt | 2 +-
# 1 file changed, 1 insertion(+), 1 deletion(-)

Änderungen hervorheben

Bei Änderungen auf Zeilenebene kann die Standardausgabe unübersichtlich sein, da Git eine vollständige entfernte Zeile und eine vollständige hinzugefügte Zeile anzeigt, auch wenn sich nur ein Wort unterscheidet. Die beiden folgenden Werkzeuge heben die genauen geänderten Teile hervor.

git diff --color-words

Der erste Weg ist ein spezieller Modus, der in git diff eingebaut ist: --color-words. Er tokenisiert die hinzugefügten und entfernten Zeilen nach Leerzeichen und vergleicht dann diese Token, sodass nur die geänderten Wörter farbig markiert werden statt ganzer Zeilen.

git diff --color-words
diff --git a/test.txt b/test.txt
index 6b0c6cf..b37e70a 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

(Hinweis: --color-words hebt inline-Änderungen mithilfe von Terminal-Farben hervor. Im Klartext entspricht das Ausgabeformat dem Standard-Diff.)

git diff-highlight

Wenn Sie den Git-Quellcode klonen, wird ein Unterverzeichnis namens contrib mitgeliefert. Es enthält Werkzeuge rund um Git, eines davon ist diff-highlight. Es hebt geänderte Teile innerhalb von Wörtern hervor und ist damit feingranularer als --color-words. Beachten Sie, dass dieses Werkzeug die Standardeingabe filtert (Sie leiten einen Diff hinein) und Terminal-Farbgebung erfordert, um sichtbar zu sein.

git diff | git diff-highlight
diff --git a/test.txt b/test.txt
index 6b0c6cf..b37e70a 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

Binärdateien vergleichen

git diff kann nicht nur auf Textdateien, sondern auch auf Binärdateien angewendet werden. Standardmäßig ist das Ergebnis wenig hilfreich – Git teilt Ihnen nur mit, dass sich die Datei geändert hat, aber nicht wie:

git diff
# Binary files a/script.pdf and b/script.pdf differ

Git verfügt über eine Funktion, mit der Sie einen Shell-Befehl angeben können, um den Inhalt der Binärdatei vor der Durchführung des Diffs in Text umzuwandeln. Dazu ist etwas Einrichtung erforderlich. Definieren Sie zunächst einen textconv-Filter, der beschreibt, wie ein bestimmter binärer Typ in Text umgewandelt werden soll. Das Dienstprogramm pdftohtml (über Homebrew verfügbar) kann beispielsweise ein PDF in HTML umwandeln. Es gibt zwei Stellen für diese Konfiguration: pro-Repository in .git/config oder global in ~/.gitconfig.

[diff "pdfconv"]
textconv=pdftohtml -stdout

Verbinden Sie dann ein oder mehrere Dateimuster mit dem pdfconv-Filter, indem Sie eine .gitattributes-Datei im Stammverzeichnis des Repositorys erstellen:

*.pdf diff=pdfconv

Nach dieser Konfiguration führt git diff jede passende Binärdatei zunächst durch den Konverter und vergleicht die Textausgabe des Konverters. Mit derselben Technik können Sie lesbare Diffs aus vielen Binärformaten erhalten (Zips, Jars und andere Archive).

Eine einzelne Datei vergleichen

git diff akzeptiert auch einen expliziten Dateipfad. Wenn ein Pfad übergeben wird, wird die Operation auf diese eine Datei beschränkt. Im folgenden Beispiel vergleicht das Argument ./path/to/file die Änderungen im Arbeitsverzeichnis mit dem HEAD-Commit:

git diff HEAD ./path/to/file

Alle Änderungen vergleichen

Um Änderungen im gesamten Repository zu vergleichen, führen Sie git diff ohne Dateipfad aus. Jede der oben genannten Formen kann ohne das Argument ./path/to/file aufgerufen werden, um denselben Vergleich auf jede Datei im lokalen Repository anzuwenden.

Änderungen seit dem letzten Commit

Ein einfaches git diff vergleicht das Arbeitsverzeichnis mit dem Staging-Bereich (Index) und zeigt daher nur nicht gestagte Änderungen. Um alle nicht committeten Änderungen seit dem letzten Commit zu sehen – sowohl gestagte als auch nicht gestagte – vergleichen Sie mit HEAD:

git diff HEAD

Zwei Commits vergleichen

git diff akzeptiert Git-Refs wie Branch-Namen, Tags und Commit-Hashes. Jeder Commit hat eine eindeutige ID, die Sie mit git log finden können. Übergeben Sie zwei Commit-IDs, um sie direkt zu vergleichen:

git diff <commit-hash-1> <commit-hash-2>

Die Ausgabe zeigt, was sich vom ersten Commit zum zweiten geändert hat.

Branches vergleichen

Das Vergleichen von Branches funktioniert wie jede andere Ref-Eingabe für git diff. Es gibt zwei Operatoren, die Sie kennen sollten.

Der Zwei-Punkte-Operator vergleicht die Spitzen beider Branches:

git diff branch1..branch2

Sie erhalten dasselbe Ergebnis, wenn die Punkte weggelassen und ein Leerzeichen zwischen den Branch-Namen verwendet wird. Es gibt auch einen Drei-Punkte-Operator:

git diff branch1...branch2

Der Drei-Punkte-Operator setzt den Vergleich auf die gemeinsame Historie zurück: Er ersetzt branch1 durch den gemeinsamen Vorfahren (Merge-Basis) der beiden Branches, während die zweite Eingabe die Spitze von branch2 bleibt. Mit anderen Worten beantwortet branch1...branch2 die Frage: „Was ist auf branch2 passiert, seit es sich von branch1 abgezweigt hat?" – was in der Regel das ist, was Sie möchten, wenn Sie einen Feature-Branch vor einem git merge überprüfen.

Eine Datei zwischen zwei Branches vergleichen

Um eine bestimmte Datei zwischen Branches zu vergleichen, übergeben Sie den Dateipfad als drittes Argument:

git diff master new_branch ./test.txt

Verwandte Befehle

  • git status — sehen Sie, welche Dateien geändert wurden, bevor Sie git diff verwenden, um zu sehen, was sich in ihnen geändert hat.
  • git add — sobald ein Diff richtig aussieht, stagen Sie ihn; verwenden Sie danach git diff --staged, um zu überprüfen, was gestagt ist.
  • git commit — zeichnet die gestagten Änderungen auf.
  • git log — findet die Commit-Hashes, die Sie an git diff <commit> <commit> übergeben.
  • git show — zeigt den Diff an, der durch einen einzelnen Commit eingeführt wurde.

Übungen

Übung
Was sind die Funktionalitäten und Optionen des Befehls 'git diff'?
Was sind die Funktionalitäten und Optionen des Befehls 'git diff'?
Was this page helpful?