W polskich software house'ach pracujących na zlecenie zachodnich klientów typowy zespół miesza programistów na Windows z serwerami CI opartymi na Linuksie — to właśnie w takich zespołach źle dobrany core.autocrlf najczęściej zamienia jednolinijkową poprawkę w code review na diff obejmujący cały plik.
Skąd wzięła się rozbieżność
Unix i macOS używają jednego znaku — LF (line feed, \n). Windows odziedziczył po starych dalekopisach parę znaków — CRLF (carriage return + line feed, \r\n): jeden znak zwraca karetkę na początek wiersza, drugi przesuwa o wiersz w dół — dosłowna imitacja maszyny do pisania.
Dlaczego to wciąż ma znaczenie
- Git. Jeśli plik z CRLF trafi do repozytorium, gdzie inne pliki mają LF, git może pokazać „cały plik zmieniony", chociaż zmienił się tylko jeden wiersz — bo technicznie zmieniły się końce wszystkich wierszy.
- Skrypty z shebang. Skrypt dla powłoki Unix z końcami CRLF może się nie uruchomić na serwerze produkcyjnym, bo interpreter widzi zbędny znak
\rw pierwszym wierszu. - Porównywanie ciągów w kodzie. Wiersz odczytany z pliku CRLF może się nie zgadzać przy porównaniu z oczekiwanym ciągiem LF, nawet jeśli widoczny tekst wygląda tak samo.
Jak się to rozwiązuje
Git ma ustawienie (core.autocrlf), które automatycznie konwertuje końce wierszy przy checkout/commit, ale poleganie na lokalnej konfiguracji każdego programisty jest zawodne. Pewniejszym rozwiązaniem jest narzucenie stylu w pliku .gitattributes wersjonowanym razem z repozytorium — wtedy reguła obowiązuje wszystkich, niezależnie od edytora czy systemu operacyjnego.
Do czego potrzebna jest ręczna konwersja
- Naprawienie pliku, który trafił do repozytorium z niewłaściwym stylem końców wierszy.
- Przygotowanie skryptu dla serwera linuksowego, który był edytowany w edytorze Windows.
- Zdiagnozowanie, dlaczego porównanie tekstowe dwóch pozornie identycznych plików pokazuje różnicę.
Mieszane końce linii w jednym pliku
Plik edytowany w kilku edytorach lub na różnych systemach operacyjnych może zawierać jednocześnie i CRLF, i LF — część linii w jednym stylu, część w drugim. To najbardziej kapryśny przypadek: konwersja „do LF" na pierwszy rzut oka niczego nie zmienia w liniach, które już miały LF, ale ważne jest, by zastosować konwersję do całego pliku, a nie tylko do widocznie „podejrzanych" linii, inaczej problem pozostanie ukryty.