ToolZen ToolZen
Text analyzer client

Text Diff

Compare two text blocks and highlight insertions, deletions, and unchanged lines side by side or inline.

Advertisement (Top Banner)
Added Removed Unchanged
Advertisement (Bottom)

Zwei Texte, die identisch aussehen, sind es selten, und den Unterschied mit bloßem Auge zu finden ist eine Aufgabe, in der Menschen spektakulär schlecht sind. Dieses Tool vergleicht Zeile für Zeile und markiert, was hinzukam und was wegfiel. Interessant ist, dass "was hat sich geändert" eine Frage mit mehr als einer richtigen Antwort ist.

Der unsichtbare Unterschied, der alles geändert aussehen lässt

Meldet ein Diff, dass sich jede einzelne Zeile geändert hat, während der Text sichtlich derselbe ist, sind fast immer die Zeilenenden schuld. Windows beendet Zeilen mit Wagenrücklauf plus Zeilenvorschub; Unix, Linux und macOS nehmen nur den Zeilenvorschub. Beide sind auf dem Bildschirm überhaupt nicht zu sehen.

Der Effekt ist total. Teile "uno\ndue\ntre" und "uno\r\ndue\r\ntre" in Zeilen, und du bekommst ["uno","due","tre"] gegen ["uno\r","due\r","tre\r"] — jede Zeile trägt nun einen unsichtbaren Passagier, und nur die letzte, ohne abschließenden Umbruch, passt. Eine von drei. Die Texte sind gleich; die Bytes nicht.

Deshalb hat git autocrlf-Einstellungen, und deshalb streiten Teams darüber. Vergleichst du die Datei eines Kollegen unter Windows mit deiner auf einem Mac, normalisiere die Zeilenenden, bevor du im Ergebnis nach Bedeutung suchst.

Es gibt kein einzig richtiges Diff

Das überrascht, wer annimmt, ein Diff sei eine Tatsache. Ist es nicht — es ist eine Antwort unter mehreren gleich minimalen. Wird eine Zeile aus einer Folge identischer Zeilen gelöscht, sagt nichts im Text, welche verschwand. Der Algorithmus wählt, und verschiedene Algorithmen wählen verschieden.

Füge einer Quelldatei eine Funktion hinzu, und das Diff zeigt vielleicht deine neue Funktion als hinzugefügt — oder es zeigt deine schließende Klammer als hinzugefügt und die der folgenden Funktion als entfernt. Beides ist minimal, eines ist verständlich. Genau deshalb liefert git mehrere Algorithmen: Der Standard Myers ist schnell, während patience und histogram Diffs erzeugen, die besser zu dem passen, wie ein Mensch die Änderung sieht. Keiner ist richtiger. Sie optimieren verschiedene Definitionen einer guten Antwort.

Warum große Vergleiche gegen eine Wand laufen

Der klassische Algorithmus baut eine Tabelle jeder Zeile von A gegen jede Zeile von B, was Zeit und Speicher proportional zum Produkt der beiden Längen kostet. Zwei Dateien mit 12.000 Zeilen brauchen eine Tabelle von 144 Millionen Zellen: über ein Gigabyte Speicher und fast zwei Sekunden Arbeit. Auf einem Telefon ist das ein toter Tab.

Die Rettung: Echte Vergleiche sind selten zufällig. Zwei Fassungen eines Dokuments teilen meist einen langen identischen Kopf und Fuß, und diese Zeilen brauchen gar keine Tabelle — sie sind auf den ersten Blick gleich. Sie zuerst abzuschneiden ist der erste Schritt jeder ernsthaften Diff-Implementierung, und bei zwei 12.000-Zeilen-Dateien mit einer Abweichung schrumpft die Tabelle von 144 Millionen Zellen auf eine Handvoll.

Das deckt den Normalfall ab. Es hilft nicht, wenn zwei große Texte durchgehend wirklich verschieden sind, denn dann gibt es keinen gemeinsamen Kopf oder Fuß zum Abschneiden. Dieses Tool zieht dort eine Grenze und sagt es dir, statt es zu versuchen und zu sterben: Ist der Vergleich nach dem Beschneiden zu groß, bekommst du eine Meldung. Eine bewusste Entscheidung — ein Werkzeug, das deinen Browser einfriert, ist schlimmer als eines, das seine Grenzen zugibt.

Zeilen sind für Prosa die falsche Granularität

Dieses Tool vergleicht ganze Zeilen, was zu Code, Konfiguration und allem passt, wo eine Zeile eine sinnvolle Einheit ist. Zu Prosa passt es schlecht. Ändere ein Wort in einem Absatz, der auf einer einzigen Zeile lebt, und das Diff markiert den ganzen Absatz als entfernt und wieder hinzugefügt — technisch wahr und praktisch nutzlos.

Die Abhilfe dort ist Text mit einem Satz pro Zeile, oder ein Diff auf Wortebene. Es lohnt zu wissen, welche Art man vor sich hat: Ein Zeilen-Diff auf einem umbrochenen Dokument sagt dir, dass ein Absatz sich geändert hat, und nichts darüber, was sich darin geändert hat.

Häufige Fragen

Wird mein Text an einen Server geschickt?

Nein. Dieses Tool ist als "client" gekennzeichnet: Beide Texte werden in deinem Browser-Tab verglichen, keiner verlässt das Gerät. Das zählt hier mehr als sonst, denn zwei Fassungen von etwas zu vergleichen heißt, zwei Fassungen davon zu haben — Verträge, Entwürfe, Konfigurationsdateien mit Zugangsdaten darin.

Warum sagt es, jede Zeile habe sich geändert, obwohl sie gleich aussehen?

Zeilenenden, mit ziemlicher Sicherheit — siehe oben. Der andere Kandidat sind Leerzeichen am Zeilenende, ebenso unsichtbar und ebenso fatal für einen Vergleich. Kann dein Editor unsichtbare Zeichen anzeigen, schalte das ein und sieh dir die Zeilenenden an.

Warum ist am Ende eine zusätzliche Leerzeile?

Weil der Text mit einem Zeilenumbruch endet. "a\nb\n" an Umbrüchen zu teilen ergibt drei Stücke — "a", "b" und eine leere Zeichenkette nach dem letzten Umbruch. Das ist kein Fehler im Diff; das ist, was ein abschließender Zeilenumbruch bedeutet. Die Unix-Konvention sagt, Textdateien sollten mit einem enden — es ist also sehr verbreitet und meist nicht der Rede wert.

Kann es zwei Dateien statt eingefügtem Text vergleichen?

Hier nicht — dies ist ein Einfüge-Werkzeug. Für Dateien, und besonders für alles unter Versionskontrolle, nimm git diff: Es kommt mit Zeilenenden zurecht, bietet die oben erwähnten besseren Algorithmen und kann Änderungen auf Wortebene innerhalb einer Zeile zeigen. Dieses Tool ist für den schnellen Vergleich, bei dem ein Terminal zu öffnen mehr Aufwand wäre, als die Frage verdient.

Ignoriert es Whitespace?

Nein. Jedes Zeichen zählt, auch Leerzeichen am Zeilenende und Einrückung. Das ist die richtige Vorgabe für ein allgemeines Werkzeug — manchmal ist Whitespace genau die Änderung, die du suchst — bedeutet aber, dass eine neu eingerückte Datei als komplett neu geschrieben erscheint. Ist das deine Lage, ignoriert git diff -w Whitespace und zeigt dir, was sich wirklich bewegt hat.