git diff im Detail: Änderungen praezise nachvollziehen
git
HEAD
Git · Version Control · Diff · Developer Workflow
git diff im Detail
Änderungen praezise nachvollziehen

Wer git diff nur oberflaechlich nutzt, uebersieht schnell ungewollte Änderungen zwischen Working Directory, Staging Area und Commit. Dieser Artikel zeigt, wie ihr die drei Vergleichsebenen sauber auseinanderhaltet, mit Flags wie stat, word-diff und -w gezielt filtert und ein leistungsfaehiges Diff-Tool für den Alltag konfiguriert.

12 Min. Lesezeit git diff · --staged · --stat · --word-diff Git 2.4x · delta · diff-so-fancy

1. Warum git diff im Entwickleralltag unverzichtbar ist

git diff ist das zentrale Werkzeug, um Änderungen am Code sichtbar zu machen, bevor sie unwiderruflich in der Historie landen. Wer stattdessen blind git add . gefolgt von git commit ausfuehrt, riskiert Debug-Ausgaben, auskommentierten Code oder versehentlich geaenderte Konfigurationsdateien im Commit. Gerade in Magento-Projekten mit vielen generierten und manuell gepflegten Dateien, etwa di.xml, Layout-XML oder kompilierten Tailwind-Assets, ist ein Blick per git diff vor jedem Commit der einfachste Weg, um saubere, nachvollziehbare Änderungen zu garantieren.

Der eigentliche Mehrwert von git diff liegt darin, dass es nicht nur zeigt, dass sich etwas geaendert hat, sondern exakt, was sich geaendert hat, Zeile für Zeile und, mit den richtigen Flags, sogar Wort für Wort. Fuer PHP- und Magento-Entwickler, die taeglich mit mehreren Feature-Branches, Hotfixes und Pull Requests jonglieren, ist ein sicherer Umgang mit den verschiedenen git diff-Varianten kein Nice-to-have, sondern eine Grundfertigkeit, die Fehler vor dem Review statt danach abfaengt.

2. Working Directory, Staging Area und Commit: die drei Vergleichsebenen

Git verwaltet Änderungen über drei unterschiedliche Zustaende, und git diff vergleicht je nach Aufruf verschiedene Paare dieser Zustaende. Das Working Directory enthaelt die tatsaechlichen Dateien auf der Festplatte, so wie sie gerade bearbeitet werden. Die Staging Area, auch Index genannt, ist ein Zwischenspeicher, der genau die Änderungen enthaelt, die beim naechsten git commit tatsaechlich uebernommen werden. Der letzte Commit (HEAD) ist der zuletzt gespeicherte Snapshot des Repositories.

Ohne dieses Modell im Kopf fuehrt git diff schnell zu Verwirrung, weil derselbe Befehl je nach Staging-Zustand unterschiedliche Ergebnisse liefert. Der Standardaufruf git diff vergleicht Working Directory gegen Staging Area und zeigt damit nur ungestagte Änderungen. git diff --staged vergleicht Staging Area gegen den letzten Commit. git diff HEAD vergleicht Working Directory direkt gegen den letzten Commit und fasst damit gestagte und ungestagte Änderungen zusammen. Wer diese drei Vergleiche sauber trennt, versteht sofort, warum ein Diff plötzlich leer erscheint, obwohl sichtlich etwas geaendert wurde.

3. git diff Grundlagen: ungestagte Änderungen anzeigen

Der einfachste Aufruf git diff ohne weitere Argumente zeigt alle Änderungen im Working Directory, die noch nicht mit git add zur Staging Area hinzugefuegt wurden. Das ist der Befehl, den man vor jedem git add ausfuehren sollte, um zu sehen, was tatsaechlich zur naechsten Staging-Runde hinzukommt. Die Ausgabe folgt dem unified-diff-Format: Zeilen mit einem Minus wurden entfernt, Zeilen mit einem Plus wurden hinzugefuegt, und der Kontext drumherum bleibt unveraendert sichtbar, standardmaessig drei Zeilen vor und nach jeder Aenderung.

Ein haeufiger Stolperstein: Nachdem eine Datei bereits gestaged wurde, zeigt git diff für diese Datei nichts mehr an, selbst wenn sie objektiv geaendert wurde. Der Grund ist, dass git diff ohne Argumente ausschließlich ungestagte Änderungen im Vergleich zur Staging Area zeigt, nicht zum letzten Commit. Fuer neu erstellte, noch nicht getrackte Dateien liefert git diff ebenfalls keine Ausgabe, weil Git diese Dateien noch gar nicht kennt. Hier hilft git add -N, um eine Datei für Diff-Zwecke als leer zu tracken, ohne ihren Inhalt bereits zu stagen.


# Show all unstaged changes in the working directory
git diff

# Example output for a modified PHP class
diff --git a/app/code/Mironsoft/SeoSuite/Model/MetaGenerator.php b/app/code/Mironsoft/SeoSuite/Model/MetaGenerator.php
index 3f21ab2..9c88e10 100644
--- a/app/code/Mironsoft/SeoSuite/Model/MetaGenerator.php
+++ b/app/code/Mironsoft/SeoSuite/Model/MetaGenerator.php
@@ -42,7 +42,7 @@ class MetaGenerator
     public function generateTitle(ProductInterface $product): string
     {
-        return $product->getName();
+        return trim($product->getName()) . ' | ' . $this->storeName;
     }

# Show only which files changed, without the actual diff content
git diff --name-only

# Show status letters instead of full diff (M, A, D, R)
git diff --name-status

4. git diff --staged und --cached: die Staging Area pruefen

git diff --staged (identisch zu git diff --cached, beide Schreibweisen sind gleichwertig) vergleicht die Staging Area gegen den letzten Commit und zeigt damit exakt, was beim naechsten git commit tatsaechlich uebernommen wird. Das ist der wichtigste Befehl direkt vor jedem Commit, denn er beantwortet die eigentlich relevante Frage: Was landet gleich in der Historie? Ein einfaches git diff allein reicht dafuer nicht aus, weil es nur den ungestagten Teil zeigt und damit bereits gestagte Änderungen komplett ausblendet.

In der Praxis ist eine haeufige Kombination: Erst git add -p nutzen, um Änderungen interaktiv in kleine, logische Haeppchen zu zerlegen, dann git diff --staged, um genau diese Haeppchen vor dem Commit noch einmal zu pruefen. Wer Zwischenschritte lieber zusammenhaengend sieht, kann git diff HEAD verwenden, was gestagte und ungestagte Änderungen gemeinsam gegen den letzten Commit darstellt, ohne zwischen den beiden Bereichen zu unterscheiden. Fuer sehr disziplinierte Commit-Historien in Magento-Projekten, in denen jeder Commit einen einzelnen fachlichen Zweck erfuellt, ist git diff --staged der Befehl, der am haeufigsten im Terminal auftaucht.


# Stage a specific file for the next commit
git add app/code/Mironsoft/SeoSuite/Model/MetaGenerator.php

# Show exactly what will be committed (index vs. last commit)
git diff --staged

# Equivalent alternative syntax
git diff --cached

# Example output after staging the change from the section above
diff --git a/app/code/Mironsoft/SeoSuite/Model/MetaGenerator.php b/app/code/Mironsoft/SeoSuite/Model/MetaGenerator.php
index 3f21ab2..9c88e10 100644
--- a/app/code/Mironsoft/SeoSuite/Model/MetaGenerator.php
+++ b/app/code/Mironsoft/SeoSuite/Model/MetaGenerator.php
@@ -42,7 +42,7 @@ class MetaGenerator
     public function generateTitle(ProductInterface $product): string
     {
-        return $product->getName();
+        return trim($product->getName()) . ' | ' . $this->storeName;
     }

5. Nuetzliche Flags: --stat, --word-diff, -w und --color-words

git diff --stat liefert statt des vollstaendigen Diffs eine kompakte Zusammenfassung: pro Datei die Anzahl geaenderter Zeilen als Zahl und als kleine Balkengrafik aus Plus- und Minuszeichen. Das ist der erste Befehl, den man vor einem grossen Review ausfuehren sollte, um einen Ueberblick zu bekommen, bevor man sich in Details verliert. Bei einem Merge oder Rebase mit vielen betroffenen Dateien zeigt --stat sofort, ob eine Aenderung im erwarteten Umfang liegt oder ob unerwartet viele Dateien betroffen sind.

git diff --word-diff wechselt von zeilenbasierten zu wortbasierten Diffs und ist besonders wertvoll bei Fliesstext, Uebersetzungsdateien oder langen String-Konstanten, wo eine einzelne veraenderte Zeile sonst komplett rot und grün markiert wuerde, obwohl sich nur ein Wort geaendert hat. Mit --color-words wird dieselbe Idee noch praeziser umgesetzt, indem nur die tatsaechlich unterschiedlichen Zeichenfolgen eingefaerbt werden, ohne die klammerartige Wortmarkierung von --word-diff. Das Flag -w (Alias für --ignore-all-space) blendet reine Whitespace-Änderungen aus, etwa nach einem automatischen Reformatieren durch PHP-CS-Fixer, und zeigt nur echte inhaltliche Änderungen.


# Compact summary: files changed, lines added/removed as a bar chart
git diff --stat

# Example output
 app/code/Mironsoft/SeoSuite/Model/MetaGenerator.php | 12 +++++++-----
 app/code/Mironsoft/SeoSuite/etc/di.xml               |  3 +--
 2 files changed, 8 insertions(+), 7 deletions(-)

# Word-level diff, useful for prose or translation files
git diff --word-diff app/code/Mironsoft/SeoSuite/i18n/de_DE.csv

# Even more precise word-level highlighting without the [-old-]{+new+} markers
git diff --color-words

# Ignore all whitespace changes, e.g. after an auto-formatter run
git diff -w

# Same effect, more explicit long option
git diff --ignore-all-space

6. Branches und einzelne Commits vergleichen

git diff ist nicht auf den aktuellen Arbeitsstand beschraenkt, sondern kann beliebige Commits und Branches gegeneinander vergleichen. git diff branchA branchB zeigt die Änderungen, um von branchA zu branchB zu gelangen, direkt basierend auf dem jeweils letzten Commit beider Branches. git diff branchA...branchB mit drei Punkten dagegen vergleicht gegen den gemeinsamen Merge-Base beider Branches und ignoriert Commits, die nur auf branchA passiert sind, seit sich die Branches getrennt haben. Diese drei-Punkt-Notation ist fast immer die richtige Wahl beim Review eines Feature-Branches gegen main, weil sie ausschließlich zeigt, was der Feature-Branch tatsaechlich beitraegt.

Fuer den Vergleich einzelner Commits eignet sich git diff commit1 commit2 mit den vollen oder abgekuerzten Commit-Hashes. Relative Referenzen wie git diff HEAD~3 vergleichen den aktuellen Stand mit dem Stand vor drei Commits und sind praktisch, um schnell nachzuvollziehen, was sich seit einem bestimmten Punkt in der juengeren Historie veraendert hat, etwa vor einem Hotfix-Deployment. git diff HEAD~1 HEAD zeigt exakt den letzten Commit als Diff, eine Alternative zu git show HEAD, die sich besser mit weiteren git diff-Flags kombinieren laesst.


# Compare the tips of two branches directly
git diff main feature/checkout-redesign

# Compare against the common merge base (recommended for feature-branch reviews)
git diff main...feature/checkout-redesign

# Compare two specific commits by hash
git diff a1b2c3d 9f8e7d6

# Compare current state against three commits ago
git diff HEAD~3

# Show exactly the last commit as a diff
git diff HEAD~1 HEAD

# Compare a remote branch against local main before pulling
git fetch origin
git diff main origin/main

7. Einzelne Dateien und Pfade gezielt diffen

Bei grossen Repositories mit hunderten geaenderten Dateien nach einem Merge ist es selten sinnvoll, den kompletten Diff auf einmal zu betrachten. git diff -- pfad/zur/datei.php beschraenkt die Ausgabe auf eine einzelne Datei, während git diff -- app/code/Mironsoft/SeoSuite/ alle Änderungen innerhalb eines Verzeichnisses zeigt. Der doppelte Bindestrich -- trennt dabei explizit Commit-Referenzen von Pfadangaben und verhindert Mehrdeutigkeiten, etwa wenn ein Dateiname zufaellig wie ein Branch-Name aussieht.

Pathspecs erlauben deutlich praezisere Filter als einfache Verzeichnisangaben. Mit git diff -- '*.phtml' lassen sich beispielsweise ausschließlich Template-Dateien anzeigen, unabhaengig davon, in welchem Modul sie liegen. Magic Pathspecs wie git diff -- ':!vendor' schliessen bestimmte Verzeichnisse explizit aus, was bei generierten Vendor-Ordnern oder kompilierten Assets in pub/static den Diff drastisch verkuerzt und auf tatsaechlich relevanten, manuell gepflegten Code fokussiert. Diese Kombination aus Pfadfilterung und den Flags aus dem vorherigen Abschnitt macht auch riesige Merge-Diffs in wenigen Sekunden ueberschaubar.

8. Besseres Diff-Tool und Pager konfigurieren

Der eingebaute Diff-Output von Git ist funktional, aber bei laengeren Diffs schnell unuebersichtlich, vor allem in Standardterminals ohne Syntax-Highlighting. Tools wie delta oder diff-so-fancy setzen sich als Pager zwischen Git und das Terminal und rendern denselben Diff-Output mit Syntax-Highlighting, Seite-an-Seite-Ansicht und deutlich klarerer Zeilennummerierung. Die Konfiguration erfolgt über core.pager für die allgemeine Paginierung und interactive.diffFilter beziehungsweise die native delta-Integration für farbige Diffs.

Fuer grafische Vergleiche, etwa bei Merge-Konflikten oder komplexen Refactorings, ist git difftool mit einem externen Tool wie Meld, KDiff3 oder der IDE-eigenen Diff-Ansicht von PhpStorm oft praktischer als die Terminal-Ausgabe. Die Konfiguration in diff.tool und difftool.<name>.cmd legt fest, welches Programm bei git difftool gestartet wird, während git diff selbst weiterhin den schnellen Terminal-Output liefert. Beide Ansaetze schliessen sich nicht aus: git diff für den schnellen Blick, git difftool für die detaillierte, visuelle Analyse bei komplexeren Änderungen.


# ~/.gitconfig - improved diff experience with delta and a graphical difftool

[core]
    pager = delta

[interactive]
    diffFilter = delta --color-only

[delta]
    navigate = true
    side-by-side = true
    line-numbers = true
    syntax-theme = Monokai Extended

[diff]
    tool = phpstorm
    colorMoved = default

[difftool "phpstorm"]
    cmd = phpstorm diff \"$LOCAL\" \"$REMOTE\"

[difftool]
    prompt = false

9. Stolperfallen und git diff im Code-Review-Workflow

Der haeufigste Fehler ist die Annahme, git diff zeige alle Änderungen. Tatsaechlich zeigt es nur ungestagte Änderungen, während bereits gestagte Änderungen unsichtbar bleiben, bis man explizit --staged hinzufuegt. Ein zweiter klassischer Fehler entsteht bei Merge-Konflikten: git diff ohne Argumente zeigt während eines aktiven Merges den kombinierten Diff gegen beide Elternteile, was für ungeuebte Augen verwirrend aussieht. Ein dritter Punkt betrifft grosse, binaere oder generierte Dateien, etwa kompilierte CSS-Bundles, bei denen ein vollstaendiger Textdiff wenig aussagekraeftig ist und stattdessen --stat oder ein Ausschluss per Pathspec sinnvoller ist.

Im Code-Review-Workflow zahlt sich eine feste Routine aus: Vor dem Staging git diff, um zu sehen, was ueberhaupt geaendert wurde. Nach dem Staging git diff --staged, um zu pruefen, was tatsaechlich committet wird. Vor dem Push git diff main...HEAD, um den kompletten Beitrag des eigenen Branches gegen die Merge-Base zu sehen, so wie es auch ein Reviewer in einem Pull Request sehen wuerde. Diese drei Schritte fangen die meisten unbeabsichtigten Änderungen ab, bevor sie ueberhaupt in einem Review auffallen muessten.

Szenario Ungeeigneter Befehl Empfohlener Befehl Vorteil
Ungestagte Änderungen pruefen direkt git commit -am git diff Änderungen vor dem Commit sichtbar machen
Gestagte Änderungen vor Commit pruefen git diff (zeigt hier nichts) git diff --staged Zeigt exakt den kommenden Commit-Inhalt
Ueberblick bei grossem Merge-Diff vollstaendigen Diff ungefiltert lesen git diff --stat Schneller Ueberblick vor der Detailanalyse
Aenderung an Uebersetzungstext pruefen Standard-Zeilendiff git diff --word-diff Nur das geaenderte Wort wird markiert
Nach automatischem Reformatieren pruefen git diff ohne Whitespace-Filter git diff -w Nur inhaltliche Änderungen bleiben sichtbar
Feature-Branch gegen main reviewen git diff main feature/x git diff main...feature/x Vergleich gegen Merge-Base, keine main-Fremdcommits

Wer die Empfehlungen aus der Tabelle in die eigene Routine uebernimmt, reduziert die Zahl der ueberraschenden Änderungen in Pull Requests spuerbar. Besonders die Unterscheidung zwischen git diff branchA branchB und git diff branchA...branchB wird in Reviews haeufig uebersehen und fuehrt dazu, dass ein Diff Änderungen enthaelt, die gar nicht zum eigentlichen Feature gehoeren, sondern nur zeitlich parallel auf main gelandet sind.

Mironsoft

Git-Workflow-Beratung, Code-Review-Tooling und Entwickler-Schulungen für Magento-Teams

Saubere Git-Workflows für euer Magento-Team?

Wir analysieren bestehende Git-Praktiken in Magento-Projekten, richten Diff-Tools und Pager für euer Team ein und schulen Entwickler in effizienten Review-Workflows, die Fehler vor dem Merge statt danach abfangen.

Git-Workflow-Audit

Branching-Strategie, Commit-Hygiene und Review-Prozesse pruefen

Tooling-Setup

delta, diff-so-fancy und PhpStorm-Difftool teamweit konfigurieren

Entwickler-Schulung

Praxis-Workshop zu git diff, Rebase und Konfliktloesung

10. Zusammenfassung

git diff im Detail loest ein wiederkehrendes Problem im Entwickleralltag: Ohne klares Verstaendnis der drei Vergleichsebenen, Working Directory, Staging Area und letzter Commit, wirken Diff-Ergebnisse zufaellig statt vorhersehbar. git diff zeigt ungestagte Änderungen, git diff --staged zeigt, was tatsaechlich committet wird, und git diff HEAD fasst beides zusammen. Flags wie --stat, --word-diff und -w filtern gezielt nach dem, was in der jeweiligen Situation wirklich relevant ist, statt jedes Mal den vollstaendigen, ungefilterten Diff zu lesen.

Fuer den Vergleich zwischen Branches und Commits ist die drei-Punkt-Notation branchA...branchB fast immer die richtige Wahl bei Feature-Branch-Reviews, während die zwei-Punkt-Notation den direkten Stand-Vergleich liefert. Ein konfiguriertes Diff-Tool wie delta mit Syntax-Highlighting und Seite-an-Seite-Ansicht macht laengere Diffs im Terminal erheblich lesbarer und reduziert die Zeit, die für das reine Verstehen eines Diffs noetig ist, bevor die eigentliche inhaltliche Bewertung beginnen kann.

git diff im Detail, Das Wichtigste auf einen Blick

Drei Vergleichsebenen

git diff zeigt ungestagt, git diff --staged zeigt den Index, git diff HEAD zeigt beides gegen den letzten Commit.

Wichtige Flags

--stat für Ueberblick, --word-diff für Fliesstext, -w um Whitespace zu ignorieren.

Branches & Commits

branchA...branchB gegen Merge-Base vergleichen, HEAD~3 für relative Referenzen nutzen.

Besseres Tooling

core.pager mit delta konfigurieren, diff.tool für grafische Vergleiche in der IDE setzen.

11. FAQ: git diff im Detail

1Was ist der Unterschied zwischen git diff und git diff --staged?
git diff zeigt ungestagte Änderungen im Working Directory. git diff --staged (gleich --cached) zeigt, was in der Staging Area liegt und beim naechsten Commit uebernommen wird.
2Wie vergleiche ich zwei Branches direkt miteinander?
git diff branchA branchB vergleicht die aktuellen Stände direkt. git diff branchA...branchB vergleicht gegen die gemeinsame Merge-Base, meist die richtige Wahl bei Feature-Branch-Reviews.
3Was bewirkt -w bzw. --ignore-all-space?
Blendet reine Whitespace-Änderungen aus, etwa nach automatischem Reformatieren. Zeigt nur Zeilen mit tatsaechlicher inhaltlicher Aenderung.
4Wie aktiviere ich delta oder diff-so-fancy als Standard?
Installieren, dann core.pager auf delta setzen und interactive.diffFilter auf delta --color-only. Weitere Optionen im [delta]-Block der .gitconfig.
5Wie zeige ich nur eine Zusammenfassung der geaenderten Dateien?
git diff --stat zeigt geaenderte Zeilen pro Datei als Zahl und Balkengrafik. git diff --name-only liefert nur die reine Dateiliste.
6Was macht git diff --word-diff genau?
Vergleicht auf Wortebene statt zeilenweise und markiert nur die tatsaechlich geaenderten Woerter. Deutlich lesbarer bei Fliesstext und langen Strings.
7Wie diffe ich nur eine bestimmte Datei oder einen Ordner?
git diff -- pfad/zur/datei.php für eine Datei, git diff -- pfad/zum/ordner/ für ein Verzeichnis. Pathspecs wie '*.phtml' filtern zusaetzlich nach Dateityp.
8Unterschied zwischen git diff A B und git diff A...B?
A B vergleicht die aktuellen Stände direkt. A...B vergleicht gegen die gemeinsame Merge-Base und ignoriert Commits, die nur auf A nach der Trennung passiert sind.
9Wie konfiguriere ich einen Pager für lange Diffs?
git config --global core.pager 'less -R' für einfaches Scrollen, oder core.pager delta für ein vollstaendig aufbereitetes Diff mit Syntax-Highlighting.
10Warum zeigt git diff nichts, obwohl ich etwas geaendert habe?
Die Änderungen wurden vermutlich bereits mit git add gestaged. git diff --staged oder git diff HEAD zeigen dann die tatsaechlichen Änderungen.