Wenn zwei Dateien „inhaltlich gleich“ sind, diff aber trotzdem viele Unterschiede meldet, liegt das oft am Leerraum: Der Editor hat Leerzeichen am Zeilenende entfernt, Tabs in Leerzeichen umgewandelt oder die Einrückungsbreite geändert. diff-Werkzeuge bieten Optionen, um solche Unterschiede zu ignorieren, doch jede Option ignoriert etwas anderes — man sollte sie daher genau kennen.
Leerraum-Optionen von GNU diff
| Option | Langer Name | Ignoriert |
|---|---|---|
-Z | --ignore-trailing-space | Leerraum am Zeilenende |
-E | --ignore-tab-expansion | Unterschiede durch zu Leerzeichen expandierte Tabs |
-b | --ignore-space-change | Änderungen der Menge an Leerraum, Leerraum am Zeilenende |
-w | --ignore-all-space | jeglichen Leerraum |
-B | --ignore-blank-lines | Änderungen, die nur Leerzeilen hinzufügen oder löschen |
-i | --ignore-case | Groß-/Kleinschreibung |
--strip-trailing-cr | CR-Zeichen am Ende der Eingabezeilen |
Die entsprechenden Optionen von git diff
Die git-Dokumentation beschreibt sie so:
--ignore-cr-at-eol: Ignoriert beim Vergleich den Wagenrücklauf (CR) am Zeilenende.--ignore-space-at-eol: Ignoriert Änderungen des Leerraums am Zeilenende.-b,--ignore-space-change: Ignoriert Änderungen der Menge an Leerraum. Leerraum am Zeilenende wird ignoriert, und alle anderen Folgen aus einem oder mehreren Leerraumzeichen gelten als gleich.-w,--ignore-all-space: Ignoriert Leerraum beim Vergleich von Zeilen. Auch Unterschiede, bei denen eine Zeile Leerraum enthält und die andere keinen, werden ignoriert.--ignore-blank-lines: Ignoriert Änderungen, deren Zeilen alle leer sind.
Der entscheidende Unterschied zwischen -b und -w
Die beiden Optionen werden oft verwechselt. Entscheidend ist, ob unterschieden wird, ob Leerraum vorhanden ist oder nicht.
| Links | Rechts | -b (Menge ignorieren) | -w (allen Leerraum ignorieren) |
|---|---|---|---|
a b | a b | gleich | gleich |
a b | ab | verschieden | gleich |
x = 1 | x=1 | verschieden | gleich |
if (a) + Leerzeichen am Zeilenende | if (a) | gleich | gleich |
| Einrückung mit 1 Tab | Einrückung mit 4 Leerzeichen | gleich | gleich |
-b betrachtet jeden Leerraum-Block als ein einziges Leerzeichen, -w entfernt vor dem Vergleich jeglichen Leerraum. Deshalb hält -w x = 1 und x=1 für gleich — und sogar int a und inta.
Die Gefahr, wenn Einrückung Bedeutung hat
In Dateien, in denen Einrückung zur Syntax gehört, etwa Python, YAML oder Makefiles, können Leerraum-Optionen echte Änderungen verbergen.
if ready:
start()
notify()
if ready:
start()
notify()
In der zweiten Fassung steht notify() außerhalb der if-Anweisung, das Verhalten hat sich also geändert. Mit -w wird aller Leerraum entfernt, und der Unterschied verschwindet. -b erkennt ihn, weil der Leerraum am Zeilenanfang von „vorhanden“ zu „nicht vorhanden“ gewechselt hat. Wird die Einrückung dagegen von 4 auf 8 Leerzeichen erhöht, sodass der Code in einen tieferen Block rückt, hat sich nur die Menge an Leerraum geändert — dann sieht man es auch mit -b nicht.
Der sichere Weg: Dateien, in denen Einrückung wichtig ist, mit ausgeschalteten Leerraum-Optionen vergleichen. Es ist eine gute Gewohnheit, die Optionen nur zu nutzen, um zu prüfen, ob eine Änderung reine Formatierung ist, und die abschließende Prüfung ohne Optionen zu machen.
Reichweite von „Leerzeilen ignorieren“ (-B)
-B und --ignore-blank-lines von git blenden Änderungen aus, die nur aus Leerzeilen bestehen. Steht eine hinzugefügte Leerzeile im selben Hunk wie eine echte Änderung, kann sie trotzdem angezeigt werden. Nützlich ist die Option bei Dokumenten, in denen die Zahl der Leerzeilen zwischen Absätzen geändert wurde, oder wenn ein Code-Formatierer die Leerzeilen zwischen Funktionen angepasst hat.
Die Optionen dieser Seite im Vergleich
| Diese Seite | Nächste Entsprechung in GNU diff | Nächste Entsprechung in git diff |
|---|---|---|
| Leerraum: unverändert vergleichen | (keine Option) | (keine Option) |
| Leerraum: am Zeilenende ignorieren | -Z | --ignore-space-at-eol |
| Leerraum: Menge ignorieren | -b | -b |
| Leerraum: allen ignorieren | -w | -w |
| Groß-/Kleinschreibung ignorieren | -i | (keine Entsprechung) |
| Leerzeilen ignorieren | ähnlich wie -B (Leerzeilen werden vom Vergleich ausgenommen) | ähnlich wie --ignore-blank-lines |
| Zeilenenden normalisieren | --strip-trailing-cr + fehlender Umbruch am Dateiende wird ignoriert | ähnlich wie --ignore-cr-at-eol |
„Leerzeilen ignorieren“ nimmt Leerzeilen auf dieser Seite ganz aus dem Vergleich heraus und zeigt sie nur blass an. Außerdem gelten die Ignorieroptionen auch für die Hervorhebung innerhalb der Zeile: Ist „Menge ignorieren“ aktiv, werden Stellen, an denen sich nur die Zahl der Leerzeichen unterscheidet, nicht hervorgehoben.
In diesem Werkzeug ausprobieren
Fügen Sie die Beispiele aus der Tabelle in den Textvergleich ein und schalten Sie die Leerraum-Optionen nacheinander um — die Unterschiede sind sofort zu sehen. „Unsichtbare Unterschiede“ wie ein CR am Zeilenende oder der Umbruch am Dateiende werden in Zeilenenden und unsichtbare Unterschiede behandelt, wie man das Ergebnis als Patch liest, erklärt Unified Diff lesen.