Git-Diff-Algorithmen im Vergleich: Myers, Patience, Histogram
AI generated
git
HEAD
Git · Diff · Interna
Git-Diff-Algorithmen im Vergleich
Myers, Patience und Histogram anhand konkreter Beispiele

Git verwendet standardmäßig den Myers-Algorithmus, um Unterschiede zwischen zwei Dateiversionen zu berechnen, doch das ist längst nicht die einzige Option. Patience Diff und Histogram Diff verfolgen einen anderen Ansatz und liefern bei verschobenem oder umsortiertem Code oft deutlich verständlichere Ergebnisse. Dieser Artikel erklärt, wie die vier in Git verfügbaren Algorithmen intern arbeiten, woran sich ihre Unterschiede in der Praxis zeigen und wie sich der passende Algorithmus dauerhaft konfigurieren lässt.

10 Min. Lesezeit Git Diff Algorithmen

1. Warum der gewählte Diff-Algorithmus überhaupt einen Unterschied macht

Ein Diff zwischen zwei Dateiversionen ist mathematisch betrachtet nie eindeutig: Es gibt fast immer mehrere gültige Wege, eine Datei in eine andere zu überführen, und ein Diff-Algorithmus muss sich für einen davon entscheiden. Genau darin unterscheiden sich die in Git verfügbaren Algorithmen, sie optimieren unterschiedliche Kriterien und erzeugen dadurch bei identischem Ausgangsmaterial teils sehr verschiedene, aber jeweils technisch korrekte Diffs.

Für ein Review ist das keineswegs nur eine akademische Feinheit: Ein Diff, der eine verschobene Funktion als vollständiges Löschen und Neuhinzufügen darstellt, kostet einen Reviewer deutlich mehr Zeit und Aufmerksamkeit als ein Diff, der dieselbe Funktion klar als unverändert verschobenen Block erkennt und nur die tatsächlich geänderten Zeilen daneben markiert.

2. Myers-Algorithmus: Git-Standard und seine Funktionsweise

Der Myers-Algorithmus ist der Standardalgorithmus in Git und basiert auf der Suche nach der längsten gemeinsamen Teilfolge zweier Zeilenlisten, kurz LCS. Er berechnet die kürzestmögliche Bearbeitungssequenz aus Einfüge- und Löschoperationen, die eine Datei in die andere überführt, und ist dabei mathematisch nachweisbar optimal in Bezug auf die Anzahl der erzeugten Diff-Zeilen.

Genau diese Optimierung auf minimale Zeilenzahl kann jedoch zu unerwarteten Ergebnissen führen: Der Algorithmus kennt keinen Begriff von semantischer Bedeutung und kann daher zufällig passende, aber inhaltlich völlig unabhängige Zeilen als zusammengehörig interpretieren, etwa eine schließende geschweifte Klammer, die an vielen Stellen einer Datei identisch aussieht.


# Myers ist der Standard, muss also nicht explizit angegeben werden
git diff --diff-algorithm=myers

3. Patience Diff: eindeutige gemeinsame Zeilen als Anker

Patience Diff verfolgt eine andere Strategie: Es sucht zunächst gezielt nach Zeilen, die in beiden Dateiversionen jeweils genau einmal vorkommen, und nutzt diese eindeutigen Zeilen als feste Ankerpunkte. Zwischen zwei aufeinanderfolgenden Ankern wird der Diff rekursiv erneut berechnet, wodurch sich der Algorithmus deutlich stärker an eindeutigen Strukturmerkmalen des Codes orientiert als der rein zeilenbasierte Myers-Algorithmus.

Dieser Ansatz zahlt sich besonders bei verschobenen Codeblöcken aus: Eine eindeutige Funktionssignatur oder ein charakteristischer Kommentar dient als verlässlicher Ankerpunkt, wodurch der gesamte dazwischenliegende Block eher als zusammenhängende Verschiebung erkannt wird, statt in viele kleine, verwirrende Einzeländerungen zerlegt zu werden.


git diff --diff-algorithm=patience

4. Histogram Diff: Weiterentwicklung von Patience mit besserer Performance

Histogram Diff baut konzeptionell auf der Idee von Patience Diff auf, verwendet zur Suche nach eindeutigen Ankerzeilen aber eine Häufigkeitstabelle, ein sogenanntes Histogramm, statt einer aufwendigeren Suche nach der längsten gemeinsamen Teilfolge an jeder Stelle. Dadurch bleibt das grundlegende Verhalten dem von Patience Diff sehr ähnlich, die Berechnung selbst läuft aber in der Praxis merklich schneller ab.

Wegen dieser Kombination aus patience-ähnlicher Ergebnisqualität und besserer Performance ist Histogram in vielen Projekten inzwischen die bevorzugte Alternative zum Myers-Standard, auch außerhalb von Git: Andere Werkzeuge wie JGit verwenden Histogram bereits standardmäßig, weil es bei realistischen Codeänderungen einen guten Kompromiss zwischen Lesbarkeit und Rechenaufwand darstellt.


git diff --diff-algorithm=histogram

5. Der Minimal-Algorithmus und wann er sinnvoll ist

Der Minimal-Algorithmus ist im Kern eine Variante des Myers-Algorithmus, die zusätzlichen Rechenaufwand investiert, um die absolut kürzestmögliche Diff-Ausgabe zu garantieren, selbst wenn der reguläre Myers-Algorithmus aus Performancegründen bereits vorher eine nahezu optimale, aber nicht ganz minimale Lösung akzeptiert hätte.

In der Praxis lohnt sich Minimal vor allem bei sehr kleinen, aber kritischen Diffs, etwa bei automatisiert generierten Patches, die anschließend maschinell weiterverarbeitet werden und bei denen jede überflüssige Diff-Zeile echten Mehraufwand verursacht. Für den alltäglichen Review-Einsatz bringt Minimal gegenüber Myers dagegen selten einen spürbaren Unterschied.


git diff --diff-algorithm=minimal

6. Diff-Algorithmus gezielt pro Aufruf wählen

Für einen einmaligen Test lässt sich der Algorithmus direkt über die Kommandozeilenoption --diff-algorithm bei jedem einzelnen Aufruf von git diff, git show oder git log -p festlegen, ohne die dauerhafte Konfiguration zu verändern. Das eignet sich gut, um bei einem verwirrenden Diff schnell auszuprobieren, ob ein anderer Algorithmus ein klareres Bild liefert.

Gerade bei umfangreichen Refactorings, bei denen ganze Methoden oder Klassen innerhalb einer Datei verschoben wurden, lohnt sich dieser schnelle Vergleich fast immer: Ein Wechsel von Myers zu Histogram macht in solchen Fällen häufig den Unterschied zwischen einem unlesbaren Wust aus Löschungen und Einfügungen und einem klar erkennbaren, verschobenen Block.


# Bei einem unklaren Diff schnell einen anderen Algorithmus ausprobieren
git diff --diff-algorithm=histogram HEAD~1

7. Algorithmus dauerhaft konfigurieren

Statt den Algorithmus bei jedem Aufruf erneut anzugeben, lässt sich über git config diff.algorithm ein Standardwert für das gesamte Repository oder global für alle Repositories eines Nutzers hinterlegen. Viele Teams setzen dabei inzwischen histogram als neuen Standardwert, weil es in der Praxis selten schlechtere Ergebnisse als Myers liefert und bei verschobenem Code klar überlegen ist.

Diese Einstellung wirkt sich auch auf Werkzeuge aus, die intern auf git diff zurückgreifen, etwa viele grafische Git-Clients und IDE-Integrationen, sofern diese die Git-Konfiguration korrekt respektieren und keinen eigenen, fest verdrahteten Diff-Algorithmus mitbringen.


# Histogram als dauerhaften Standard für dieses Repository setzen
git config diff.algorithm histogram

# Oder global für alle Repositories des aktuellen Nutzers
git config --global diff.algorithm histogram

8. Indent-Heuristik als Ergänzung zum Algorithmus

Unabhängig vom gewählten Algorithmus setzt Git standardmäßig zusätzlich eine sogenannte Indent-Heuristik ein, die Diff-Grenzen bevorzugt an Zeilen mit geringerer Einrückung ausrichtet, etwa am Ende eines Blocks statt mitten in einer Bedingung. Das führt in der Praxis häufig zu intuitiveren Diffs, weil Klammern und Blockgrenzen eher zusammen bleiben, statt willkürlich mitten im Code aufzureißen.

Die Heuristik ist seit einigen Git-Versionen standardmäßig aktiviert und lässt sich über diff.indentHeuristic bei Bedarf gezielt deaktivieren, was aber in der Praxis nur selten sinnvoll ist. Sie arbeitet unabhängig vom gewählten Diff-Algorithmus als zusätzlicher Nachbearbeitungsschritt, kombiniert sich also mit Myers ebenso wie mit Histogram oder Patience.


# Indent-Heuristik explizit deaktivieren, standardmäßig ist sie aktiv
git config diff.indentHeuristic false

9. Praxisbeispiel: verschobene Funktion und wie sich die Algorithmen unterscheiden

Wird eine Hilfsfunktion innerhalb einer Datei nach unten verschoben und gleichzeitig eine neue Funktion an ihre alte Stelle geschrieben, interpretiert Myers das Ergebnis oft als eine Reihe verschachtelter Löschungen und Einfügungen quer über die gesamte Datei, weil der Algorithmus rein auf minimale Zeilenzahl optimiert, ohne semantisches Verständnis für zusammengehörige Blöcke.

Patience und Histogram erkennen dagegen anhand eindeutiger Zeilen wie der Funktionssignatur meist zuverlässig, dass es sich um eine reine Verschiebung handelt, und stellen die verschobene Funktion als unverändert dar, während nur die tatsächlich neue Funktion als Einfügung markiert wird. Bei Codeänderungen mit vielen wiederholten, generischen Zeilen, etwa kurzen schließenden Klammern, liefert Myers dagegen manchmal überraschend kompaktere Ergebnisse als die anderen Algorithmen.

Algorithmus Grundprinzip Typische Stärke Empfehlung
Myers Kürzeste Editier-Sequenz über LCS Sehr schnell, mathematisch minimal Git-Standard, für die meisten Diffs ausreichend
Minimal Myers mit erzwungen absolutem Minimum Garantiert kürzestmöglicher Diff Kleine, kritische, maschinell verarbeitete Diffs
Patience Eindeutige Zeilen als Anker, rekursiv Sehr gute Lesbarkeit bei verschobenem Code Umfangreiche Refactorings mit Verschiebungen
Histogram Patience-Prinzip mit Häufigkeitstabelle Ähnliche Qualität wie Patience, schneller Guter neuer Standard für die meisten Teams

Mironsoft

Git-Workflows, Branching-Strategien und CI-Hooks

Chaotische Git-Historie und unklare Branching-Regeln im Team?

Wir richten saubere Git-Workflows ein, klären Branching-Strategien fürs Team und automatisieren Qualitätschecks über Git-Hooks und CI-Pipelines, damit die Historie nachvollziehbar bleibt.

Workflow-Audit

Bestehende Branching-Strategie und Merge-Praxis auf Schwachstellen prüfen.

Hook-Automatisierung

Pre-Commit- und Pre-Push-Hooks für Linting, Tests und Commit-Konventionen einrichten.

Team-Schulung

Rebase, Cherry-Pick und Konfliktauflösung im Team praxisnah vermitteln.

10. Zusammenfassung

Diff-Algorithmen

Standardalgorithmus

Myers berechnet über die längste gemeinsame Teilfolge die kürzestmögliche Editier-Sequenz, kennt aber keine semantische Bedeutung.

Bessere Lesbarkeit

Patience und Histogram nutzen eindeutige Zeilen als Anker und erkennen verschobene Codeblöcke deutlich zuverlässiger.

Praktische Nutzung

Mit --diff-algorithm einmalig testen, mit git config diff.algorithm dauerhaft für Repository oder Nutzer setzen.

Zusatzoption

Die standardmäßig aktive Indent-Heuristik ergänzt jeden Algorithmus und richtet Diff-Grenzen an Einrückung aus.

11. FAQ: Diff-Algorithmen

1Welchen Diff-Algorithmus verwendet Git standardmäßig?
Git nutzt standardmäßig den Myers-Algorithmus, der über die längste gemeinsame Teilfolge die kürzestmögliche Editier-Sequenz zwischen zwei Dateiversionen berechnet.
2Warum liefert derselbe Codeunterschied je nach Algorithmus unterschiedliche Diffs?
Ein Diff ist mathematisch nie eindeutig, es gibt meist mehrere gültige Wege, eine Datei in eine andere zu überführen. Jeder Algorithmus optimiert dabei ein anderes Kriterium und trifft dadurch unterschiedliche, jeweils korrekte Entscheidungen.
3Wann liefert Patience Diff bessere Ergebnisse als Myers?
Vor allem bei verschobenem oder umsortiertem Code, weil Patience eindeutige, in beiden Versionen genau einmal vorkommende Zeilen als feste Ankerpunkte nutzt und den Block dazwischen als zusammenhängend erkennt.
4Was unterscheidet Histogram von Patience konkret?
Histogram verwendet zur Suche nach eindeutigen Ankerzeilen eine Häufigkeitstabelle statt einer aufwendigeren LCS-Suche und ist dadurch bei ähnlicher Ergebnisqualität in der Praxis merklich schneller.
5Wann sollte ich den Minimal-Algorithmus verwenden?
Vor allem bei kleinen, kritischen Diffs, die anschließend maschinell weiterverarbeitet werden, etwa automatisiert generierte Patches, bei denen jede überflüssige Zeile echten Mehraufwand verursacht.
6Wie teste ich einen anderen Algorithmus für einen einzelnen Diff, ohne die Konfiguration zu ändern?
Über die Option --diff-algorithm bei git diff, git show oder git log -p, etwa git diff --diff-algorithm=histogram HEAD~1, ohne dass eine dauerhafte Einstellung nötig ist.
7Wie setze ich Histogram als dauerhaften Standard?
Mit git config diff.algorithm histogram für das aktuelle Repository oder mit dem Zusatz --global für alle Repositories des aktuellen Nutzers.
8Was macht die Indent-Heuristik zusätzlich zum gewählten Algorithmus?
Sie richtet Diff-Grenzen bevorzugt an Zeilen mit geringerer Einrückung aus, etwa am Ende eines Blocks, und arbeitet als zusätzlicher Schritt unabhängig davon, welcher Algorithmus zuvor gewählt wurde.
9Wirkt sich die Konfiguration von diff.algorithm auch auf grafische Git-Clients aus?
Bei Werkzeugen, die intern auf git diff zurückgreifen und die Git-Konfiguration respektieren, ja. Clients mit eigenem, fest verdrahtetem Diff-Algorithmus berücksichtigen die Einstellung dagegen nicht.
10Verursacht ein Wechsel des Diff-Algorithmus irgendein Risiko für das Repository?
Nein, der Algorithmus beeinflusst ausschließlich die Darstellung eines Diffs, nicht den gespeicherten Inhalt der Commits. Ein Wechsel ist jederzeit gefahrlos und ohne Auswirkung auf die eigentliche Historie möglich.