guide/line-endings.md

Zeilenenden (CRLF, LF) und unsichtbare Unterschiede — wenn angeblich jede Zeile geändert ist

Warum diff alle Zeilen als verschieden meldet, obwohl sie gleich aussehen: CRLF- und LF-Zeilenumbrüche, Umbruch am Dateiende, BOM, Tabs und Leerzeichen, besondere Leerzeichen, Unicode-Normalisierung — und wie man das behebt.

Zuletzt aktualisiert: 2026-09-23

Manchmal unterscheiden sich zwei geöffnete Dateien um kein einziges sichtbares Zeichen, doch diff meldet, dass sich jede Zeile geändert hat, oder dass nur die erste oder die letzte Zeile verschieden ist. Die Ursache sind meist Zeichen, die auf dem Bildschirm nicht zu sehen sind. Dieser Artikel stellt die Arten solcher „unsichtbaren Unterschiede“ und ihre Lösungen vor.

Zeilenumbruchzeichen: CRLF, LF, CR

Wie eine Zeile beendet wird, ist je nach Betriebssystem unterschiedlich geregelt.

BezeichnungBytesVor allem verwendet in
LF0A (\n)Linux, macOS, den meisten Entwicklerwerkzeugen
CRLF0D 0A (\r\n)vielen Windows-Programmen wie dem Editor, Internetprotokollen wie E-Mail und HTTP
CR0D (\r)sehr altem Mac OS (bis Version 9)

Ist eine Datei mit CRLF und die andere mit LF gespeichert, wird beim zeilenweisen Vergleich an jedem Zeilenende ein unsichtbares \r als Unterschied erkannt, und alles scheint geändert. GNU diff kann diesen Unterschied mit --strip-trailing-cr, git diff mit --ignore-cr-at-eol ignorieren.

Zeilenumbruch am Dateiende

Nach POSIX-Konvention endet jede Zeile einer Textdatei mit einem Zeilenumbruchzeichen. Viele Werkzeuge setzen deshalb auch hinter die letzte Zeile einen Umbruch, manche Editoren aber nicht. Im Unified Diff wird dieser Unterschied so dargestellt:

@@ -1,2 +1,2 @@ host=example.com-port=8080\ No newline at end of file+port=8080

\ No newline at end of file bedeutet, dass am Ende der Zeile direkt darüber kein Zeilenumbruch steht. Im Beispiel ist der Inhalt gleich; nur die neue Datei hat einen abschließenden Zeilenumbruch bekommen. Viele Code-Styleguides verlangen einen Umbruch am Dateiende, und mit der Editor-Einstellung „Zeilenumbruch am Dateiende einfügen“ lässt sich das vereinheitlichen.

BOM: wenn nur die erste Zeile abweicht

Manchmal stehen am Anfang einer UTF-8-Datei die drei Bytes EF BB BF. Das ist die Byte-Order-Mark (BOM). UTF-8 braucht keine Byte-Reihenfolge, aber manche Programme fügen sie als Kennzeichen „diese Datei ist UTF-8“ ein. Die BOM ist unsichtbar — meldet diff, dass nur die erste Zeile verschieden ist, sollten Sie an eine BOM denken. Diese Seite entfernt beim Laden einer Datei eine BOM am Anfang, und bei aktivierten Leerraum-Optionen wird eine BOM (U+FEFF) in eingefügtem Text ebenfalls wie Leerraum behandelt.

Tabs, Leerzeichen und besondere Leerzeichen

Die meisten dieser Zeichen werden herausgefiltert, wenn Sie die Leerraum-Optionen aktivieren (Zeichen wie U+200B, die nicht als Leerraum klassifiziert sind, können allerdings auch dann bestehen bleiben). Stellen Sie den Vergleich innerhalb der Zeile auf Zeichen um, zeigt die Hervorhebung, an welcher Stelle ein unsichtbares Zeichen steht.

Unicode-Normalisierung: gleiches Zeichen, andere Bytes

Das „ü“ lässt sich als ein einziges Zeichen (U+00FC) schreiben oder als „u“ (U+0075), gefolgt vom kombinierenden Trema (U+0308). Ebenso kann die koreanische Silbe „가“ als ein vorkomponiertes Zeichen (U+AC00) oder als Folge der Jamo ㄱ (U+1100) und ㅏ (U+1161) dargestellt werden. Unicode nennt die erste Form NFC und die zweite NFD (UAX #15). Die beiden Texte sehen auf dem Bildschirm identisch aus, sind beim Vergleich aber verschiedene Zeichen. Ein typisches Beispiel: Auf macOS erstellte Dateinamen erscheinen auf anderen Betriebssystemen manchmal in ihre Bestandteile zerlegt, etwa koreanische Silben als einzelne Jamo („ㄱㅏ“). Die Lösung: vor dem Vergleich eine Seite in NFC umwandeln, damit beide übereinstimmen.

Zeilenumbrüche in git vereinheitlichen

In Repositorys, an denen auf mehreren Betriebssystemen gearbeitet wird, lassen sich Zeilenumbrüche über git-Einstellungen vereinheitlichen.

* text=auto
*.sh text eol=lf
*.bat text eol=crlf

text=auto normalisiert die Zeilenumbrüche von Dateien, die git als Textdateien erkennt, im Repository auf LF; eol=lf und eol=crlf legen fest, welche Zeilenumbrüche beim Auschecken ins Arbeitsverzeichnis verwendet werden.

In diesem Werkzeug ausprobieren

Zeilenenden normalisieren ist im Textvergleich standardmäßig aktiv: CRLF, CR und LF gelten als derselbe Umbruch, und ob am Dateiende ein Umbruch steht, wird ignoriert. Schalten Sie die Option aus, wird ein CR am Zeilenende als und eine letzte Zeile ohne Umbruch mit angezeigt, sodass Sie die bisher unsichtbaren Unterschiede sehen. Die Leerraum-Optionen erklärt Leerraum ignorieren, die Bedeutung der Symbole im Ergebnis Unified Diff lesen.

Zum Textvergleich