Dlaczego powinienem używać core.autocrlf = true w Git?

295

Mam repozytorium Git, do którego można uzyskać dostęp zarówno z systemu Windows, jak i OS X, i wiem, że zawiera już niektóre pliki z zakończeniami linii CRLF. O ile mi wiadomo, istnieją dwa sposoby radzenia sobie z tym:

  1. Ustaw core.autocrlfsię falsewszędzie,

  2. Postępuj zgodnie z instrukcjami tutaj (powtórzonymi na stronach pomocy GitHub), aby przekonwertować repozytorium tak, aby zawierało tylko zakończenia linii LF, a następnie ustawić core.autocrlfje truew systemie Windows i inputOS X. Problem z tym polega na tym, że jeśli mam jakieś pliki binarne w repozytorium że:

    1. nie są poprawnie oznaczone jako binarne w gitattributes, i
    2. zawiera zarówno CRLF, jak i LF,

    będą skorumpowani. Możliwe, że moje repozytorium zawiera takie pliki.

Dlaczego więc nie miałbym po prostu wyłączyć końcowej konwersji Gita? W sieci jest wiele niejasnych ostrzeżeń o core.autocrlfwyłączeniu powodującym problemy, ale bardzo niewiele konkretnych ; jedyne, co do tej pory znalazłem, to to, że kdiff3 nie może obsłużyć zakończeń CRLF (nie jest to dla mnie problemem) i że niektóre edytory tekstu mają problemy z zakończeniem linii (również dla mnie nie stanowi problemu).

Repozytorium jest wewnętrzne dla mojej firmy, więc nie muszę się martwić udostępnianiem go osobom o różnych ustawieniach autocrlf lub wymaganiach dotyczących zakończenia linii.

Czy są jakieś inne problemy z pozostawieniem zakończenia linii takim, jakiego nie jestem świadomy?

Bogaty
źródło
1
Czy stackoverflow.com/questions/2333424/… pomógłby? Mam link do konkretnych powodów pozostawienia autocrlffałszywego.
VonC
3
@VonC Dzięki, ale już mogę dyktować, że wszyscy użytkownicy w firmie ustawili <code> autocrlf </code> na false i obecnie uważają, że to najlepsza opcja. Ale chcę wiedzieć, czy istnieją jakieś powody, dla których nie powinienem tego robić, ponieważ mogę znaleźć wielu ludzi (np. GitHub), którzy twierdzą, że należy ustawić autocrlf, ale nie ma konkretnych faktów wyjaśniających dlaczego.
Rich
3
@VonC tzn. Nie szukam powodów, aby ustawić wartość autocrlffalse. Szukam powodów, aby to zrobić.
Rich
9
Dlaczego nie użyć autocrlf = input: wydaje się, że jest to idealna rozdzielczość między dwiema skrajnościami: utrzymujesz swoje repozytorium w czystości od bzdur CRLF, a lokalnie programiści Windows mogą używać wszystkiego, co chcą, bez konieczności przerywania automatycznie plików lokalnych przez magię. (Mogą chcieć LF lokalnie z różnych powodów, więc truemoim zdaniem jest to złe.) Nie widzę żadnych wad używania autocrlf = input.
iconoclast
7
@iconclast, jednym z powodów, dla których natknąłem się na to, jest to, że budujesz dystrybucje zawierające zarówno pliki wsadowe Windows, jak i skrypty powłoki Unix. Chcesz użyć poprawnego zakończenia linii w każdym przypadku, a jest to trudniejsze, jeśli Git zamiata rzeczy nawet po jawnym ustawieniu ich w ten czy inny sposób.
user1809090

Odpowiedzi:

227

Jedyne konkretne powody, aby ustawić autocrlfna trueto:

  • unikaj git statuswyświetlania wszystkich plików, modifiedponieważ następuje automatyczna konwersja EOL podczas klonowania repozytorium EOL Git opartego na Uniksie na Windowsie ( na przykład patrz problem 83 )
  • a narzędzia do kodowania w jakiś sposób zależą od natywnego stylu EOL obecnego w pliku:

Chyba widać specjalnej obróbce, która musi radzić sobie z natywnym EOL, jesteś lepiej pozostawiając autocrlfdofalse ( git config --global core.autocrlf false).

Zauważ, że ta konfiguracja byłaby lokalna (ponieważ config nie jest przekazywany z repo do repo)

Jeśli chcesz mieć tę samą konfigurację dla wszystkich użytkowników klonujących to repozytorium, sprawdź „ Jaka jest najlepsza CRLFstrategia obsługi z git? ”, Używając textatrybutu w .gitattributespliku .

Przykład:

*.vcproj    text eol=crlf
*.sh        text eol=lf

Uwaga: począwszy od gita 2.8 (marzec 2016), znaczniki scalające nie będą już wprowadzać mieszanego zakończenia linii (LF) w pliku CRLF.
Zobacz „ Spraw, aby Git używał CRLF na liniach scalających„ HEAD ”<<<<<<<

VonC
źródło
5
@VonC Dzięki! To pomaga mi czuć się pewniej, że korzystanie z niego jest bezpieczne autocrlf=false. Zainteresowanych, czy wiesz, dlaczego git nadal wykonuje konwersję eol, nawet jeśli ustawiłeś autocrlf na false?
Bogaty
14
@VonC: Nie sądzę, aby ta odpowiedź była poprawna. Użycie core.autocrlf = true w systemie Windows działa zgodnie z oczekiwaniami. Wszystkie pliki z repozytorium (które w tym scenariuszu powinny mieć zakończenia linii LF) są konwertowane na zakończenia linii CRLF przy kasie na komputer z systemem Windows. Wszystkie pliki są konwertowane z powrotem na zakończenia linii LF po zatwierdzeniu z komputera z systemem Windows. Sposobem na znalezienie się w kłopotach jest przejście do komputera z systemem Windows z niewłaściwym ustawieniem core.autocrlf (co jest zbyt łatwe do zrobienia).
Michael Maddox,
3
@Michael Więc w takim przypadku jedynym powodem, aby nie używać tego core.autocrlf=falsew moim scenariuszu, jest posiadanie jakiegoś narzędzia / edytora, który zostałby pomylony przez zakończenia linii?
Bogaty
49
Zdecydowanie skorzystałbym false, nigdy nie byłem wielkim fanem automatycznych lub magicznych rzeczy dziejących się w tle. Po prostu użyj \ni UTF-8wszędzie, a wszystko będzie dobrze. Jeśli jakiś szaleniec nie rozumie, że istnieją konwencje, reguły i zapomina użyć UTF-8lub \n, to ktoś przekształca je ręcznie i uderza go w twarz.
Tower
5
@ Pauld'Aoust Nadal wolałbym określać typ pliku wymagającego tego CRLF poprzez core.eolatrybuty w .gitattributespliku, zamiast używać tego globalnego core.autocrlfustawienia, które stosuje się bez rozróżnienia do wszystkich plików.
VonC 10.04.13
40

Jestem programistą .NET i od lat korzystam z Git i Visual Studio. Moim zdecydowanym zaleceniem jest ustawienie prawdziwych zakończeń linii. I zrób to tak wcześnie, jak to możliwe, przez cały okres istnienia swojego repozytorium.

W związku z tym NIENAWIDZĘ, że Git zmienia moje zakończenia linii. Kontrola źródła powinna tylko zapisywać i pobierać pracę, którą wykonuję, NIE powinna jej modyfikować. Zawsze. Ale tak jest.

Co stanie się, jeśli nie ustawisz każdego programisty na true, to JEDEN programista ostatecznie ustawi się na true. Spowoduje to zmianę końców linii wszystkich plików na LF w repozytorium. A gdy użytkownicy ustawią na fałsz, to sprawdzą, Visual Studio ostrzeże Cię i poprosi o ich zmianę. Będziesz miał 2 rzeczy, które dzieją się bardzo szybko. Po pierwsze, będziesz otrzymywać coraz więcej takich ostrzeżeń, im większy zespół, tym więcej dostaniesz. Drugą i najgorszą rzeczą jest to, że pokaże, że każda linia każdego zmodyfikowanego pliku została zmieniona (ponieważ zakończenia linii każdej linii zostaną zmienione przez prawdziwego faceta). W końcu nie będzie już można niezawodnie śledzić zmian w repozytorium. O DUŻO łatwiej i czystiej jest, aby wszyscy trzymali się prawdy, niż starać się, aby wszyscy byli fałszywi. Jakkolwiek okropne jest życie z faktem, że zaufana kontrola źródła robi coś, czego nie powinna. Zawsze.

JGTaylor
źródło
Moja firma jest na tyle mała, że ​​możemy z łatwością nakazać, aby fałsz był używany wszędzie, i pomyślałbym, że większe firmy mogłyby to zrobić za pomocą zasad, ale sądzę, że jest to uzasadniony powód, aby używać „prawdy”, więc aprobuję tak czy siak. Dzięki!
Rich
1
Problem z robieniem tego z polityką (wymuszonym plikiem) polega na tym, że na komputerze z systemem Windows możesz mieć lokalny, globalny i ukryty plik konfiguracyjny (ProgramData / Git / Confg). Możesz wymusić lokalny, zaznaczając go w repozytorium, ale globalne ORAZ ukryte pliki mają pierwszeństwo. Możliwe jest także, aby lokalny i globalny (lub ukryty) był inny. Jeśli tak, będą konfliktować ze sobą na SAMYM komputerze, powodując błędy zakończenia linii tam, gdzie ich nie ma. Śledzenie tego jest trudne. :(
JGTaylor
7
dokładnie to, co myślę. nie jest zadaniem kontroli źródła, aby bałaganić pliki kodu, jak chce. zakończenia linii powinny po prostu dotyczyć narzędzi do edycji, nic więcej.
Tuncay Göncüoğlu 18.08.16
6
Jeśli Twój projekt dotyczy tylko systemu Windows, nie ma problemu. Jeśli jednak Ty lub Twoi koledzy pracujecie na platformie * nix, wówczas wasza „silna rekomendacja” spowoduje problemy. Spróbuj uruchomić skrypt bash, perl lub python z shebang na końcu, \r\na zobaczysz.
phuclv
6
Sytuacja, którą opisałeś jako nie jest problemem GIT, ustaw wartość FAŁSZ tak, jak zwykle powinna być i zniknęła. Instad to problem w pracy zespołowej. Co to znaczy „ostatecznie jeden programista true”? Dlaczego miałbyś im na to pozwolić? kiedy skonfigurujesz je do uzyskiwania dostępu do repozytorium git, to tak, jakbyś nie pozwalał na zanieczyszczenie niektórych obszarów różnymi językami (aby każdy, kto nad tym pracuje, mógł je odczytać), lub tak jak trzymasz gałęzie / scalenia / rebazy / etc wzdłuż wybranego polityki, powinni uzyskać jasną regułę: ustaw poprawne crlf.
quetzalcoatl,
12

Aktualizacja 2 :

Wygląda na to, że Xcode 9 ma „funkcję” polegającą na ignorowaniu bieżących zakończeń linii i zamiast tego po prostu użyj domyślnego ustawienia zakończenia linii podczas wstawiania linii do pliku, co powoduje, że pliki mają mieszane zakończenia linii.

Jestem prawie pewien, że ten błąd nie istniał w Xcode 7; nie jestem pewien co do Xcode 8. Dobrą wiadomością jest to, że wydaje się być naprawiony w Xcode 10.

W czasie, gdy istniał, ten błąd powodował niewielką wesołość w bazie kodu, do której odwołuję się w pytaniu (które do dziś używa autocrlf=false), i doprowadził do wielu komunikatów o zatwierdzeniu „EOL”, a ostatecznie do napisania napisu „git pre-commithook” w celu sprawdzenia za / zapobieganie wprowadzaniu mieszanych zakończeń linii.

Aktualizacja :

Uwaga: Jak zauważył VonC, począwszy od Git 2,8, markery scalania będzie nie wprowadzać stylu Unix line-zakończeń do pliku Windows stylu .

Oryginał :

Jednym z drobnych problemów, które zauważyłem w tej konfiguracji, jest to, że gdy występują konflikty scalania, linie git dodaje, aby zaznaczyć, że różnice nie mają zakończeń linii systemu Windows, nawet jeśli ma to miejsce w pozostałej części pliku, i możesz skończyć z plikiem z mieszanymi zakończeniami linii, np .:

// Some code<CR><LF>
<<<<<<< Updated upstream<LF>
// Change A<CR><LF>
=======<LF>
// Change B<CR><LF>
>>>>>>> Stashed changes<LF>
// More code<CR><LF>

Nie powoduje to żadnych problemów (wyobrażam sobie, że każde narzędzie, które poradzi sobie z obydwoma rodzajami zakończeń linii, poradzi sobie również z mieszanymi zakończeniami linii - z pewnością wszystkie te, których używamy, to robi), ale należy o tym pamiętać.

Inną rzeczą, którą * odkryliśmy, jest to, że podczas git diffprzeglądania zmian w pliku z zakończeniami linii systemu Windows, dodane linie wyświetlają zwroty karetki, a zatem:

    // Not changed

+   // New line added in^M
+^M
    // Not changed
    // Not changed

* To naprawdę nie zasługuje na określenie: „problem”.

Bogaty
źródło
2
NB: Gdy program Visual Studio napotka taki plik, oferuje normalizację zakończeń linii. Picking albo LINE-zakończeń Windows lub wyboru nie znormalizować line-zakończeń działa dobrze (jak VS nadal wyświetlany poprawnie linie naruszającym przepisy zostały usunięte, gdy konflikt został rozwiązany).
Rich
2
Niestety, nazistowska kontrola wersji korporacyjnych nie zgadza się z tym, że nie jest to problemem (LF na znacznikach konfliktu scalania).
Ilia G,
1
Zgadzam się, że LF dotyczące łączenia znaczników konfliktu nie powinno stanowić problemu. Te linie i tak nie powinny być przypisane do repozytorium.
okradać
1
Uwaga: począwszy od gita 2.8 (marzec 2016 r.), Znaczniki scalania będą faktycznie miały zakończenie linii CRLF. Patrz stackoverflow.com/a/35474954/6309
VonC