Git und die Zeilenenden

Letzte Änderung am 30. September 2021 by Christoph Jüngling

Quecksilber

Quecksilber
Von Own work – Eigenes Werk, CC BY 3.0, Link

Eine Quellcodeverwaltung wie z.B. Git oder Mercurial (Hg) ist hervorragend geeignet, auch kleine Projekte zu verwalten. Der Aufwand, ein neues lokales Repository zu erstellen, beschränkt sich auf die Kommandozeilenbefehle git init oder hg init und ist damit vergleichsweise minimal. Auch die verfügbaren graphischen Oberflächen wie z.B. TortoiseGit oder TortoiseHg bieten recht einfache Befehle über das Kontextmenü im Windows-Explorer an. Das beste daran ist aber, dass diese beiden Tools (natürlich auch weitere) aufgrund des dezentralen Charakters keinerlei zentrales Repository auf irgendeinem Server oder in der Cloud benötigen! Bei Bedarf kann ein solches jedoch problemlos angebunden werden.

Der kleine Unterschied

Solange ich nur alleine arbeite, kann ich damit leben, dass alle Dateien so eingecheckt werden, wie ich sie schreibe, und auch ebenso wieder aus dem Repository heraus kommen. Doch was ist, wenn ich mit Kollegen zusammenarbeite? In einem Python-Projekt kann es z.B. durchaus passieren, dass einer von ihnen Windows verwendet, während ich unter Linux programmieren möchte. Und schon könnten wir ein Problem mit den Zeilenenden bekommen.

Der Unterschied ist minimal, aber für manche Programme entscheidend. In aller Kürze sieht es bei den Zeilenenden im Moment so aus:

  • Windows: CR + LF
  • Linux und Mac OS (ab OS X): LF
  • Mac OS (bis Version 9): CR

Wir reden übrigens über die ASCII/ANSI-Codes 13 (0x0D) für CR (“Carriage Return”) und 10 (0x0A) für LF (“Line Feed”).

Wer mal versucht hat, mit dem Standard-Notepad unter Windows eine unter Linux geschriebene Textdatei zu öffnen, hat sich sicher schon über das merkwürdige Format gewundert. Da Notepad bis zu einem gewissen Punkt das LF (Line Feed, Ascii 10) nicht als Zeilenumbruch interpretiert hat, hat es den Text einfach fortlaufend dargestellt, bestenfalls noch mit einem Quadratsymbol anstelle des LF. Das ist nicht wirklich lesbar, und für Programmcode indiskutabel. Aufwändigere Editoren wie UltraEdit oder Notepad++ haben damit noch nie Probleme gehabt. Aber man weiß ja nicht, was der Kollege verwenden will.

Die Lösung in Git

Praktischerweise kennt Git eine Option, die uns hilft, dieses Problem gar nicht erst auftreten zu lassen. Alles was man tun muss, ist beim Einrichten des Repositories je nach Betriebssystem darauf zu achten, die richtige Einstellung vorzunehmen. Dabei sollte eine Vorüberlegung nicht vergessen werden: Git unterscheidet bei solchen Optionen, ob es eine globale (also für den gesamten Rechner), benutzerspezifische oder repositoryspezifische Einstellung ist. Gehen wir davon aus, dass die Zeilenendeneinstellung etwas mit dem Betriebssystem zu tun hat, dann dürfte die globale Einstellung in diesem Fall die beste sein. Doch diese erfordert i.d.R. Adminrechte, über die wir auf einem Kundenrechner vielleicht nicht verfügen. Dann bietet sich die Konfiguration auf Benutzerebene an.

Die Kommandozeile unterscheidet die obigen drei Möglichkeiten mit den Parametern --system, --global und --local, der Befehl zum Konfigurieren lautet git config und die Einstellung für die Zeilenenden core.autocrlf. Empfohlene Einstellungen sind dann:

  • Windows: git config --global core.autocrlf true
  • Linux und Mac: git config --global core.autocrlf input

Der Vollständigkeit halber sei erwähnt, dass auch der Wert false zulässig ist. Dieser führt allerdings dazu, dass alle Dateien immer genau so ein- und ausgecheckt werden, wie sie gerade sind. Das ist bestenfalls dann sinnvoll, wenn man alleine immer auf dem selben System arbeitet oder wirklich alle z.B. mit Windows unterwegs sind. Mit den oben empfohlenen Einstellungen vergibt man sich nichts und ist selbst dann noch auf der sicheren Seite, wenn ein Kollege in’s Team kommt, der ganz andere Betriebssystemvorlieben hat.

Sicher ist sicher

Um für den Fall, dass doch mal eine andere Datei auftaucht, auf Nummer sicher zu gehen, gibt es eine weitere Einstellung: core.safecrlf. Diese kann auf true oder false gesetzt werden. Steht der Wert auf true, dann kann eine Datei, die z.B. unter Windows zufälligerweise mit LF gespeichert wurde (was TortoiseGit gern für die .gitignore macht) nicht committet werden.

Ausnahmen von der Regel

In einem aktuellen Projekt muss ich unter Windows Dateien im Repository verwalten, die zusammen mit anderen gezippt und dann in ein Linux-Zielsystem geladen werden. Dort müssen diese Konfigurationsdateien für einen Treiber unbedingt mit LF als Zeilenende auftauchen. Ein CRLF würde diesen Treiber so sehr irritieren, dass die Funktionalität nicht mehr gewährleistet ist. Folglich müssen die Dateien beim Auschecken aus dem Repository auch unter Windows unbedingt mit LF lokal gespeichert werden.

Da diese Einstellung nur für ein einziges Verzeichnis relevant ist, löse ich dies mit Hilfe der Datei .gitattributes ebenda. Diese enthält im geschilderten Fall nur eine Zeile, die dafür sorgt, dass alle Dateien mit der Erweiterung “cfg” ein LF als Zeilenendezeichen erhalten:

*.cfg   text eol=lf

Dies gilt nur für die Dateien in diesem Verzeichnis und dessen Unterverzeichnissen. Alle anderen Dateien (auch in anderen Verzeichnissen) werden gemäß der global gültigen Einstellung gespeichert.

Falls Dateien ohne Dateiendung eingeschlossen werden sollen, reicht *.* unter Windows leider nicht aus. Dafür muss zusätzlich das Suchmuster * ergänzt werden. Beispiel:

* text eol=lf
*.* text eol=lf

Ähnliche Artikel:

Schreibe einen Kommentar

Deine Email-Adresse wird nicht veröffentlicht.

5 × drei =