Status Git pokazuje pliki jako zmienione, nawet jeśli zawartość jest taka sama

194

Otrzymałem kasę od git od kogoś innego i próbuję zatwierdzić niestacjonarne zmiany w lokalnym repozytorium. Jednak wiele plików (jeśli nie każdy) wydaje się zmodyfikowanych, mimo że ich zawartość jest dokładnie taka sama.

Ustawiłem już core.fileModena false, a także core.autocrlfna false, bez powodzenia.

Warto wspomnieć, że otrzymane przeze mnie repozytorium Git pochodzi od osoby używającej systemu Windows, a ja korzystam z systemu Linux.

Co mogę zrobić, aby zatwierdzić faktyczne zmiany?

EDYCJA: wyjście git config -l:

user.name=Aron Rotteveel
user.email=<removed>
color.diff=auto
color.status=auto
color.branch=auto
color.interactive=auto
color.ui=true
color.pager=true
color.branch.current=yellow reverse
color.branch.local=yellow
color.branch.remote=green
color.diff.meta=yellow bold
color.diff.frag=magenta bold
color.diff.old=red bold
color.diff.new=green bold
color.status.added=yellow
color.status.changed=green
color.status.untracked=cyan
core.pager=less -FRSX
core.whitespace=fix,-indent-with-non-tab,trailing-space,cr-at-eol
alias.co=checkout
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
core.hidedotfiles=dotGitOnly
core.autocrlf=false
remote.origin.url=<removed>
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*

Aktualizacja: dodano kilka losowych plików przykładowych. Te pliki są zwykłym tekstem, więc najłatwiej je dołączyć.

Oryginalne pliki znajdują się tutaj: https://gist.github.com/c3c5302430935155ef3d . Hexdumps zdecydowanie wskazują, że pliki są różne, ale nie mam pojęcia, co to powoduje i jak to naprawić.

Wersja HEAD:

0000000: 4854 4d4c 2e53 6166 654f 626a 6563 740d  HTML.SafeObject.
0000010: 0a54 5950 453a 2062 6f6f 6c0d 0a56 4552  .TYPE: bool..VER
0000020: 5349 4f4e 3a20 332e 312e 310d 0a44 4546  SION: 3.1.1..DEF
0000030: 4155 4c54 3a20 6661 6c73 650d 0a2d 2d44  AULT: false..--D
0000040: 4553 4352 4950 5449 4f4e 2d2d 0d0a 3c70  ESCRIPTION--..<p
0000050: 3e0d 0a20 2020 2057 6865 7468 6572 206f  >..    Whether o
0000060: 7220 6e6f 7420 746f 2070 6572 6d69 7420  r not to permit 
0000070: 6f62 6a65 6374 2074 6167 7320 696e 2064  object tags in d
0000080: 6f63 756d 656e 7473 2c20 7769 7468 2061  ocuments, with a
0000090: 206e 756d 6265 7220 6f66 2065 7874 7261   number of extra
00000a0: 0d0a 2020 2020 7365 6375 7269 7479 2066  ..    security f
00000b0: 6561 7475 7265 7320 6164 6465 6420 746f  eatures added to
00000c0: 2070 7265 7665 6e74 2073 6372 6970 7420   prevent script 
00000d0: 6578 6563 7574 696f 6e2e 2054 6869 7320  execution. This 
00000e0: 6973 2073 696d 696c 6172 2074 6f0d 0a20  is similar to.. 
00000f0: 2020 2077 6861 7420 7765 6273 6974 6573     what websites
0000100: 206c 696b 6520 4d79 5370 6163 6520 646f   like MySpace do
0000110: 2074 6f20 6f62 6a65 6374 2074 6167 732e   to object tags.
0000120: 2020 596f 7520 7368 6f75 6c64 2061 6c73    You should als
0000130: 6f20 656e 6162 6c65 0d0a 2020 2020 254f  o enable..    %O
0000140: 7574 7075 742e 466c 6173 6843 6f6d 7061  utput.FlashCompa
0000150: 7420 696e 206f 7264 6572 2074 6f20 6765  t in order to ge
0000160: 6e65 7261 7465 2049 6e74 6572 6e65 7420  nerate Internet 
0000170: 4578 706c 6f72 6572 0d0a 2020 2020 636f  Explorer..    co
0000180: 6d70 6174 6962 696c 6974 7920 636f 6465  mpatibility code
0000190: 2066 6f72 2079 6f75 7220 6f62 6a65 6374   for your object
00001a0: 2074 6167 732e 0d0a 3c2f 703e 0d0a 2d2d   tags...</p>..--
00001b0: 2320 7669 6d3a 2065 7420 7377 3d34 2073  # vim: et sw=4 s
00001c0: 7473 3d34 0d0a                           ts=4..

Skopiowana wersja:

0000000: 4854 4d4c 2e53 6166 654f 626a 6563 740a  HTML.SafeObject.
0000010: 5459 5045 3a20 626f 6f6c 0a56 4552 5349  TYPE: bool.VERSI
0000020: 4f4e 3a20 332e 312e 310a 4445 4641 554c  ON: 3.1.1.DEFAUL
0000030: 543a 2066 616c 7365 0a2d 2d44 4553 4352  T: false.--DESCR
0000040: 4950 5449 4f4e 2d2d 0a3c 703e 0a20 2020  IPTION--.<p>.   
0000050: 2057 6865 7468 6572 206f 7220 6e6f 7420   Whether or not 
0000060: 746f 2070 6572 6d69 7420 6f62 6a65 6374  to permit object
0000070: 2074 6167 7320 696e 2064 6f63 756d 656e   tags in documen
0000080: 7473 2c20 7769 7468 2061 206e 756d 6265  ts, with a numbe
0000090: 7220 6f66 2065 7874 7261 0a20 2020 2073  r of extra.    s
00000a0: 6563 7572 6974 7920 6665 6174 7572 6573  ecurity features
00000b0: 2061 6464 6564 2074 6f20 7072 6576 656e   added to preven
00000c0: 7420 7363 7269 7074 2065 7865 6375 7469  t script executi
00000d0: 6f6e 2e20 5468 6973 2069 7320 7369 6d69  on. This is simi
00000e0: 6c61 7220 746f 0a20 2020 2077 6861 7420  lar to.    what 
00000f0: 7765 6273 6974 6573 206c 696b 6520 4d79  websites like My
0000100: 5370 6163 6520 646f 2074 6f20 6f62 6a65  Space do to obje
0000110: 6374 2074 6167 732e 2020 596f 7520 7368  ct tags.  You sh
0000120: 6f75 6c64 2061 6c73 6f20 656e 6162 6c65  ould also enable
0000130: 0a20 2020 2025 4f75 7470 7574 2e46 6c61  .    %Output.Fla
0000140: 7368 436f 6d70 6174 2069 6e20 6f72 6465  shCompat in orde
0000150: 7220 746f 2067 656e 6572 6174 6520 496e  r to generate In
0000160: 7465 726e 6574 2045 7870 6c6f 7265 720a  ternet Explorer.
0000170: 2020 2020 636f 6d70 6174 6962 696c 6974      compatibilit
0000180: 7920 636f 6465 2066 6f72 2079 6f75 7220  y code for your 
0000190: 6f62 6a65 6374 2074 6167 732e 0a3c 2f70  object tags..</p
00001a0: 3e0a 2d2d 2320 7669 6d3a 2065 7420 7377  >.--# vim: et sw
00001b0: 3d34 2073 7473 3d34 0a                   =4 sts=4.
Aron Rotteveel
źródło
1
Jeśli masz core.filemoderozbrojone lub ustawione na true, czy wyjście jest inne?
Mark Longair,
Inną ważną informacją, która mogłaby pomóc, jest wynikgit --version
Mark Longair
2
@AronRotteveel: To proste: pierwszy plik ma końce linii CRLF (Windows), drugi LF (Unix)
patrz
3
git 2.8 (marzec 2016) wprowadza git ls-files --eol, aby szybko sprawdzić, czy eol jest zaangażowany. Zobacz moją odpowiedź poniżej
VonC
Osoba w systemie Windows może uruchomić git config --global core.autocrlf true, aby rozwiązać ten problem.
Inyoka

Odpowiedzi:

62

Aktualizacja: zgodnie z komentarzem do tego pytania problem został rozwiązany:

To proste: pierwszy plik ma końce linii CRLF (Windows), drugi LF (Unix). fileUtil (dostępny w git \ usr \ bin) pokaże, że ( file a bodpowie coś takiego a: ASCII text, with CRLF line terminators b: ASCII text)

Oryginalna odpowiedź poniżej:


Pokazana różnica nie pokazuje żadnej innej linii. Czy możesz opublikować .git / config (lub lepszy git config -l).

Być może niektóre z ignorowanych białych znaków są aktywowane

Powinieneś spróbować wyłączyć core.whitespace=fix,-indent-with-non-tab,trailing-space,cr-at-eol;

również

git show HEAD:myfile|md5sum
md5sum myfile

może być użyty do sprawdzenia, czy pliki są w rzeczywistości różne. Korzystanie z zewnętrznego diff również może działać

git show HEAD:myfile > /tmp/myfile.HEAD

diff -u myfile /tmp/myfile.HEAD

# or if you prefer an interactive tool like e.g.:
vim -d myfile /tmp/myfile.HEAD
sehe
źródło
Dziwne jest to, że sumy md5 dla obu plików są różne, ale nie mogę znaleźć ŻADNEJ różnicy białych znaków. (Zakładam, że tak jest, ale po prostu tego nie widzę). Każda pomoc byłaby mile widziana.
Aron Rotteveel,
Po prostu prześlij gdzieś przykład (gist.github.com byłby do tego odpowiedni). Zakładam, że jest to znak nowej linii w ostatnim wierszu, znak kolejności bajtów lub ogólnie niekanoniczne kodowanie UTF8. Zawsze możesz patrzeć na binarne pliki xxdbdiff
różnicowe
dzięki za wskazówkę. xddbył dla mnie nowy. Świetne narzędzie! Zaktualizowałem swój post za pomocą przykładu.
Aron Rotteveel
1
@AronRotteveel: To proste: pierwszy plik ma końce linii CRLF (Windows), drugi LF (Unix). Edycjafile util pokaże, że ( file a bodpowie coś podobnego a: ASCII text, with CRLF line terminators b: ASCII text)
sehe
czy nie powinny one być pokazywane jako ^ M w VIM? (Nie widzę tego). Oczywiście wierzę ci, ale naprawdę interesuje mnie to, jak to zauważyłeś :)
Aron Rotteveel
134

Rozwiązałem ten problem za pomocą następujących kroków

1) Usuń każdy plik z indeksu Gita.

git rm --cached -r .

2) Przepisz indeks Git, aby wybrać wszystkie nowe zakończenia linii.

git reset --hard

Pamiętaj, że krok 2 może usunąć lokalne zmiany. Rozwiązanie było częścią kroków opisanych na stronie git https://help.github.com/articles/dealing-with-line-endings/

Jacek Szybisz
źródło
W moim przypadku zrobiłem kilka notatek do niektórych plików, a następnie skopiowałem repozytorium bez folderu .git na nowy komputer. Kiedy zdałem sobie sprawę, że brakuje mi paczki .git, było już za późno, aby wrócić i ją odzyskać. Więc ja: 1. Sprawdziłem nową kopię całego repozytorium 2. Zastąpiłem pliki waniliowe plikami z moimi zmianami 3. Przebiegłem krok pierwszy w poście PO: git rm --cached -r .4. To zainscenizowało moje zmiany (i wszelkie inne pliki, które zostały zastąpione ), więc je wystawiłem. W tym momencie moje repo wróciło do normy.
cody
2
Znakomity. Dzięki za to.
rupi
6
Musisz zachować ostrożność, ponieważ w takim przypadku stracisz wszelkie inne zmiany.
Mohy Eldeen
Miałem ten problem po skopiowaniu i wklejeniu folderu repo z systemu Windows do Ubuntu. Nie wprowadzono żadnych lokalnych zmian, ale z jakiegoś powodu git pomyślał, że każdy plik się zmienił. To rozwiązanie rozwiązało ten problem.
Linek
88

Czy zmieniłeś tryb plików? Zrobiłem to na moim komputerze, a lokalna maszyna programistyczna otrzymała 777 dla wszystkich plików, podczas gdy repo miało 755, które pokazały każdy plik jako zmodyfikowany. Zrobiłem to git diffi pokazałem, że stary tryb i nowy tryb są różne. Jeśli to jest problem, możesz łatwo zignorować je przez git config core.filemode false
okrzyki

itsandy
źródło
2
Korzystając z systemu Windows 10 lxss (tj. Ubuntu Bash) z repozytorium w systemie plików Windows z git w Linuksie, myślałem, że to problem z zakończeniem linii. Nawet nie sądziłem, że to może być sposób, w jaki tryby plików są różne.
Matt L
To działało dla mnie, kiedy zmieniłem moje lokalne O / S z Ubuntu na Windows. Na zdrowie
Mark Bucknell,
@MattL i itsandy Zwykle rozwijam na Win 10 z Git Bash, ale dzisiaj jestem na Macu i widzę, że git uważa, że .gitignorepliki się zmieniły, gdy tak nie jest. Na tym komputerze Mac git config core.filemodeodpowiada za pomocą true. Zmieniłem to na false, ale to nie pomogło.
Ryan
43

miałem ten sam problem. po win-> lin copy mam zmodyfikowane wszystkie pliki.
Użyłem fromdos, aby naprawić zakończenia linii,
a następnie

git add -uv 

aby dodać zmiany.
dodał 3 pliki (nie wszystkie), które faktycznie zmodyfikowałem. a po tym status git pokazuje tylko 3 zmodyfikowane pliki. po zatwierdzeniu przez git wszystko jest w porządku ze statusem git

Demo_S
źródło
2
Dzięki, tego właśnie potrzebowałem. Skorzystałem z sugestii @ sehe, by porównać md5sum, aby sprawdzić, czy pliki są identyczne (w moim przypadku były). Następnie użycie flagi -u poprawnie odfiltrowało te pliki bez rzeczywistych różnic od plików ze zmianami.
STW
Dzięki, to było pomocne. Miałem ten problem po zrobieniu npm iw katalogu głównym mojego projektu. Jakoś wiele plików miało inne zakończenia linii, co powodowało ten problem.
Serwer Chałiłow
tego się spodziewałem ... zmiany, które dokonały, pozostały, a reszta cofnęła się
Deepak,
24

W moim przypadku pliki były wyświetlane jako zmodyfikowane po zmianie uprawnień do plików .

Aby git ignorował zmiany uprawnień, wykonaj następujące czynności:

# For the current repository
git config core.filemode false   

# Globally
git config --global core.filemode false
Sakis
źródło
1
Twoja odpowiedź pozwoliła mi zaoszczędzić dużo czasu. Dzięki!
Pavel_K
Po wykonaniu tej czynności zalecam przechowywanie / przenoszenie żądanych zmian, resetowanie / sprawdzanie plików, których uprawnienia zostały zmienione, a następnie ponowne włączanie core.filemode. :)
XtraSimplicity
Miałem ten problem po skopiowaniu plików z jednego laptopa na drugi. Twój naprawiony zapisał to. Dzięki!
Sam
23

Jednak wiele plików (jeśli nie każdy) wydaje się zmodyfikowanych, mimo że ich zawartość jest dokładnie taka sama.

Z git 2.8 (marzec 2016 r.) Będziesz mógł szybko sprawdzić, czy zmiany te są związane z eol.

Zobacz commit a7630bd (16 stycznia 2016 r.) Autor: Torsten Bögershausen ( tboegi) .
(Połączone przez Junio ​​C Hamano - gitster- w commit 05f1539 , 03 lutego 2016)

ls-files: dodaj diagnostykę eol

Podczas pracy w środowisku wieloplatformowym użytkownik może chcieć sprawdzić, czy pliki tekstowe są znormalizowane w repozytorium i czy .gitattributessą odpowiednio ustawione.

Umożliwiaj Gitowi wyświetlanie zakończeń linii w indeksie i drzewie roboczym oraz efektywnych atrybutów text / eol.

Koniec linii („ eolinfo”) pokazano w następujący sposób:

"-text"        binary (or with bare CR) file
"none"         text file without any EOL
"lf"           text file with LF
"crlf"         text file with CRLF
"mixed"        text file with mixed line endings.

Efektywny atrybut text / eol jest jednym z następujących:

"", "-text", "text", "text=auto", "text eol=lf", "text eol=crlf"

git ls-files --eol daje takie wyjście:

i/none   w/none   attr/text=auto      t/t5100/empty
i/-text  w/-text  attr/-text          t/test-binary-2.png
i/lf     w/lf     attr/text eol=lf    t/t5100/rfc2047-info-0007
i/lf     w/crlf   attr/text eol=crlf  doit.bat
i/mixed  w/mixed  attr/               locale/XX.po

aby pokazać, jaka konwencja eol jest używana w danych w indeksie (' i') i w drzewie roboczym (' w') oraz jaki atrybut obowiązuje dla każdej wyświetlanej ścieżki .

VonC
źródło
Chociaż pokazuje to problem, nie rozwiązuje go.
Greeso
7

Oto jak rozwiązałem problem w systemie Linux podczas klonowania projektu utworzonego w systemie Windows:

na Linuksie, aby wszystko działało poprawnie, musisz mieć to ustawienie: core.autocrlf = input

tak to ustawić: git config --global core.autocrlf input

Następnie sklonuj projekt ponownie z github.

poszukiwacz prawdy
źródło
Działa to dla mnie w scenariuszu, w którym korzystam z programu Visual Studio w systemie Windows, ale wykonuję zatwierdzenia i dodatkowe kontrole w WSL w wierszu polecenia. W wierszu poleceń każdy plik pokazał się jako zmieniony, ale w Visual Studio zmieniło się tylko kilka plików. Dodałem dane autoclrf = do mojego pliku .gitconfig i naprawiłem je natychmiast. Dziękuję Ci!
Big Data Brian
5

Git FAQ ma odpowiedzi, które mogą być istotne, chociaż nigdy nie natknąć to wcześniej:

Dlaczego git diff czasami wyświetla listę plików bez zmian?

git diff i inne operacje git są zoptymalizowane, więc nawet nie patrzy na pliki, których status (rozmiar, czas modyfikacji itp.) na dysku i w indeksie gita są różne. To sprawia, że ​​git diff jest niezwykle szybki dla małych zmian. Jeśli plik został w jakiś sposób dotknięty, git diff musi spojrzeć na zawartość i porównać go, co jest znacznie wolniejszą operacją, nawet jeśli w rzeczywistości nie ma zmian. git diff wyświetla listę plików jako przypomnienie, że nie jest ona optymalnie używana. Uruchomienie statusu git nie tylko pokaże status, ale także zaktualizuje indeks o status niezmienionego dysku plików, dzięki czemu kolejne operacje, nie tylko różnice, będą znacznie szybsze. Typowym przypadkiem, który powoduje, że wiele plików jest wyświetlanych przez diff, jest uruchamianie poleceń edycji masowej, takich jak perl -pi -e '...'.

Co ci git statuspokazuje?

Mark Longair
źródło
git statuspo prostu pokazuje ogromną listę plików w zmodyfikowanej sekcji.
Aron Rotteveel
@Aron: na podstawie tego pojęcia powiedziałbym: 85% mówi konwersja lineend
sehe
4
Łał. Przypomnienie, jak niezrozumiałe są niektóre oficjalne dokumenty git.
Mars
2

Po skopiowaniu mojego lokalnego repozytorium i kopii roboczej do innego folderu (przy okazji w systemie Windows) miałem cztery pliki, które wyświetlały się jako zmienione i wypróbowałem każdą sugestię wymienioną w innych odpowiedziach. W końcu naprawiłem to, usuwając lokalny oddział i ponownie pobierając go ze zdalnego. W moim przypadku myślę, że miało to coś wspólnego z kopiowaniem lokalnego repozytorium, a nie klonowaniem.

Nate Cook
źródło
2

Próbowałem więc prawie wszystkiego tutaj i chcę wprowadzić jeszcze jedno rozwiązanie, które rozwiązało wszystkie moje problemy. Moje problemy nie dotyczyły zakończenia linii, faktycznych uprawnień ani nic podobnego. Stało się tak, ponieważ zainstalowałem Cygwin i całą masę rzeczy z tym związanych, które bez mojej wiedzy również zainstalowały moją własną wersję git. Nigdy tego nie zauważyłem, po prostu miałem dziwne problemy z oznaczaniem użytkowników i plików jako zmienionych (z powodu zmian perms).

Okazuje się, że wymyśliłem to, ponieważ pomyślałem, że powinienem po prostu zaktualizować Git do najnowszej wersji, co zrobiłem, ale uruchomione git --versionzwróciło stary numer wersji. Po kolejnym poszukiwaniu przyczyny znalazłem katalog główny bin katalogu cygwin w mojej ścieżce środowiska, która zawierała plik wykonywalny git, działający pod starym numerem wersji. Domyśl.

Było to również trudne do znalezienia, ponieważ mam zainstalowany TortoiseGit. Moje narzędzia wiersza poleceń użyłyby wersji cygwin ze względu na awarie ścieżek, a TortoiseGit został skonfigurowany do korzystania z wersji systemu Windows, co jeszcze bardziej go dezorientuje.

Mam nadzieję, że to komuś pomoże.

dudewad
źródło
1
Dobry chwyt +1. Dlatego zawsze ustawiam swoją ŚCIEŻKĘ samodzielnie, jak w stackoverflow.com/a/44351065/6309
VonC
Często pozwalam instalatorowi ustawić PATH, ale potem sprawdzam go ręcznie, co zrobiłem tutaj. Moja poprzednia instalacja miała git 2.4.x (x86) i zainstalowałem git 2.13.x (x64). Możesz sobie wyobrazić moje zamieszanie, kiedy usunąłem odniesienie do ścieżki x86 i nadal mam 2.4 !! Wtedy zobaczyłem katalog bin cygwina i wydawało mi się, że to kolejne logiczne miejsce do poszukiwania. Zatem ustawienie FWIW, a nawet wizualne sprawdzenie ŚCIEŻKI może nie rozwiązać tego problemu, jeśli katalog bin Cygwin jest wymieniony jako pierwszy!
dudewad
1

Jedyny podejrzany wpis w twojej konfiguracji wydaje mi się być core.ignorecase. Możesz spróbować usunąć to z:

  git config --unset core.ignorecase

... i sprawdź, czy wyjście z git statuslub git diffjest inne.

Mark Longair
źródło
1

Właśnie ustawiłem filemode = false w .git / config i zadziałało to dla mnie.

filemode = false
Felipe Santa
źródło
0

Dla mnie było tak, ponieważ 2 maszyny wirtualne z systemem Linux zostały zmapowane do tego samego domowego systemu plików. Jedna maszyna wirtualna działała na git-1.7.1, a druga na git-2.14

Maszyna wirtualna z uruchomionym programem git-1.7.1 zawsze wyświetlałaby 4 pliki po zmianie (nawet myślała, że ​​zawartość i zakończenia linii są identyczne).

Po uruchomieniu „statusu git” na maszynie wirtualnej z systemem g-2.14 obie maszyny wirtualne zaczęłyby raportować repozytorium jako czyste. „status git” ma skutki uboczne. To nie jest niezmienna operacja. A git-1.7.1 nie rozumie świata w taki sam sposób, jak git-2 +.

William
źródło