Wyłącz konwersje git EOL


107

Staram się, aby git nie zmieniał żadnych zakończeń linii dla żadnej operacji. Niestety wydaje się, że tak się dzieje, niezależnie od wszystkiego. Sprowadziłem to do następującego przypadku testowego, który ma tyle różnych mechanizmów wyłączania tego zachowania, ile mogłem znaleźć.


  • Rozpocznij od dwóch komputerów (komputer z systemem Windows = A, komputer z systemem Linux = B)
  • Na obu maszynach: git config --global core.autocrlf false
  • Na obu komputerach: git config --global core.eol crlf(na wszelki wypadek)

  • Utwórz nowe repozytorium na A. Z pustego folderu:
    • git init --shared(następnie odkryj utworzony .gitkatalog)
    • Utwórz nowy plik .gitignorew repozytorium
    • Utwórz nowy plik .gitattributesw repozytorium za pomocą jednej linii:* -text
    • git add ., a następnie git commit -m "initial commit"obejść, np . to .
    • git branch master_recv
    • Dodaj piloty
  • Utwórz nowy plik document.txtw repozytorium zawierającym CRLF
  • Commit: git add -Awięcgit commit -m "<something>"
  • Zwróć uwagę, że A document.txtnadal zawiera CRLF (a usunięcie go i zresetowanie za pomocą --hardzwraca wersję nadal z CRLF)

  • SCP cały katalog na komputer B
  • Dodaj nowy plik new filezawierający CRLF
  • Commit: git add -Awięcgit commit -m "<something>"
  • Zauważ, że oba document.txtB i B new filenadal zawierają CRLF

  • Pociągnij mistrza B do A: git pull <remote> master:master_recv
  • A document.txtzmieniło się na LF. Dodany plik new filezawiera również LF.

Problem nie występuje, jeśli B to komputer z systemem Windows.


Czy core.autocrlf zawsze był fałszywy? Wygląda na to, że masz już \nzakończenia linii w repozytorium? Nie ma ustawienia do zmiany \nw repozytorium na \r\nw katalogu roboczym.
Edward Thomson,

Nie zawsze był ustawiony (na przykład kiedy repozytorium zostało utworzone pierwotnie). Jednak w repozytorium nie powinno już być żadnych zakończeń linii CR. Nie chcę też, żeby w ogóle zaszły jakiekolwiek zmiany.
imallett

Pytam, ponieważ twoja konfiguracja powinna zachować twoje zakończenia linii jako CRLF. Czy mógłbyś umieścić jakiś plik w swoim repozytorium z jego identyfikatorem obiektu tylko dla mojej (co prawda prawdopodobnie irytującej) edycji?
Edward Thomson,

@EdwardThomson, co masz na myśli? Repozytorium nie jest publiczne (ponieważ maszyna Linux nie jest). Zakładam, że potrzebujesz przykładowego pliku. Zobacz edycję.
imallett

Tak, zgadzam się, że ten plik ma zakończenia linii CRLF. Czy możesz wyjaśnić jedną rzecz: wspomniałeś, że "znaki nowej linii komputera z systemem Windows zmieniają się na CR!" Z pewnością to była literówka, czy naprawdę otrzymujesz zakończenia linii powrotu karetki w stylu Mac OS 9?
Edward Thomson,

Odpowiedzi:


78

W projekcie powinien znajdować się .gitattributesplik. W większości przypadków powinien wyglądać jak poniżej (lub ten zrzut ekranu ):

# Handle line endings automatically for files detected as text 
# and leave all files detected as binary untouched.
* text=auto

# Never modify line endings of our bash scripts
*.sh -crlf

#
# The above will handle all files NOT found below
#
# These files are text and should be normalized (Convert crlf => lf)
*.css           text
*.html          text
*.java          text
*.js            text
*.json          text
*.properties    text
*.txt           text
*.xml           text

# These files are binary and should be left untouched
# (binary is macro for -text -diff)
*.class         binary
*.jar           binary
*.gif           binary
*.jpg           binary
*.png           binary

Zmień * text=autona, * text=falseaby wyłączyć automatyczną obsługę (patrz zrzut ekranu ).

Lubię to:

wprowadź opis obrazu tutaj

Jeśli Twój projekt nie ma pliku .gitattributes, zakończenia linii są ustawiane przez konfiguracje git. Aby zmienić konfiguracje git, wykonaj następujące czynności:

Przejdź do pliku konfiguracyjnego w tym katalogu:

1) C: \ ProgramData \ Git \ config

2) Otwórz plik konfiguracyjny w Notepad ++ (lub dowolnym edytorze tekstu, który preferujesz)

3) Zmień „autocrlf =” na false.

wprowadź opis obrazu tutaj


31
Po co używać obrazów zamiast tagów kodu? Bardzo niewygodne
Clint

32
Ponieważ mogę dodać duże czerwone pole na zdjęciu, aby podkreślić różne rzeczy.
Gene

23
Użycie * text=falsenie usuwa tekstu: pozostawia tekst ustawiony na wartość ciągu false. Ma to taki sam efekt, jak pozostawienie nieokreślonego tekstu (nie konkretnie nieustawionego). Użycie * -textdaje specjalne ustawienie w trybie rozbrojenia. Usunięcie ustawienia atrybutu tekstowego na ścieżce mówi gitowi, aby nie podejmował żadnych prób konwersji końca linii podczas sprawdzania lub pobierania.
JustAMartin

Dziękuję @Gene za tę odpowiedź. To doprowadzało mnie do szału przez cały dzień, a ten rozwiązał to dla mnie!
LeopardSkinPillBoxHat

7
Przepraszam, że nie mogę podziękować za tę odpowiedź. Pół dnia kosztowało mnie odkrycie, że ktoś zastosował się do wprowadzającej w błąd rady. Jak zauważył @JustAMartin, * text=falsenie ma to wpływu. Napraw odpowiedź!
Paul B.

54

Jednym prostym rozwiązaniem jest:

  • upewnij się, że core.autocrlf ma ustawioną wartość false dla wszystkich repozytoriów:
    git config --global core.autocrlf false
  • sklonuj ponownie repozytorium i sprawdź, czy nie została wykonana konwersja EOL.
  • lub, od Git 2.16 (Q1 2018) , zachowaj aktualne repozytorium i zróbgit add --renormalize .

Jeśli konwersje są wykonywane automatycznie, oznacza to, że w repozytorium znajduje się .gitattributes core.eoldyrektywa .

Z Git 2.8+ (marzec 2016) sprawdź, czy nadal istnieje transformacja eol z:

git ls-files --eol

3
PO PROSTU autocrlfDZISIAJ NIE UŻYWAJ ! unsetted autocrlfjest równoważne false. Pozostałeś w tyle za modnymi ruchami w Git
Lazy Badger,

1
Jak wyżej, próbowałem tego (chociaż nie z flagą globalną) i nie zadziałało. wersja git to 1.8.5.2.
imallett

@IanMallett „W tym momencie wydaje się, że maszyna z Linuksem nadal ma CRLF”: będzie do czasu, gdy ponownie znormalizujesz jego zawartość lub sklonujesz ją (tak jak w systemie Windows)
VonC,

Jeśli próbujesz zrobić to tylko dla jednego repozytorium, po prostu uruchom git config core.autocrlf false- wspominając o tym, ponieważ generalnie autocrlf powinien być truedla Windows i inputdla innych, ale czasami potrzebujesz czegoś konkretnego dla dziwnych skrajnych przypadków. W moim przypadku pobrałem kilka plików i chcę rejestrować zmiany, które wprowadzam, aby pamiętać, co zrobiłem (w przeciwieństwie do śledzenia zmian w kodzie). Nie wiem, czy zakończenia linii są ważne (i chcę, aby różnice miały sens w porównaniu z "prawdziwymi" rzeczami), więc wyłączyłem autocrlf.
Kapitan Man

11

Rozgryzłem to. Wygląda na to, że program SCP konwertował zakończenia linii. Zauważyłem to, gdy próbowałem celowo utworzyć plik z zakończeniami LF, a następnie zauważyłem, że po pobraniu pojawił się jako CRLF.

Ponieważ było to dla mnie rozwiązanie, przyjmuję tę odpowiedź, ale ludzie w przyszłości powinni również odnosić się do innych odpowiedzi, aby uzyskać bardziej ogólne rozwiązanie.


1
Dobry chwyt, bardziej konkretny niż moja odpowiedź. +1
VonC,

4

Z tematu "Efekty" na stronie podręcznika gitattributes (5)

text

Ten atrybut włącza i kontroluje normalizację końca linii. Kiedy plik tekstowy jest znormalizowany, jego zakończenia wierszy są konwertowane na LF w repozytorium. Aby kontrolować, jaki styl zakończenia linii jest używany w katalogu roboczym, użyj eolatrybutu dla pojedynczego pliku i core.eol zmiennej konfiguracyjnej dla wszystkich plików tekstowych.

Set

Ustawienie atrybutu tekstowego na ścieżce włącza normalizację końca wiersza i oznacza ścieżkę jako plik tekstowy. Konwersja na końcu linii odbywa się bez zgadywania typu zawartości.

Unset Usunięcie ustawienia atrybutu tekstowego na ścieżce mówi Gitowi, aby nie podejmował żadnych prób konwersji na końcu linii podczas sprawdzania lub pobierania.

core.autocrlfw nowym (1.7.2+) Git nie używany, core.eola poprawne ustawienie | usunięcie atrybutu tekstowego uważane za bardziej niezawodny sposób


Jednak w .gitattributespliku wyraźnie wyłączyłem wszystko jako tekst, prawda? Ponadto nie widzę tego z opcją, aby uniemożliwić konwersję (chociaż crlfmoże to nie mieć żadnego efektu)?
imallett

7
Ważna rzecz, która często jest mylona - aby usunąć ustawienie texti zapobiec jakiejkolwiek konwersji, należy ustawić .gitattributes na, * -text a nie na * text=false. falsenie jest poprawną wartością textatrybutu - git nie rozpozna go i zamiast tego powróci do domyślnego ustawienia autocrlf. Ponadto po zmianie textwartości musisz wykonać kopię zapasową wszystkich plików z lokalnego repozytorium, wykonać zatwierdzenie, a następnie przywrócić pliki z poprawnymi końcami wierszy zgodnie z potrzebami i zatwierdzić je z powrotem. Wtedy twój koniec linii nie będzie już nigdy modyfikowany przez git.
JustAMartin

0

Oto jak to zrobić dla pojedynczego repozytorium.

Utwórz plik .gitattributesw katalogu głównym repozytorium z tym wierszem

* -text

Otóż ​​to. To jest symbol wieloznaczny pasujący do wszystkich plików, nakazujący gitowi usunięcie atrybutu tekstowego. Oznacza to, że git traktuje wszystkie pliki jako binarne i dlatego nie wykonuje żadnej konwersji końca linii.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.