2014-10-24 16 views
20

Git pokazuje mi, że cały plik został zmieniony, kiedy nie mogę wymyślić zmian. To Cygwin git, ale zdarza się w msysGitGit pokazujący identyczne pliki jako zmienione

$ git --version 
git version 2.1.1 

$ diff <(git show HEAD:File.cs) <(cat File.cs) 
// Shows no differences 

$ diff <(git show HEAD:File.cs | xxd) <(xxd File.cs) 
// Shows no differences 

$ git diff 
// shows the entire file has changed 

$ git hash-object <(git show HEAD:File.cs) 
7b3762473342a5b040835bfef9f6b45c109ba48b 

$ git hash-object <(cat File.cs) 
7b3762473342a5b040835bfef9f6b45c109ba48b 

$ git hash-object File.cs 
7b3762473342a5b040835bfef9f6b45c109ba48b 

mam

$ git config --get core.fileMode 
false 

i

$ git config --get core.autocrlf 
true 

ja naprawdę nie mam pojęcia, co się dzieje, wszystko chce im się być tak samo, ale git chce utworzyć commit mówiąc, że cała zawartość została usunięta i odtworzona. Czy ktokolwiek, kto zna git hydraulika, ma lepsze sugestie? Wszystko, co mogę wymyślić to, że git show usuwa/normalizuje dziwne zakończenia linii.

UPDATE:

jestem całkiem pewny, jego dzieje, ponieważ proces rozwoju jest tak. Kasy z git, rsync na dev, rozwijaj, rsync z powrotem. Wierzę, że rsync ma problemy z niektórymi końcówkami linii. To dziwne, że gitary nie donosiły o końcach linii i wydaje się, że naprawdę nie rozumieją, co się do cholery dzieje. Mimo że różnice w binarnej reprezentacji plików wydają się identyczne.

UPDATE 2:

Więc to jest bardzo irytujące, i czuję, że natknęliśmy się na błąd w git.

Na przykład

$ git gc 
$ git checkout -- . 
$ git clean -fd 
$ git status 

> shows a heap of modified files 

Jestem pewien, że powinien pokazać żadnych zmian, bez względu na to, gdzie jego bieg, ale dostaję listę 20 dziwnych rzeczy :(

+0

Czy widzisz to samo z 'git config --get core.autocrlf false'? – VonC

+0

Tak samo. Nawet upewniłem się, że mogę to naprawić za pomocą 'git rm --cached. -r' i 'git reset --hard'. Następnie uruchomiłem go za pomocą narzędzi programistycznych, przejdź do "statusu git" i przekonałem się, że cały plik "zmienił się". Zgadzam się, że mój proces zmienia pliki (wyobrażam sobie zakończenia linii), ale chcę, żeby git naprawdę mi powiedział. Dezorientuje mnie to bez końca, szczególnie biorąc pod uwagę to, że wynik hash-object jest taki sam. –

+0

Jakiego systemu operacyjnego i jakiej wersji Git używasz? – VonC

Odpowiedz

17

Może to być spowodowane przez plik .gitattributes wskazując git to powinno wystarczyć EOL normalizację ale repozytorium zawierającego nieznormalizowaną zakończeń linii.

prostym rozwiązaniem jest usunięcie odpowiedniego wiersza od .gitattributes. to może być

* text=auto 

lub

*.cs text 

Szybkie przykładem tego, jak to się mogło stać idzie tak:

$ echo "Hello World" > example.txt 
$ unix2dos example.txt #Make sure it uses CRLF 
$ git add example.txt 
$ git commit -m "commit 1" 
$ #Instruct git that all .txt files should be normalized 
$ echo '*.txt text' >> .gitattributes 
$ git add .gitattributes 
$ git commit -m "commit 2" 

Teraz repozytorium jest w obcym państwie, ponieważ .gitattributes twierdzi, że plik powinien być znormalizowane przed dodaniem go do indeksu, ale aktualna zatwierdzona wersja nie jest znormalizowana.

Jednak w tym momencie, git status nie zauważyć, że ponieważ sam plik nie uległ zmianie wielkości lub mtime ponieważ została dodana do indeksu, więc indeks jest uważane za aktualne:

$ git status 
On branch master 
nothing to commit, working directory clean 

Ale wszystko, co unieważnia indeks spowoduje git rozważyć plik będzie brudny:

$ touch example.txt 
On branch master 
Changes not staged for commit: 

     modified: example.txt 

no changes added to commit (use "git add" and/or "git commit -a") 

And git reset --hard lub wszelkich innych działań, aby spróbować przywrócić plik do stanu, w jakim ma być w nie będzie napraw to. Dzieje się tak dlatego, że nie ma możliwości dodania pliku do indeksu w jego bieżącym stanie, ponieważ znajduje się on w repozytorium, ponieważ polecenie git nakazało normalizację tego pliku i że normalizacja nie może wygenerować tego obiektu w chwili jego zatwierdzenia.

Dlatego strona GITATTRIBUTES(1) człowiek zaleca wyraźnie unieważnia całą indeks przy wprowadzaniu kończący linię normalizację tak:

$ echo "* text=auto" >>.gitattributes 
$ rm .git/index  # Remove the index to force Git to 
$ git reset   # re-scan the working directory 
$ git status  # Show files that will be normalized 
$ git add -u 
$ git add .gitattributes 
$ git commit -m "Introduce end-of-line normalization" 

Przeczytaj sekcję na „end-of-line konwersji” w gitattributes człowieka strona po więcej szczegółów.

Zamiast iść z szybką korektą po prostu usunięcie tej linii z .gitattributes, możesz zamiast tego zachować zasady normalizacji końca linii i dalej i znormalizować je teraz. Oznacza to po prostu zobowiązanie się do zmian 20+, które nie znikną, ale możesz to zrobić metodycznie, postępując zgodnie z powyższymi instrukcjami dotyczącymi wprowadzania normalizacji końca linii (bez edycji .gitattributes), a następnie mając pewność, że to się więcej nie powtórzy. , ponieważ wszystkie pliki są teraz zatwierdzone ze znormalizowanymi zakończeniami, a wszelkie dodawane pliki będą również normalizowane. To głównie osobiste preferencje.

Powiązane problemy