Jaka jest najlepsza strategia obsługi CRLF (powrót karetki, przesunięcie wiersza) z Git?

598

Próbowałem zatwierdzić pliki z liniami kończącymi CRLF, ale nie powiodło się.

Cały dzień pracy spędziłem na komputerze z systemem Windows, próbując różnych strategii i prawie byłem zmuszony przestać używać Gita, a zamiast tego spróbować Mercurial .

Udostępnij tylko jedną najlepszą praktykę na odpowiedź.

Daniel Jomphe
źródło

Odpowiedzi:

753

Prawie cztery lata po zadaniu tego pytania w końcu znalazłem odpowiedź, która całkowicie mnie satysfakcjonuje !

Zobacz szczegóły w github: przewodnik pomocy Jak radzić sobie z zakończeniami linii .

Git pozwala ustawić właściwości zakończenia linii dla repo bezpośrednio za pomocą atrybutu text w .gitattributespliku. Ten plik jest przypisany do repozytorium i zastępuje core.autocrlfustawienie, umożliwiając zapewnienie spójnego zachowania wszystkim użytkownikom, niezależnie od ich ustawień git.

A zatem

Zaletą tego jest to, że konfiguracja na końcu linii przemieszcza się teraz z repozytorium i nie musisz się martwić, czy współpracownicy mają odpowiednie ustawienia globalne.

Oto przykład .gitattributespliku

# Auto detect text files and perform LF normalization
*        text=auto

*.cs     text diff=csharp
*.java   text diff=java
*.html   text diff=html
*.css    text
*.js     text
*.sql    text

*.csproj text merge=union
*.sln    text merge=union eol=crlf

*.docx   diff=astextplain
*.DOCX   diff=astextplain

# absolute paths are ok, as are globs
/**/postinst* text eol=lf

# paths that don't start with / are treated relative to the .gitattributes folder
relative/path/*.txt text eol=lf

Istnieje wygodny zbiór gotowych do użycia plików .gitattributes dla najpopularniejszych języków programowania. Dobrze jest zacząć.

Po utworzeniu lub dostosowaniu .gitattributesnależy wykonać ponowną normalizację zakończeń linii raz na zawsze .

Pamiętaj, że aplikacja GitHub Desktop może zasugerować i utworzyć .gitattributesplik po otwarciu repozytorium Git projektu w aplikacji. Aby spróbować, kliknij ikonę koła zębatego (w prawym górnym rogu)> Ustawienia repozytorium ...> Zakończenia linii i atrybuty. Zostaniesz poproszony o dodanie zalecanego, .gitattributesa jeśli się zgodzisz, aplikacja wykona również normalizację wszystkich plików w repozytorium.

Wreszcie artykuł Mind the End of Your Line zawiera więcej informacji i wyjaśnia, w jaki sposób Git ewoluował w omawianych sprawach. Uważam to za konieczne czytanie .

Prawdopodobnie masz w swoim zespole użytkowników, którzy używają EGit lub JGit (narzędzia takie jak Eclipse i TeamCity używają ich) do zatwierdzania swoich zmian. Nie masz szczęścia, jak wyjaśnił @gatinueta w komentarzach do tej odpowiedzi:

To ustawienie nie zadowoli Cię całkowicie, jeśli masz w zespole osoby pracujące z Egit lub JGit, ponieważ narzędzia te po prostu zignorują atrybuty .git i z przyjemnością sprawdzą pliki CRLF https://bugs.eclipse.org/bugs/show_bug.cgi? id = 342372

Jedną sztuczką może być zmuszenie ich do wprowadzenia zmian w innym kliencie, powiedzmy SourceTree . Nasz zespół wolał wtedy to narzędzie od EGit Eclipse w wielu przypadkach użycia.

Kto powiedział, że oprogramowanie jest łatwe? : - /

Daniel Jomphe
źródło
7
Chcesz udostępnić system Windows .gitattributes?
Pułkownik Panic
Jak możesz zobaczyć, co .gitattributesGitHub dla Windows sugeruje dla twojego projektu? Zainstalowałem GitHub dla Windows, uruchomiłem wersję GUI i nie mogłem znaleźć żadnej opcji związanej z .gitattributessugestiami.
JLDiaz
4
To ustawienie nie zadowoli Cię całkowicie, jeśli masz w zespole osoby pracujące z Egit, ponieważ egit po prostu zignoruje .gitattributes i szczęśliwie sprawdzi pliki CRLF bugs.eclipse.org/bugs/show_bug.cgi?id=342372
gatinueta
19
W przypadku systemu Windows zwykle jestem skłonny ustawić globalny core.autocrlf = false- wolę LF wszędzie, ale niektóre narzędzia Windows, takie jak Visual Studio, nalegają na zakończenie CRLF w niektórych plikach (a nawet mieszają je w kilku ...); nie mungowanie zakończeń linii jest najbezpieczniejszą opcją. Jeśli wiesz, co robisz, prawdopodobnie core.autocrlf = inputużyłbym wyjątków dla projektów w systemie Windows, o których wiesz, że są wrażliwe na zakończenia linii. Jak podkreślają inni, każdy porządny edytor tekstu obsługuje teraz zakończenia LF. Myślę, że core.autocrlf = trueprawdopodobnie może powodować więcej problemów, niż to zapobiega.
Adrian
1
@gatinueta Mówiąc dokładniej, jest to problem JGit. Znaczenie TeamCity, które również korzysta z JGit, od razu ignoruje .gitattributes.
sdds
122

Nie przekształcaj zakończeń linii. Interpretacja danych nie jest zadaniem VCS - wystarczy je zapisać i zaktualizować. Każdy nowoczesny edytor tekstu może odczytać oba rodzaje zakończeń linii.

John Millikin
źródło
25
Oddelegowany. Jeśli masz problemy z niespójnymi zakończeniami linii, najlepszym rozwiązaniem jest krzyczenie na osobę, która używa niewłaściwych ustawień edytora, dopóki go nie naprawi.
136
Nie zgadzać się. Natywne łącza na wszystkich platformach to wygoda.
Jonas Byström
25
Visual Studio to PITA, jeśli chodzi o coś innego niż CRLF.
Brett Ryan
32
Git ma opcję, aby nie konwertować końcówek linii, jest to autocrlf = false i chyba, że ​​robisz programowanie na różnych platformach, jak powiedzmy Mono, najlepiej pozostawić fałsz, gdy pracujesz pod Windows i ustawić na true, jeśli będziesz rozwijać open-source dla Mono.
Chris Nicola
24
Problem z zakończeniem linii polega na obliczeniu poprawnych różnic. Więc odpowiedź jest błędna i myląca.
cos
84

Prawie zawsze chcesz, autocrlf=inputchyba że naprawdę wiesz, co robisz.

Dodatkowy kontekst poniżej:

Powinno tak być, core.autocrlf=truejeśli podoba Ci się zakończenie DOS lub core.autocrlf=inputjeśli wolisz unix-newline. W obu przypadkach twoje repozytorium Git będzie miało tylko LF, co jest właściwą rzeczą. Jedyny argument przemawiał za core.autocrlf=falsetym, że automatyczna heurystyka może nieprawidłowo wykryć niektóre pliki binarne jako tekst, a następnie twój kafelek zostanie uszkodzony. Tak więc core.safecrlfwprowadzono opcję ostrzegania użytkownika o nieodwracalnej zmianie. W rzeczywistości istnieją dwie możliwości nieodwracalnych zmian - mieszane zakończenie linii w pliku tekstowym, w tej normalizacji jest pożądane, więc to ostrzeżenie można zignorować lub (bardzo mało prawdopodobne), że Git nieprawidłowo wykrył twój plik binarny jako tekst. Następnie musisz użyć atrybutów, aby powiedzieć Gitowi, że ten plik jest binarny.

Powyższy akapit został pierwotnie pobrany z wątku na gmane.org, ale od tamtej pory został usunięty.

Cory
źródło
31
Dlaczego jest to „słuszna rzecz”?
Artem Tikhomirov
35
core.autocrlf = true to okropny pomysł. Nie miałem żadnych problemów z tą opcją, a ponadto musisz pamiętać, aby ustawić ją za każdym razem, gdy klonujesz repozytorium.
Luís Oliveira
28
NIE używaj autocrlf = true, chyba że wiesz, co robisz. Jeśli rozwijasz się w DOS / Win, to autocrlf = false zachowa takie same zakończenia między zdalnymi i lokalnymi repozytoriami i jest najlepszą opcją w prawie każdej sytuacji.
Chris Nicola,
13
@Chris - Co jeśli twoi programiści mają okna i projekty wieloplatformowe, w których niektórzy programiści wieloplatformowi pracują na OSX lub Linux? Czy najlepszą opcją nie powinien być autocrlf = true?
Brett Ryan,
20
Pozytywne, z zastrzeżeniami. Akapit wprowadzający jest nieprzydatny. core.autocrlf=inputjest kanoniczną odpowiedzią. W większości przypadków użycia, core.autocrlf=truea core.autocrlf=falsesą zbyt gorliwi (... w przeciwną ale równie strasznych sposobów, oczywiście), a więc z natury destrukcyjne. „Git dla Windows” powinien być naprawdę dostarczany z „Checkout as-is, commit end-line-style end-line end” (tj. core.autocrlf=input) Jako domyślną strategią nowej linii. Nie udało się. Więc tutaj jesteśmy - w cholernym 2015 roku - wciąż bez końca debatujemy nad tym.
Cecil Curry
58

Dwie alternatywne strategie pozwalające uzyskać spójność zakończeń linii w środowiskach mieszanych (Microsoft + Linux + Mac):

A. Konfiguracja globalna dla wszystkich repozytoriów

1) Konwertuj wszystko na jeden format

find . -type f -not -path "./.git/*" -exec dos2unix {} \;
git commit -a -m 'dos2unix conversion'

2) Zestaw core.autocrlfdo inputna Linux / Unix lub truena MS Windows (repozytorium lub globalne)

git config --global core.autocrlf input

3) [Opcjonalnie] ustaw core.safecrlfna true(aby zatrzymać) lub warn(aby śpiewać :), aby dodać dodatkową ochronę, porównując, czy odwrócona transformacja nowego wiersza da ten sam plik

git config --global core.safecrlf true


B. Lub według konfiguracji repozytorium

1) Konwertuj wszystko na jeden format

find . -type f -not -path "./.git/*" -exec dos2unix {} \;
git commit -a -m 'dos2unix conversion'

2) dodaj .gitattributesplik do swojego repozytorium

echo "* text=auto" > .gitattributes
git add .gitattributes
git commit -m 'adding .gitattributes for unified line-ending'

Nie martw się o swoje pliki binarne - Git powinien być wystarczająco inteligentny.


Więcej informacji o zmiennych safecrlf / autocrlf

lukmdo
źródło
5
globalne podejście == ustaw i zapomnij dla wszystkich repozytoriów vs. per repo == nie wymaga od innych zmiany ich globalnej konfiguracji.
lukmdo,
4
dos2unixto narzędzie wiersza polecenia, które w zależności od systemu może wymagać dodatkowej instalacji
lukmdo
2
Nie są wyłączne, możesz korzystać z obu podejść jednocześnie. Zachowaj też ostrożność podczas używania dos2unix- istnieje ryzyko uszkodzenia.git/index i nie musimy stosować go do każdego pliku. Lepiej jest użyć czegoś takiego find ./ -name "*.html"i określić, do których plików chcesz go zastosować.
cregox
6
OSTRZEŻENIE: przed uruchomieniem findlinii należy pamiętać: dos2unixdostarczane z Git dla Windows ma specyficzne (idiotyczne i niebezpieczne) IMO, bez argumentów: zamiast przejścia na UNIX, przełącza format nowej linii (DOS <-> UNIX )
leonbloy,
2
I kolejne ostrzeżenie: nie DOS2UNIX folderu .git. Tylko mówię.
hakre
10

Spróbuj ustawić core.autocrlfopcję konfiguracji na true. Zobacz także core.safecrlfopcję.

Właściwie to wygląda na to, że core.safecrlfmoże być już ustawione w twoim repozytorium, ponieważ (moje wyróżnienie):

Jeśli tak nie jest w przypadku bieżącego ustawienia core.autocrlf, git odrzuci plik .

W takim przypadku możesz sprawdzić, czy edytor tekstu jest skonfigurowany do spójnego używania zakończeń linii. Prawdopodobnie wystąpią problemy, jeśli plik tekstowy zawiera mieszaninę zakończeń linii LF i CRLF.

Wreszcie, uważam, że zalecenie, aby po prostu „użyć tego, co otrzymałeś” i użyć linii zakończonych LF w systemie Windows spowoduje więcej problemów niż rozwiązuje. Git ma powyższe opcje, aby rozsądnie traktować zakończenia linii, więc warto z nich korzystać.

Greg Hewgill
źródło
1
Czy nie byłoby lepiej używać ustawień dla całego repozytorium za pomocą pliku .gitattributes? Zastanawiałem się po prostu: niewygodne jest zmuszanie każdego użytkownika do dbania o ustawienia zakończenia linii na swoim komputerze ... Czy są też inne wady?
trainoasis
10

Użycie core.autocrlf=falsezatrzymało oznaczanie wszystkich plików jako zaktualizowane, gdy tylko je sprawdziłem w projekcie Visual Studio 2010 . Pozostali dwaj członkowie zespołu programistycznego również używają systemów Windows, więc mieszane środowisko nie wchodziło w grę, ale ustawienia domyślne dostarczone z repozytorium zawsze oznaczały wszystkie pliki jako zaktualizowane natychmiast po klonowaniu.

Wydaje mi się, że najważniejsze jest ustalenie, jakie ustawienie CRLF działa w twoim środowisku. Zwłaszcza, że ​​w wielu innych repozytoriach w naszym systemie Linux ustawienie pudełek autocrlf = truedaje lepsze wyniki.

Ponad 20 lat później nadal mamy do czynienia z różnicami w końcowych liniach między systemami operacyjnymi ... smutne.

Lance Cleveland
źródło
31
@ orange80, różnica jest niefortunna, ale nie ma powodu, by nazywać ją winą systemu Windows. Być może tylko LF ma sens z minimalistycznego punktu widzenia; ale CRLF ma większy sens na podstawie tego, co oznaczają CR i LF. „Powrót karetki” oznacza powrót na początek linii; „przesunięcie wiersza” oznacza przejście prosto do następnego wiersza, a nie na początek następnego wiersza. Z semantycznego punktu widzenia system Windows jest bardziej poprawny, jeśli ma oba: cofnij się do początku (CR), a następnie o jedną linię w dół (LF).
Ryan Lundy
40
@ Kyralessa „bardziej poprawny”, wciąż udając, że komputer jest maszyną do pisania, a tak nie jest, przy okazji. Utrzymanie analogii maszyn do pisania nie ma żadnego sensu, biorąc pod uwagę, że użytkownicy końcowi nigdy nie będą mieli do czynienia z tym, a dwie postacie zamiast jednej są bezcelowe.
jpswain,
1
Późno na tę imprezę o kilka lat, ale zignorowałeś fakt, że CR i LF to narzędzia do pozycjonowania kursora. „CR” może również być „Powrót kursora” w tym momencie historii. Gdybym chciał, aby kursor powrócił na początek linii, powiedziałbym aplikacji, aby to zrobiła. W przeciwnym razie musi pozostać tam, gdzie go położyłem.
EKW
2
Ponadto, jeśli CRLF jest „bardziej poprawny”, ponieważ nowa linia pliku tekstowego tak naprawdę jest zarówno „przejściem o jeden wiersz w dół”, jak i „przejściem do początku linii”, wynikałoby z tego, że tylko CR spowoduje, że edytor tekstu zastąpi wiersz po linii. Nie znam edytorów, które tak naprawdę to obsługują, co oznacza, że ​​potrzeba wyrażenia zarówno CRLF, jak i CR jako różnych rzeczy, tak naprawdę nie istnieje.
avl_sweden
@avl_sweden To było bardzo powszechne zachowanie przed DOS-em, a ponieważ Microsoft uważa, że ​​kompatybilność jest ważna, odtąd tak jest. Był to również standardowy sposób w USA (jako pere ASA) - ISO dopuszczało zarówno CR + LF, jak i LF (więc ponownie DOS był zgodny ze standardami); w obu przypadkach od lat sześćdziesiątych. Multics (uniksowy prekursor) wspiera CR dla pogrubienia / strajku. Wiele aplikacji w dzisiejszych czasach (w tym funkcje „podziału na linie” .NET szukają jednej z trzech (samotny CR, samotny LF, CRLF) i traktują każdą z nich jako linię końcową. Jednak wiele aplikacji jest nadal mylonych przez mieszane zakończenia linii w pliku.
Luaan
7

Są to dwie opcje dla użytkowników Windows i Visual Studio, którzy współużytkują kod z użytkownikami komputerów Mac lub Linux . Aby uzyskać szczegółowe wyjaśnienie, przeczytaj instrukcję gitattributes .

* tekst = auto

W .gitattributespliku repozytorium dodaj:

*   text=auto

Spowoduje to normalizację wszystkich plików z LFzakończeniami linii w repozytorium.

W zależności od systemu operacyjnego ( core.eolustawienia) pliki w drzewie roboczym zostaną znormalizowane do LFsystemów opartych na Uniksie lub CRLFsystemów Windows.

Jest to konfiguracja używana przez repozytorium Microsoft .NET .

Przykład:

Hello\r\nWorld

Będzie znormalizowany w repozytorium zawsze jako:

Hello\nWorld

Podczas realizacji transakcji działające drzewo w systemie Windows zostanie przekonwertowane na:

Hello\r\nWorld

Przy kasie działające drzewo w Macu pozostanie jako:

Hello\nWorld

Uwaga: jeśli Twoje repozytorium zawiera już pliki, które nie są znormalizowane, git statuspokażą te pliki jako całkowicie zmodyfikowane przy następnym wprowadzeniu jakichkolwiek zmian, a innym użytkownikom może być problem z późniejszym scaleniem. Zobacz odświeżanie repozytorium po zmianie zakończenia linii, aby uzyskać więcej informacji.

core.autocrlf = true

Jeśli nie textjest określony w .gitattributespliku, Git używa core.autocrlfzmiennej konfiguracyjnej do ustalenia, czy plik powinien zostać przekonwertowany.

Dla użytkowników systemu Windows git config --global core.autocrlf truejest świetną opcją, ponieważ:

  • Pliki są znormalizowane do LFzakończeń linii tylko po dodaniu do repozytorium. Jeśli w repozytorium znajdują się pliki, które nie są znormalizowane, to ustawienie ich nie dotknie.
  • Wszystkie pliki tekstowe są konwertowane na CRLFzakończenia linii w katalogu roboczym.

Problem z tym podejściem polega na tym, że:

  • Jeśli jesteś użytkownikiem systemu Windows autocrlf = input, zobaczysz kilka plików z LFzakończeniami linii. Nie stanowi to zagrożenia dla reszty zespołu, ponieważ twoje zobowiązania nadal będą znormalizowane z LFzakończeniami linii.
  • Jeśli jesteś użytkownikiem systemu Windows core.autocrlf = false, zobaczysz kilka plików z LFzakończeniami linii i możesz wprowadzić pliki z CRLFzakończeniami linii do repozytorium.
  • Większość użytkowników komputerów Mac używa autocrlf = inputi może pobierać pliki z CRLFkońcówkami, prawdopodobnie od użytkowników systemu Windows z core.autocrlf = false.
kiewic
źródło
1
Twoje polecenie dla użytkowników systemu Windows mówi git config --global core.autocrl true. Masz na myśli git config --global core.autocrlf true.
JellicleCat
6

--- UPDATE 3 --- (nie koliduje z UPDATE 2)

Biorąc pod uwagę przypadek, w którym użytkownicy systemu Windows wolą pracować, CRLFa użytkownicy systemu Linux / Mac wolą pracować nad LFplikami tekstowymi. Udzielenie odpowiedzi z perspektywy opiekuna repozytorium :

Dla mnie najlepszą strategią (mniej problemów do rozwiązania) jest: zachowaj wszystkie pliki tekstowe z LFwewnętrznym repozytorium git, nawet jeśli pracujesz nad projektem tylko dla systemu Windows. Następnie daj klientom swobodę pracy nad stylem końca preferencji , pod warunkiem, że wybiorą core.autocrlfwartość właściwości, która będzie szanować twoją strategię (LF przy repo) podczas przemieszczania plików do zatwierdzenia.

Inscenizacja jest tym, co wiele osób myli, próbując zrozumieć, jak działają strategie nowej linii . Przed wybraniem właściwej wartości core.autocrlfwłaściwości należy koniecznie zrozumieć następujące punkty :

  • Dodanie pliku tekstowego dla commit ( wystawiając go) to jak kopiowanie pliku do innego miejsca wewnątrz .git/podkatalogu z przekonwertowane line-zakończeń (w zależności od core.autocrlfwartości na swojej konfiguracji klienta). Wszystko to odbywa się lokalnie.
  • ustawienie core.autocrlfjest jak udzielenie odpowiedzi na pytanie (dokładnie to samo pytanie na wszystkich systemach operacyjnych):
    • „Czy git-client a. Konwertuje LF-na-CRLF podczas sprawdzania (wyciągania) zmian repo ze zdalnego lub b. Konwertuje CRLF-na-LF podczas dodawania pliku do zatwierdzenia? ” I możliwe odpowiedzi (wartości) są:
    • false:nie rób nic z powyższych ”,
    • input:Nie tylko b
    • true: „ zrób aib
    • zwróć uwagę, że NIE MA „ rób tylko

na szczęście

  • Domyślne ustawienia klienta git (windows core.autocrlf: true:, linux / mac:) core.autocrlf: falsebędą zgodne ze strategią repo tylko LF .
    Znaczenie : klienci Windows domyślnie przekonwertują na CRLF podczas sprawdzania repozytorium i konwertują na LF podczas dodawania do zatwierdzenia. Klienci Linuksa domyślnie nie wykonują żadnych konwersji. Teoretycznie zachowuje to tylko twoje repozytorium.

Niestety:

  • Mogą istnieć klienci GUI, którzy nie przestrzegają core.autocrlfwartości git
  • Mogą istnieć ludzie, którzy nie używają wartości, aby szanować twoją strategię repo. Np. Używają core.autocrlf=falsei dodają plik z CRLF do zatwierdzenia.

Aby wykryć ASAP inne niż tekstowe pliki tekstowe zatwierdzone przez powyższych klientów , możesz postępować zgodnie z opisem w --- aktualizacja 2 ---: ( git grep -I --files-with-matches --perl-regexp '\r' HEAD, na kliencie skompilowanym przy użyciu: --with-libpcreflag)

I tu jest haczyk: . Jako opiekun repo przechowuję plik, git.autocrlf=inputdzięki czemu mogę naprawić wszelkie nieprawidłowo popełnione pliki, dodając je ponownie w celu zatwierdzenia. I dostarczam tekst zatwierdzenia: „Naprawianie nieprawidłowo zatwierdzonych plików”.

O ile .gitattributesjest to uzasadnione. Nie liczę na to, ponieważ jest więcej klientów interfejsu użytkownika, którzy tego nie rozumieją. Używam go tylko do udzielania wskazówek dla plików tekstowych i binarnych, a może oznaczam wyjątkowe pliki, które powinny wszędzie mieć te same zakończenia linii:

*.java          text !eol # Don't do auto-detection. Treat as text (don't set any eol rule. use client's)
*.jpg           -text     # Don't do auto-detection. Treat as binary
*.sh            text eol=lf # Don't do auto-detection. Treat as text. Checkout and add with eol=lf
*.bat           text eol=crlf # Treat as text. Checkout and add with eol=crlf

Pytanie: Ale dlaczego w ogóle interesuje nas strategia obsługi nowego wiersza?

Odpowiedź: Aby uniknąć zatwierdzenia zmiany jednej litery, wyświetlaj się jako zmiana 5000-wierszowa , tylko dlatego, że klient, który dokonał zmiany, automatycznie przekonwertował pełny plik z crlf na lf (lub odwrotnie) przed dodaniem go do zatwierdzenia. Może to być dość bolesne, gdy w grę wchodzi rozwiązanie konfliktu . Lub może w niektórych przypadkach być przyczyną nierozsądnych konfliktów.


--- AKTUALIZACJA 2 ---

Awarie klienta git będą działać w większości przypadków. Nawet jeśli masz tylko klientów Windows, tylko Linux lub oba. To są:

  • windows: core.autocrlf=true oznacza konwersję linii do CRLF przy kasie i konwersję linii do LF podczas dodawania plików.
  • linux: core.autocrlf=input oznacza, że ​​nie należy konwertować linii przy kasie (nie ma takiej potrzeby, ponieważ oczekuje się, że pliki zostaną zatwierdzone w LF) i konwertuj linie do LF (jeśli to konieczne) podczas dodawania plików. ( - update3 - : Wydaje się, że jest to falsedomyślnie, ale znowu jest w porządku)

Właściwość można ustawić w różnych zakresach. Sugerowałbym wyraźne ustawienie --globalzakresu, aby uniknąć niektórych problemów IDE opisanych na końcu.

git config core.autocrlf
git config --global core.autocrlf
git config --system core.autocrlf
git config --local core.autocrlf
git config --show-origin core.autocrlf

Również zdecydowanie odradzałbym używanie w systemie Windows git config --global core.autocrlf false (jeśli masz tylko klientów Windows) w przeciwieństwie do tego, co proponuje się w dokumentacji git . Ustawienie wartości false spowoduje zatwierdzenie plików z CRLF w repozytorium. Ale tak naprawdę nie ma powodu. Nigdy nie wiadomo, czy będziesz musiał udostępnić projekt użytkownikom Linuksa. Dodatkowo jest to jeden dodatkowy krok dla każdego klienta, który dołącza do projektu zamiast korzystać z ustawień domyślnych.

Teraz w przypadku niektórych specjalnych przypadków plików (np. *.bat *.sh), Które chcesz, aby zostały wyewidencjonowane za pomocą LF lub CRLF, możesz użyć.gitattributes

Podsumowując, dla mnie najlepszą praktyką jest:

  • Upewnij się, że każdy plik niebinarny jest zatwierdzony przez LF na git repo (zachowanie domyślne).
  • Użyj tego polecenia, aby upewnić się, że żadne pliki nie są zatwierdzone za pomocą CRLF: git grep -I --files-with-matches --perl-regexp '\r' HEAD( Uwaga: w systemach Windows klienci działają tylko przez, git-basha na klientach z systemem Linux tylko, jeśli są skompilowani przy użyciu --with-libpcrein ./configure).
  • Jeśli znajdziesz takie pliki, wykonując powyższe polecenie, popraw je. Dotyczy to (przynajmniej na Linuksie):
    • zestaw core.autocrlf=input( --- aktualizacja 3 - )
    • zmień plik
    • cofnij zmianę (plik jest nadal wyświetlany jako zmieniony)
    • popełnij to
  • Używaj tylko absolutnego minimum .gitattributes
  • Poinstruuj użytkowników, aby ustawili core.autocrlfwyżej opisane wartości domyślne.
  • Nie licz 100% na obecność .gitattributes. git-klienci IDE mogą je ignorować lub traktować inaczej.

Jak już wspomniano, niektóre atrybuty git można dodać:

# Always checkout with LF
*.sh            text eol=lf
# Always checkout with CRLF
*.bat           text eol=crlf

Myślę, że istnieją inne bezpieczne opcje .gitattributeszamiast używania automatycznego wykrywania plików binarnych:

  • -text(np. dla plików *.ziplub *.jpg: nie będzie traktowany jak tekst. W związku z tym nie będą podejmowane próby konwersji na końcu linii. Różnice mogą być możliwe w programach do konwersji)
  • text !eol(np *.java, *.html:.. Traktowana jako tekst, ale preferencji styl EOL nie jest tak ustawiony ustawienie klient jest używany)
  • -text -diff -merge(np. dla *.hugefile: Nie jest traktowany jako tekst. Brak możliwości porównania / scalenia)

--- POPRZEDNIA AKTUALIZACJA ---

Jeden bolesny przykład klienta, który nieprawidłowo zatwierdza pliki:

netbeans 8.2 (w systemie Windows), nieprawidłowo zatwierdza wszystkie pliki tekstowe z CRLF-ami, chyba że jawnie ustawisz core.autocrlfjako globalny . Jest to sprzeczne ze standardowym zachowaniem klienta git i powoduje wiele problemów później, podczas aktualizacji / scalania. To sprawia, że ​​niektóre pliki wyglądają inaczej (chociaż nie są) nawet po przywróceniu .
To samo zachowanie w netbeansie dzieje się, nawet jeśli poprawnie dodałeś .gitattributesprojekt.

Użycie następującego polecenia po zatwierdzeniu pomoże przynajmniej wcześnie wykryć, czy w repozytorium git występują problemy z zakończeniem linii: git grep -I --files-with-matches --perl-regexp '\r' HEAD

Spędziłem godziny, aby wymyślić jak najlepsze wykorzystanie .gitattributes, aby w końcu uświadomić sobie, że nie mogę na to liczyć.
Niestety, dopóki istnieją edytory oparte na JGit (które nie mogą .gitattributespoprawnie obsługiwać ), bezpiecznym rozwiązaniem jest wymuszanie LF wszędzie, nawet na poziomie edytora.

Użyj następujących anti-CRLFśrodków dezynfekujących.

Marinos An
źródło
Zgadzam się z tobą, że jest to najlepsze podejście, nikt nie powinien używać edytorów bez wsparcia LF. Ale uważaj na swoją .gitattributeslinię, ma ona niezamierzone konsekwencje w Git <2.10, patrz stackoverflow.com/a/29508751/2261442
phk
Cholera ... Mam mnóstwo odpowiedzi, które popieram git config --global core.autocrlf falsei zalecam zajmowanie się eolem .gitattributestylko w dyrektywach.
VCC
5

To tylko rozwiązanie obejścia :

W normalnych przypadkach użyj rozwiązań dostarczonych z git. Te działają świetnie w większości przypadków. Skorzystaj z LF, jeśli udostępniasz programowanie w systemach Windows i Unix, ustawiając .gitattributes .

W moim przypadku było> 10 programistów rozwijających projekt w systemie Windows. Ten projekt został zaewidencjonowany za pomocą CRLF i nie było opcji wymuszania na LF.

Niektóre ustawienia zostały zapisane wewnętrznie na moim komputerze bez żadnego wpływu na format LF; dlatego niektóre pliki zostały globalnie zmienione na LF przy każdej małej zmianie pliku.

Moje rozwiązanie:

Komputery z systemem Windows: pozwól, by wszystko było takie, jakie jest. Nie przejmuj się niczym, ponieważ jesteś domyślnym programistą Windows „samotnego wilka” i musisz sobie z tym poradzić w następujący sposób: „Nie ma innego systemu na całym świecie, prawda?”

Maszyny uniksowe

  1. Dodaj następujące wiersze do [alias]sekcji konfiguracji . To polecenie wyświetla listę wszystkich zmienionych (tj. Zmodyfikowanych / nowych) plików:

    lc = "!f() { git status --porcelain \
                 | egrep -r \"^(\?| ).\*\\(.[a-zA-Z])*\" \
                 | cut -c 4- ; }; f "
  2. Konwertuj wszystkie zmienione pliki do formatu dos:

    unix2dos $(git lc)
  3. Opcjonalnie ...

    1. Utwórz git hook dla tej akcji, aby zautomatyzować ten proces

    2. Użyj params i dołącz go i zmodyfikuj grepfunkcję, aby dopasować tylko określone nazwy plików, np .:

      ... | egrep -r "^(\?| ).*\.(txt|conf)" | ...
    3. Zachęcamy do uczynienia go jeszcze wygodniejszym za pomocą dodatkowego skrótu:

      c2dos = "!f() { unix2dos $(git lc) ; }; f "

      ... i odpal przekonwertowane rzeczy, pisząc

      git c2dos
John Rumpel
źródło