Jak rozwiązać problem „Błąd: zły indeks - krytyczny: plik indeksu uszkodzony” podczas korzystania z Git

611

Następnie git initdodałem i zatwierdziłem kilka plików, wprowadziłem pewne zmiany, dodałem i zatwierdziłem. Skonfiguruj demona git (działającego pod Cygwin na WinXP) i raz sklonował repozytorium. Teraz otrzymuję ten błąd ze sklonowanym repozytorium:

$ git status
error: bad index file sha1 signature
fatal: index file corrupt

Czy jest jakiś sposób, aby to naprawić, poza uzyskaniem nowej kopii repozytorium?

Liczba 8
źródło
Czy jest to w sklonowanym repozytorium, czy w oryginalnym repozytorium? Czy polecenie klonowania wygenerowało jakieś błędy?
CB Bailey,

Odpowiedzi:

1254

Jeśli problem dotyczy indeksu jako obszaru przejściowego dla zatwierdzeń (tj. .git/index), Możesz po prostu usunąć indeks (wykonać kopię zapasową, jeśli chcesz), a następnie przywrócić indeks do wersji w ostatnim zatwierdzeniu:

W systemie OSX / Linux:

rm -f .git/index
git reset

W systemie Windows:

del .git\index
git reset

(Powyższe resetpolecenie jest takie samo jak git reset --mixed HEAD)

Można alternatywnie używać niższego poziomu kanalizacji git read-tree zamiast git reset.


Jeśli problem dotyczy indeksu pliku pakietu , możesz go odzyskać za pomocą git index-pack.

Jakub Narębski
źródło
27
Przypadkowo zrobiłem :w!a :Gstatus(z fugitive.vim). Ta odpowiedź zaoszczędziła mi dużo ciągnięcia włosów.
Laurence Gonsalves
5
Wiem, że nie lubimy wiadomości „ja też” - ale „ja też”. Odpowiednikiem w systemie Windows jest to erase /s .git\index, że ja też potrzebowałem erase .git\index.lock.
Jeremy McGee
1
Cześć, miałem ten sam problem ze znajdowaniem i zamienianiem, ale git reset mówi mi, że w .git / objects / pack / są dwa pliki paczek, do których nie można uzyskać dostępu. Masz pomysł ?
epsilones
13
czy zamiast tego nie byłoby bezpieczniej używać git reset --keep? W arkuszu
ściągowym
10
Nie istniało, kiedy pisałem tę odpowiedź ... W każdym razie git reset --keepjest to bezpieczniejsza forma git reset --hard; git reset --mixedw ogóle nie dotyka workdir.
Jakub Narębski
76

Być może przypadkowo uszkodziłeś plik .git / index przy pomocy sed w katalogu głównym projektu (być może refaktoryzacji?) Za pomocą czegoś takiego:

sed -ri -e "s/$SEACHPATTERN/$REPLACEMENTTEXT/g" $(grep -Elr "$SEARCHPATERN" "$PROJECTROOT")

aby tego uniknąć w przyszłości, po prostu zignoruj ​​pliki binarne za pomocą grep / sed:

sed -ri -e "s/$SEACHPATTERN/$REPLACEMENTTEXT/g" $(grep -Elr --binary-files=without-match "$SEARCHPATERN" "$PROJECTROOT")
płyty grzewcze
źródło
6
Jeśli nie masz nic przeciwko utracie zmian .git/index, zawsze możesz je usunąć i odtworzyć za pomocą git reset(bez --hard!).
Jakub Narębski
1
Zepsułem to za pomocą # find ./ -type f -exec sed -i 's / Politician / Legislator / g' {} \; Wykonanie tego, co zaleca ta odpowiedź, nie spowodowałoby jej w pierwszej kolejności, ale zaakceptowana odpowiedź naprawiła szkody, które wyrządziłem. Jest to jednak doskonałe zapobieganie.
Ryan Mortensen
1
@RyanMortensen Możesz spróbować odwrócić sedcoś z czymś takim. find .git/ -type f -exec sed -i 's/Legislator/Politician/g' {} \; Może to pomóc, jeśli jesteś .git/tak zepsuty, że git resetto nie zadziała. A może chcesz przywrócić istniejący .git/indexbez usuwania go. Nie powiedzie się to oczywiście, jeśli w twoim oryginalnym kodzie lub indeksie było już trochę „Legislatora”.
płyty grzejne
1
Dziękuję, że zaoszczędziłeś mi wielu kłopotów - rozwiązałem to, odwracając sed, zastępując mój new_stringmoim old_string!
tsveti_iko,
1
Przeprojektowałem cały projekt zamiast folderu „src” w IntelliJ i miałem ten problem. To wyjaśnia, dlaczego miałem tak dziwne błędy!
Michael
18

Miałem ten problem i próbuję naprawić to:

rm -f .git/index
git reset

Ale to nie zadziałało. Rozwiązanie ? Z jakiegoś powodu miałem inne foldery .git w podkatalogach. Usuwam te foldery .git (nie główny) i git resetponownie. Po ich usunięciu wszystko znów działało.

Cleiton Almeida
źródło
15

To brzmi jak zły klon. Możesz spróbować wykonać następujące czynności, aby uzyskać (ewentualnie?) Dodatkowe informacje:

git fsck --full
Gav
źródło
8

Ponieważ powyższe rozwiązania pozostawiły mnie z ciągłymi problemami, zastosowałem to nudne rozwiązanie:

  1. sklonuj nową kopię repozytorium w innym miejscu
  2. skopiuj nowy katalog .git do (uszkodzonego) repozytorium zawierającego zmiany, które chciałem zatwierdzić

Wykonał lewę. Btw, zrobiłem sedw katalogu głównym projektu, jak zgadł @hobs. Nauczyłem się mojej lekcji.

eskimwier
źródło
To wspaniale :)
Jeremy Belolo
To nie jest naprawdę genialne, jeśli byłeś w trakcie fuzji, utworzyłeś gałęzie lub wydałeś jakieś zatwierdzenia od klonowania lub któregokolwiek z wielu innych scenariuszy ... Klonowanie nowej kopii repo nie jest rozwiązaniem, a ja śmiem twierdzić pachnie niecierpliwością (najlepiej pozostawić, gdy jest w prawdziwej szczypcie). O wiele lepiej jest zdiagnozować, co się dzieje i naprawić istniejący indeks repo - zwykle jest to stosunkowo łatwe. Czasami możesz po prostu zmienić nazwę pliku indeksu (lub usunąć go, jeśli jesteś pewien, że nigdy go więcej nie będziesz potrzebować) i pozwolić Gitowi utworzyć nowy (za pomocą git-reset lub git-checkout) ..
Jazimov
7

To zadziałało dla mnie. Chociaż jestem ciekawy powodu, dla którego zacząłem otrzymywać błędy. Kiedy wylogowałem się wczoraj, było dobrze. Zaloguj się dziś rano, nie było.

rm .git/index

git reset
Osiemdziesiąt
źródło
To działało dla mnie, chociaż usunęło wszystkie dodane pliki z git. Musiałem uruchomić git add dla tych plików
Shamsul Arefin Sajib
6

Uwaga dla użytkowników submodułów git - rozwiązania tutaj nie będą działać tak, jak są.

Załóżmy, że masz devna przykład repozytorium nadrzędne , a Twoje repozytorium podmenu jest wywoływane api.

jeśli jesteś w środku apii pojawia się błąd wymieniony w tym pytaniu:

error: bad index file sha1 signature fatal: index file corrupt

indexPlik nie będzie wewnątrz .gitfolderu. W rzeczywistości .gitnie będzie to nawet folder - będzie to dokument tekstowy z lokalizacją prawdziwych danych .git dla tego repozytorium. Prawdopodobnie coś takiego:

~/dev/api $ cat .git gitdir: ../.git/modules/api

Zamiast tego rm -f .git/indexmusisz to zrobić:

rm -f ../.git/modules/api/index git reset

lub bardziej ogólnie

rm -f ../.git/modules/INSERT_YOUR_REPO_NAME_HERE/index git reset

Jenny
źródło
4

Ten problem może wystąpić, gdy w .gitjednym z podkatalogów znajduje się katalog. Aby to naprawić, sprawdź, czy są tam inne katalogi .git, usuń je i spróbuj ponownie.

Nick Kuijpers
źródło
Kilka innych odpowiedzi podało już te informacje.
Simon Forsberg
-1

Zrobiłem prostą sztuczkę. Sklonowałem repozytorium do nowego folderu. Skopiowałem folder .git z nowego folderu do starego folderu repozytorium, zastępując tam .git.

Astra Uvarova - gwiazda Saturna
źródło
Jest to bardzo niebezpieczne, ponieważ spowoduje usunięcie danych, takich jak niepublikowane zatwierdzenia, znaczniki i gałęzie, a także skrytki i dziennik logowania.
Koraktor
Nie jestem pewien co do niepublikowanych zatwierdzeń, ponieważ uważam, że są one przechowywane w folderze .git, a ja skopiowałem folder .git. Nic nie straciłem tą metodą. Nie wiem o skrytkach i loguję się, aby móc komentować.
Astra Uvarova - gwiazda Saturna
Masz rację, ale może powinieneś podkreślić, że zrobiłeś lokalnego klona. Ale mój komentarz jest nadal prawdziwy dla skrytek i ponownego logowania.
Koraktor
Okej, nie mam żadnego doświadczenia z tym komentarzem, jednak zadziałało to dla mnie i niektórzy użytkownicy mogą uznać je za przydatne. Nie ma potrzeby głosowania za tym.
Astra Uvarova - gwiazda Saturna
-7

To niedorzeczne, ale właśnie uruchomiłem ponownie komputer (Mac), a problem zniknął, jakby nigdy się nie zdarzyło. Nienawidzę brzmieć jak pomocnik ...

Herman Leus
źródło
-9

Możesz także spróbować przywrócić poprzednią wersję pliku (jeśli używasz systemu operacyjnego Windows)

Shyamsundar
źródło
1
Nie udzielaj odpowiedzi, której nie znasz.
Altaf Patel