Nieustawione zmiany pozostawione po resecie git - twarde


275

Po git reset --hard, git statusdaje mi pliki w Changes not staged for commit:sekcji.

Ja również próbował git reset ., git checkout -- .i git checkout-index -f -a, bezskutecznie.

Jak więc pozbyć się tych nieustawionych zmian?

Wydaje się, że dotyczy to tylko plików projektu Visual Studio. Dziwne. Zobacz tę pastę: http://pastebin.com/eFZwPn9Z . Cechą szczególną tych plików jest to, że w .gitattributes mam:

*.sln        eol=crlf
*.vcproj     eol=crlf
*.vcxproj*   eol=crlf

Ponadto autocrlfw moim globalnym ustawieniu jest false .gitconfig. Czy to może być w jakiś sposób istotne?


Czy zastosowałeś te polecenia z katalogu głównego repozytorium? Uwaga .oznacza katalog bieżący, a nie katalog główny
Alexander

1
Zrobiłem je naprawdę z repozytorium root.
Norswap

Jaka jest twoja gitwersja Albo popełniasz głupi błąd, albo masz starą wersję z błędami?
Shahbaz,

To jest git 1.7.4 msysgit. To może być pomyłka, ale polecenia wydają się dość proste i nie mogłem dostrzec błędu.
Norswap

Dla przypomnienia próbowałem użyć najnowszej wersji msysgit (1.7.11), ale problem nadal występuje.
Norswap

Odpowiedzi:


361

Miałem ten sam problem i był on związany z .gitattributesplikiem. Jednak typ pliku, który spowodował problem, nie został określony w pliku .gitattributes.

Mogłem rozwiązać problem, po prostu uruchamiając

git rm .gitattributes
git add -A
git reset --hard

7
Jest to dyrektywa * text = auto w pliku gitattributes. Automatycznie zmienia zakończenia plików, więc pliki będą automatycznie oznaczane jako „zmodyfikowane” po sprawdzeniu stanu.
Cody Django,

3
To działa, ale nie do końca rozumiem dlaczego. Czy ktoś chce wyjaśnić każde polecenie?
Edwin Stoteler,

18
@NLwino, git rm .gitattributesusuwa .gitattributes z indeksu. git add -Adodaje wszystkie (łącznie z usunięciem .gitattributes) do indeksu, co powinno wtedy polegać wyłącznie na usuwaniu .gitattributes, jeśli to naprawdę był problem. git reset --hardresetuje wszystkie niezatwierdzone zmiany, które obejmowałyby usunięcie .gitattributes. Zasadniczo ignoruje to .gitattributes (i * text=autodyrektywę) dla jednego zatwierdzenia poprzez usunięcie go, a następnie zresetowanie indeksu podczas jego usuwania, a więc odłożenie go z powrotem, ale po zresetowaniu innych plików, więc nie zostały one ponownie zmodyfikowane.
Cloudworks

4
@GameScripting, To rozwiązanie nie działa dla mnie. Nie ma takiego pliku jak .gitattributes: „fatal: pathspec” .gitattributes ”nie pasuje do żadnych plików”
Pacerier,

4
Robię tak i mówi fatal: pathspec '.gitattributes' did not match any files . Co ja robię źle?
Honey,

136

ZDECYDOWANY!!!

Rozwiązałem ten problem, wykonując następujące czynności

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

Rozwiązanie było częścią kroków opisanych na stronie git https://help.github.com/articles/dealing-with-line-endings/


5
TO DZIAŁA, gdy nic innego nie działa! Próbowaliśmy wszystkiego w tym i wielu innych wątkach - jest to duży zespół programistów, więc doprowadzenie wszystkich do tego samego crlf było koszmarem, ale to rozwiązuje problem.
tkersh

Interesujące ... Użyłem „git rm --chached <jeden_specyficzny_plik>, zamiast usuwania wszystkiego.” Git status ”zgłosił ten plik jako usunięty i nieśledzony. Następnie„ git reset --hard ”naprawiłem ten plik i wszystkie inne pliki, które były zgłaszane jako „Zmiany nie zostały wprowadzone”. (Przed użyciem git rm, ciężko próbowałem zresetować, aby bezskutecznie). Uwielbiam takie tajemnicze systemy kontroli źródła.
dołączam

Wiesz, usuwa całą pamięć podręczną. W dużych projektach może to zmarnować dużo czasu.
Ohar,

To jest brutalne. Mogłeś zrobić to samo, usuwając katalog repo i ponownie klonując.
ingyhere

4
Weź pod uwagę, że korzystasz z systemu Windows i nie rozróżnia wielkości liter. Jeśli pracujesz również z programistami używającymi systemów plików z rozróżnianiem wielkości liter, takich jak Mac lub Linux, mogą oni w różnych przypadkach zatwierdzać tagi, gałęzie, a nawet pliki. W takiej sytuacji indeks wyświetli istniejące pliki, które są zastępowane przez system operacyjny podczas pobierania. Jedynym sposobem, aby to naprawić, byłoby ustanowienie zasad nazewnictwa na serwerze Git (przechwytuje) lub wykrywanie błędów z góry.
ingyhere

97

Git nie resetuje plików, które nie znajdują się w repozytorium. Więc możesz:

$ git add .
$ git reset --hard

Spowoduje to stopniowe wprowadzanie zmian, które spowodują, że Git będzie wiedział o tych plikach, a następnie je zresetuje.

Jeśli to nie zadziała, możesz spróbować ukryć i upuścić swoje zmiany:

$ git stash
$ git stash drop

4
Pliki były już śledzone. Próbowałem mimo to i to też nie działa. Coś musi być nie tak z moim repozytorium, ale nie mam pojęcia, co. Jeśli chodzi o skrytkę git, zobacz moją odpowiedź dla Shahbaza.
Norswap

Co się dzieje, gdy robisz status git?
YuriAlbuquerque

1
Myślałem o rozwiązaniu. Wykonaj zatwierdzenie i interaktywną bazę, aby usunąć to zatwierdzenie.
YuriAlbuquerque

Próbowałem tego w pewnym momencie i zadziałało, chociaż później spróbowałem jeszcze raz i wymyśliłem zaskakujący wynik opisany w edycji mojej odpowiedzi.
Norswap

@YuriAlbuquerque, Git nie do końca rozumie POLA . Czy nie chodzi o git reset --hardresetowanie zarówno obszaru pomostowego, jak i katalogu roboczego, aby dopasować ”? Jeśli plik nie jest przemieszczany, oczywiście chcielibyśmy go usunąć, gdy to zrobimy reset --hard.
Pacerier,

71

Jeśli korzystasz z Git dla Windows, prawdopodobnie jest to twój problem

Miałem ten sam problem i schowek, twardy reset, czyszczenie, a nawet wszystkie z nich nadal pozostawiają zmiany. Problemem okazał się tryb plików x, który nie został poprawnie ustawiony przez git. Jest to „znany problem” z git dla systemu Windows. Lokalne zmiany pokazują się w statusie gitk i git jako stary tryb 100755 nowy tryb 100644, bez żadnych faktycznych różnic plików.

Rozwiązaniem jest zignorowanie trybu pliku:

git config core.filemode false

Więcej informacji tutaj


2
Działa to wtedy, gdy nawet rm -rf *; git checkout HEAD .nie. Uff!
forumulator

Pracowałem dla mnie, podczas gdy upuszczanie skrytki / twardy reset / rm. Atrybuty nie powiodły się.
kakyo


pracował dla mnie - próbowałem wszystkiego innego i tak, stary problem vs nowy tryb był problemem (zauważyłem, że mam inny numer, ale pliki są takie same)
Taehoon A Kim

Życie i oszczędność czasu.
Yogesh Patil

31

Okej, trochę rozwiązałem problem.

Wyglądało na to, że .gitattributesplik zawierający:

*.sln        eol=crlf
*.vcproj     eol=crlf
*.vcxproj*   eol=crlf

sprawiło, że pliki projektu wyglądały na nieustawione. Nie mam pojęcia, dlaczego tak jest, i naprawdę mam nadzieję, że ktoś wtajemniczony w sposoby git da nam miłe wytłumaczenie.

Mój dylemat było usunąć te pliki i dodać autocrlf = falsepod [core]w .git/config.

Nie oznacza to dokładnie tego samego, co poprzednia konfiguracja, ponieważ wymaga każdego programisty autocrlf = false. Chciałbym znaleźć lepszy sposób.

EDYTOWAĆ:

Skomentowałem linie obciążające, nie skomentowałem ich i zadziałało. Co do ... ja nawet ...!


1
Właśnie wystąpił ten sam dokładny problem i było to jedyne działające rozwiązanie. W moim przypadku przeniosłem się z gałęzi funkcji do mojego wzorca i wyciągnąłem kilka nowych zmian z poprzedniej wersji i zaczęło się to dziać w przypadku dwóch zmodyfikowanych plików. Wygląda na to, że pliki mogły zostać zmienione z zakończeń linii Unix na Windows, co może mieć z tym coś wspólnego. Nie jestem jednak pewien, jak i dlaczego.
Steven Surowiec

+1 Ten sam problem w Windows Git. Już miałem autocrlf = false. Połączyłem zmiany z nadrzędnego repozytorium svn repo ( git svn fetch/ git merge git-svn) i otrzymałem 1 plik oznaczony jako zmodyfikowany. Dziwne jest to, że miałem ten problem wcześniej i wszystko, co musiałem zrobić, to sprawdzić inną gałąź (z -fflagą), a następnie wrócić z powrotem. Zrobiłem to i zadziałało, ale kiedy przełączyłem się na gałąź funkcji, „zmiana” powróciła! Twoja edycja na dole odpowiedzi była rozwiązaniem. W moim przypadku skomentowałem / odkomentowałem jedną linię na górze mojego pliku .gitattributes:* text=auto !eol
Aaron Blenkush,

1
Ta EDYCJA również zadziałała dla mnie: skomentuj linie w .gitattributes, uruchom git status, odkomentuj linie w .gitattributes, uruchom git statusponownie
Ignitor

Wynika to z faktu, że git resetuje te pliki, a następnie ponownie stosuje zakończenia linii określone w dalszej części .gitattributes. git diffPrawdopodobnie przedstawia słynną ścianę czerwony / zielony ścianę , która jest typowa dla różnic kończący linię.
Dagrooms,

21

Możliwa przyczyna # 1 - Normalizacja zakończenia linii

Jedną z sytuacji, w której może się to zdarzyć, jest to, że dany plik został sprawdzony w repozytorium bez prawidłowej konfiguracji zakończeń linii (1), w wyniku czego plik w repozytorium zawiera niepoprawne zakończenia linii lub mieszane zakończenia linii. Aby potwierdzić, sprawdź, czy git diffpokazuje tylko zmiany na końcach linii (mogą one być domyślnie niewidoczne, spróbuj git diff | cat -vzobaczyć znaki powrotu karetki jako literalne ^Mznaki).

Następnie ktoś prawdopodobnie dodał a .gitattributeslub zmodyfikował to core.autocrlfustawienie, aby znormalizować zakończenia linii (2). W oparciu o .gitattributeskonfigurację globalną Git zastosował lokalne zmiany do kopii roboczej, które stosują żądaną normalizację zakończenia linii. Niestety z jakiegoś powodu git reset --hardnie cofa tych zmian normalizacji linii.

Rozwiązanie

Obejścia, w których resetowane są zakończenia linii lokalnej, nie rozwiążą problemu. Za każdym razem, gdy git „widzi” plik, spróbuje ponownie zastosować normalizację, co powoduje ten sam problem.

Najlepszą opcją jest zezwolenie gitowi na zastosowanie normalizacji, jakiej chce, poprzez znormalizowanie wszystkich zakończeń linii w repozytorium w celu dopasowania ich .gitattributesi zatwierdzenie tych zmian - zobacz Próbowanie naprawienia zakończeń linii za pomocą gałęzi filtru git, ale bez powodzenia .

Jeśli naprawdę chcesz ręcznie przywrócić zmiany w pliku, wydaje się, że najłatwiejszym rozwiązaniem jest usunięcie zmodyfikowanych plików, a następnie polecenie gitowi przywrócenia ich, chociaż zauważam, że to rozwiązanie nie działa konsekwentnie w 100% czas ( OSTRZEŻENIE: NIE uruchamiaj tego, jeśli zmodyfikowane pliki mają zmiany inne niż zakończenia linii !!):

    git status --porcelain | grep "^ M" | cut -c4- | xargs rm
    git checkout -- .

Zauważ, że jeśli w pewnym momencie nie znormalizujesz zakończeń linii w repozytorium, nadal będziesz napotykać ten problem.

Możliwa przyczyna # 2 - Rozróżnianie wielkości liter

Drugą możliwą przyczyną jest brak rozróżniania wielkości liter w systemie Windows lub Mac OS / X. Załóżmy na przykład, że w repozytorium istnieje ścieżka taka jak poniżej:

/foo/bar

Teraz ktoś w systemie Linux wprowadza pliki /foo/Bar(prawdopodobnie z powodu narzędzia do kompilacji lub czegoś, co utworzyło ten katalog) i pcha. W systemie Linux są to teraz dwa osobne katalogi:

/foo/bar/fileA
/foo/Bar/fileA

Zaznaczenie tego repo zewnątrz na Windows lub Mac może spowodować zmodyfikowanej fileA, która nie może być zresetowany, ponieważ na każdym resecie, Git na kontroli systemu Windows na zewnątrz /foo/bar/fileA, a następnie, ponieważ system Windows nie uwzględnia wielkości liter, nadpisuje zawartość fileAz /foo/Bar/fileA, powodując w nich jest „zmodyfikowany”.

Innym przypadkiem mogą być pojedyncze pliki, które istnieją w repozytorium, które po wyewidencjonowaniu w systemie plików bez rozróżniania wielkości liter nakładałyby się na siebie. Na przykład:

/foo/bar/fileA
/foo/bar/filea

Mogą występować inne podobne sytuacje, które mogą powodować takie problemy.

git w systemach plików bez rozróżniania wielkości liter powinien naprawdę wykryć tę sytuację i pokazać użyteczny komunikat ostrzegawczy, ale obecnie tego nie robi (może się to zmienić w przyszłości - zobacz tę dyskusję i powiązane proponowane łaty na liście mailowej git.git).

Rozwiązanie

Rozwiązaniem jest wyrównanie wielkości plików w indeksie git i wielkości liter w systemie plików Windows. Można to zrobić w systemie Linux, który pokaże prawdziwy stan rzeczy, LUB w systemie Windows za pomocą bardzo użytecznego narzędzia open source Git-Unite . Git-Unite zastosuje niezbędne zmiany wielkości liter do indeksu git, które następnie można zatwierdzić w repozytorium.

(1) był to najprawdopodobniej ktoś z Windows, bez jakiejkolwiek .gitattributesdefinicji dla danego pliku, a przy użyciu domyślnego ustawienia globalne dla core.autocrlfktórych jest false(patrz (2)).

(2) http://adaptivepatchwork.com/2012/03/01/mind-the-end-of-your-line/


Cholera synu, doszedł do tego. Musiałem popełnić po pierwszej linii, ale w końcu mogłem w końcu zrealizować transakcję master. To nie było zabawne.
Tim Lieberman,

16

Jeśli inne odpowiedzi nie działają, spróbuj dodać pliki, a następnie zresetuj

$ git add -A
$ git reset --hard

W moim przypadku pomogło to, gdy git śledził kilka pustych plików.


To działa. Właśnie użyłem $ git add .zamiast$ git add -A
Bjarne Gerhardt-Pedersen

8

Inną przyczyną tego mogą być systemy plików bez rozróżniania wielkości liter . Jeśli masz wiele folderów w repozytorium na tym samym poziomie, których nazwy różnią się tylko wielkością liter, to Cię to uderzy. Przejrzyj repozytorium źródłowe, używając jego interfejsu internetowego (np. GitHub lub VSTS), aby się upewnić.

Aby uzyskać więcej informacji: https://stackoverflow.com/a/2016426/67824


Aby znaleźć nazwy takich plików, uruchomgit ls-tree -r --name-only HEAD | tr A-Z a-z | sort | uniq -d
Diomidis Spinellis


5

Żadna z tych metod nie działała dla mnie, jedynym rozwiązaniem było zniszczenie całego repozytorium i jego sklonowanie. Obejmuje to ukrywanie, resetowanie, dodawanie, a następnie resetowanie, ustawienia clrf, rozróżnianie wielkości liter itp.


Aktualizacja, okazało się, że mój zamontowany system plików nie rozróżnia wielkości liter. Po tym, jak ustaliłem, że problem można naprawić za pomocą wyżej wymienionych technik.
John Hunt

4

Uruchom polecenie czyszczenia :

# Remove all untracked files and directories. (`-f` is `force`, `-d` is `remove directories`)

git clean -fd

3
Niestety nie rozwiązuje to problemów związanych z zakończeniami linii.
Christopher Schneider,

To jest jedyna rzecz, która rozwiązuje mój problem, niezależnie od tego, jaki był mój problem. Nie miałem żadnych .gitattributesplików, a zakończenia linii nie stanowiły problemu, ponieważ korzystam z Linuksa, a wszyscy deweloperzy i nasz serwer są Linuksem.
Samuel Neff,

4

Sprawdź swoje .gitattributes.

W moim przypadku mam *.js text eol=lfw nim i opcja git core.autocrlfbyło true.

To prowadzi mnie do sytuacji, w której git automatycznie konwertuje zakończenia linii plików i uniemożliwia mi to naprawienie, a nawet git reset --hard HEADnic nie zrobił.

Naprawić je komentując *.js text eol=lfw moim .gitattributesi Odkomentowano go po niej.

Wygląda na to, że to po prostu magia.


To było dla mnie, uaktualnienie mojego projektu wprowadzonego *.bat text eol=crlfdo mojego projektu.
Leo

1

Dotknąłem również podobnego problemu .gitattributes, ale w moim przypadku dotyczył LFS GitHub. Chociaż nie jest to dokładnie scenariusz PO, myślę, że daje możliwość zilustrowania tego, co .gitattributesrobi plik i dlaczego może prowadzić do nieustawionych zmian w postaci różnic „fantomowych”.

W moim przypadku plik był już w moim repozytorium, tak jak od samego początku. W ostatnim zatwierdzeniu dodałem nowygit-lfs track regułę, używając wzorca, który był z perspektywy czasu nieco zbyt szeroki, i ostatecznie dopasowałem ten starożytny plik. Wiem, że nie chciałem zmieniać tego pliku; Wiem, że nie zmieniłem pliku, ale teraz znajdowałem się w moich zmianach niestacjonarnych i żadna ilość transakcji lub twardego resetu tego pliku nie zamierzała go naprawić. Czemu?

Rozszerzenie GitHub LFS działa przede wszystkim poprzez wykorzystanie haków, które gitzapewniają dostęp poprzez .gitattributesplik. Zasadniczo wpisy .gitattributesokreślają sposób przetwarzania pasujących plików. W przypadku PO dotyczyło to normalizacji zakończeń linii; w moim przypadku było to, czy LFS może obsługiwać przechowywanie plików. W obu przypadkach plik, który gitwidzi podczas obliczania git diff, nie pasuje do pliku widocznego podczas sprawdzania pliku. Dlatego jeśli zmienisz sposób, w jaki plik jest przetwarzany za pomocą .gitattributespasującego do niego wzorca, pojawi się on jako niestacjonarne zmiany w raporcie stanu, nawet jeśli naprawdę nie ma zmian w pliku.

Wszystko, co powiedziałem, moja „odpowiedź” na pytanie brzmi: jeśli zmiana .gitattributespliku jest czymś, co chciałbyś zrobić, powinieneś po prostu dodać zmiany i przejść dalej. Jeśli nie, to zmień, .gitattributesaby lepiej odzwierciedlało to, co chcesz robić.

Bibliografia

  1. Specyfikacja GitHub LFS - świetny opis sposobu, w jaki łączą się one z wywołaniami funkcji cleani, smudgeaby zastąpić plik w gitobiektach prostym plikiem tekstowym z skrótem.

  2. Dokumentacja gitattributes - Wszystkie szczegóły na temat tego, co jest dostępne, aby dostosować sposób gitprzetwarzania dokumentów.


0

Miałem ten sam problem. Tak zrobiłem, git reset --hard HEADale wciąż za każdym razem git statuswidziałem zmodyfikowane pliki.

Moje rozwiązanie było stosunkowo proste. Właśnie zamknąłem moje IDE (tutaj był Xcode) i zamknąłem wiersz poleceń (tutaj był terminal w moim Mac OS) i spróbowałem ponownie i zadziałało.

Jednak nigdy nie byłem w stanie znaleźć źródła problemu.


0

Uważam, że istnieje problem z git dla Windows, w którym git losowo zapisuje nieprawidłowe zakończenia linii przy kasie, a jedynym obejściem jest pobranie innej gałęzi i zmusienie git do ignorowania zmian. Następnie sprawdź gałąź, nad którą naprawdę chcesz pracować.

git checkout master -f
git checkout <your branch>

Pamiętaj, że spowoduje to usunięcie wszelkich zmian, które mogłeś wprowadzić celowo, więc rób to tylko wtedy, gdy masz ten problem natychmiast po kasie.

Edycja: Mogłem mieć szczęście za pierwszym razem. Okazuje się, że znów dostałem trochę po zmianie gałęzi. Okazało się, że pliki, które git zgłasza jako zmodyfikowane po zmianie gałęzi. (Najwyraźniej dlatego, że git nie konsekwentnie stosował końcówkę CRLF do plików poprawnie).

Zaktualizowałem do najnowszej wersji git dla Windows i mam nadzieję, że problem zniknął.


0

Podobny problem, chociaż jestem pewien, że tylko na powierzchni. W każdym razie może to komuś pomóc: co zrobiłem (FWIW, w SourceTree): ukryłem nieprzydzielony plik, a następnie wykonałem twardy reset.


0

Jak wskazały inne odpowiedzi, problem polega na automatycznej korekcie końca linii. Napotkałem ten problem z plikami * .svg. Użyłem pliku SVG dla ikon w moim projekcie.

Aby rozwiązać ten problem, informuję gita, że ​​pliki svg powinny być traktowane jako pliki binarne zamiast tekstu, dodając poniższy wiersz do .gitattributes

* .svg plik binarny


0

W podobnej sytuacji. W wyniku wielu lat udręki wielu programistów, którzy byli w stanie upchnąć różne kodowania końców linii (. Asp , .js, .css ... nie istota) w jednym pliku. Jakiś czas temu odmówił .gitattributes. Ustawienia repo lewej autorclf = trueisafecrlf = warn .

Ostatni problem powstał podczas synchronizacji z archiwum z różnymi końcami linii. Po skopiowaniu z archiwum, w stanie git wiele plików jest zmienianych wraz z notatką

The line will have its original line endings in your working directory. warning: LF will be replaced by CRLF in ...

Wskazówki dotyczące normalizacji działających zakończeń linii drzew w Git? pomógł

git add -u


0

Inną możliwością, z którą się spotkałem, było to, że jeden z pakietów w repozytorium skończył się odłączonym HEAD. Jeśli żadna z odpowiedzi tutaj nie pomoże i napotkasz taki komunikat o statusie git, możesz mieć ten sam problem:

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   path/to/package (new commits)

Przechodzenie do path/to/packagefolderu a git statuspowinno dać następujący wynik:

HEAD detached at 7515f05

Następujące polecenie powinno następnie rozwiązać problem, gdzie masterpowinien zostać zastąpiony przez lokalny oddział:

git checkout master

Otrzymasz wiadomość, że Twój oddział lokalny będzie miał pewną liczbę zatwierdzeń za oddziałem zdalnym. git pulli powinieneś wyjść z lasu!


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.