Как решить «Ошибка: неверный индекс - Фатальный: поврежден индексный файл» при использовании Git

612

После git initэтого я добавил и зафиксировал несколько файлов, внес некоторые изменения, добавил и зафиксировал. Установите демон git (работает под Cygwin на WinXP) и клонировали репозиторий один раз. Теперь я получаю эту ошибку с клонированным хранилищем:

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

Есть ли способ исправить это, кроме получения новой копии хранилища?

Number8
источник
Это в клонированном репозитории или в оригинальном репозитории? Команда clone выдает какие-либо ошибки?
CB Bailey

Ответы:

1259

Если проблема связана с индексом в качестве промежуточной области для фиксации (то есть .git/index), вы можете просто удалить индекс (сделать резервную копию, если хотите), а затем восстановить индекс до версии в последнем коммите:

В OSX / Linux:

rm -f .git/index
git reset

В Windows:

del .git\index
git reset

(Команда resetвыше такая же как git reset --mixed HEAD)

В качестве альтернативы вы можете использовать более низкий уровень сантехники git read-tree вместо git reset.


Если проблема связана с индексом для packfile , вы можете восстановить его, используя git index-pack.

Якуб Наребски
источник
27
Я случайно сделал :w!в :Gstatus(от fugitive.vim). Этот ответ спас меня от растягивания волос.
Лоуренс Гонсалвес
5
Я знаю, что нам не нравятся сообщения «я тоже», но «я тоже». Эквивалент в Windows есть erase /s .git\index, мне erase .git\index.lockтоже нужен был .
Джереми МакГи
1
Привет, у меня была такая же проблема с поиском и заменой, но git reset говорит мне, что в .git / objects / pack / есть два файла пакета, к которым нет доступа. У тебя есть идея?
epsilones
13
не будет ли безопаснее использовать git reset --keepвместо этого? В шпаргалке Tower Git это объясняется так: Сбросьте указатель HEAD на предыдущий коммит и сохраните незафиксированные локальные изменения
Pjetr
10
Его не было, когда я писал этот ответ ... Во всяком случае, git reset --keepэто более безопасная форма git reset --hard; git reset --mixedвообще не касается workdir
Якуб Наребски
76

Возможно, вы случайно повредили файл .git / index с помощью sed в корне вашего проекта (возможно, рефакторинг?) Примерно так:

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

чтобы избежать этого в будущем, просто игнорируйте двоичные файлы с помощью вашего grep / sed:

sed -ri -e "s/$SEACHPATTERN/$REPLACEMENTTEXT/g" $(grep -Elr --binary-files=without-match "$SEARCHPATERN" "$PROJECTROOT")
варочные панели
источник
6
Если вы не против потерять изменения .git/index, вы всегда можете удалить их и создать заново git reset(без --hard!).
Якуб Наребски
1
Я сломал его с помощью команды # find ./ -type f -exec sed -i 's / Politician / Legislator / g' {} \; Выполнение того, что рекомендует этот ответ, во-первых, не сломало бы его, но принятый ответ восстановил ущерб, который я нанес. Это отличная профилактика.
Райан Мортенсен
1
@RyanMortensen Вы можете попробовать инвертировать sedчто-то вроде этого. find .git/ -type f -exec sed -i 's/Legislator/Politician/g' {} \; Это может помочь, если ваш файл .git/настолько поврежден, что git resetне сработает. Или, может быть, вы хотите восстановить существующие, .git/indexне удаляя их. Конечно, это не удастся, если в вашем исходном коде или индексе уже есть некоторые «Законодатели».
варенье
1
Спасибо, @hobs, ты избавил меня от многих проблем - я решил их, перевернув sed, заменив мой new_stringна мой old_string!
цветы_ико
1
Я изменил весь свой проект вместо папки 'src' в IntelliJ, и у меня возникла эта проблема. Это объясняет, почему у меня были такие странные ошибки!
Майкл
18

У меня была эта проблема, и я пытаюсь исправить это:

rm -f .git/index
git reset

НО это не сработало. Решение ? По какой-то причине у меня были другие папки .git в подкаталогах. Я удаляю эти .git папки (не главные) и git resetснова. Как только они были удалены, все снова заработало.

Клитон Алмейда
источник
15

Это звучит как плохой клон. Вы можете попробовать следующее, чтобы получить (возможно?) Больше информации:

git fsck --full
Гав
источник
8

Поскольку вышеприведенные решения оставили меня с постоянными проблемами, я использовал это скучное решение:

  1. клонировать новую копию репо в другом месте
  2. скопируйте новый каталог .git в (поврежденный) репозиторий, содержащий изменения, которые я хотел зафиксировать

Сделал трюк. Кстати, я сделал sedв корне проекта, как и предполагал @hobs. Выучил мой урок.

eskimwier
источник
Это великолепно :)
Джереми
Это не очень хорошо, если вы были в середине слияния, создали ветви или выполнили какие-либо коммиты после клонирования или по ряду других сценариев ... Клонирование новой копии репо вряд ли является решением, и я осмелюсь сказать, это пахнет нетерпением (лучше оставить, когда в истинной щепотке). Гораздо лучше на самом деле диагностировать происходящее и восстанавливать индекс существующего репо - это обычно относительно легко сделать. Иногда вы можете просто переименовать индексный файл (или удалить его, если вы уверены, что он вам больше не понадобится) и позволить Git создать новый (используя git-reset или git-checkout) ..
Джазимов
7

Это сработало для меня. Хотя мне любопытно, почему я начал получать ошибки в первую очередь. Когда я вышел из системы вчера, это было нормально. Войдите сегодня утром, это не было.

rm .git/index

git reset
Восемьдесят
источник
Это сработало для меня, хотя и удалило все добавленные файлы из git. Я должен был запустить git add для этих файлов
Шамсул Арефин Саджиб
6

Примечание для пользователей подмодулей git - решения здесь не будут работать для вас как есть.

Допустим, у вас есть dev, например, родительский репозиторий , а ваш субмодульный репозиторий называется api.

если вы внутри, apiи вы получите ошибку, упомянутую в этом вопросе:

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

indexФайл НЕ будет внутри .gitпапки. Фактически, это .gitдаже не будет папка - это будет текстовый документ с расположением реальных данных .git для этого хранилища. Скорее всего как то так

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

Итак, вместо этого rm -f .git/indexвам нужно будет сделать это:

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

или, в более общем плане,

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

jenming
источник
4

Эта проблема может возникнуть, если .gitпод одним из подкаталогов находится каталог. Чтобы исправить это, проверьте, есть ли там другие каталоги .git, удалите их и попробуйте снова.

Ник Куйперс
источник
Несколько других ответов уже предоставили эту информацию.
Саймон Форсберг,
-1

Я сделал простой трюк. Я клонирую репо в новую папку. Скопировал папку .git из новой папки в старую папку репозитория, заменив там .git.

Астра Уварова - звезда Сатурна
источник
Очень опасно, потому что удаляет такие данные, как неопубликованные коммиты, теги и ветки, а также тайники и журналы.
Корактор
Не уверен насчет неопубликованных коммитов, так как считаю, что они хранятся в папке .git, а я скопировал папку .git. Я ничего не потерял с этим методом. Я не знаю о тайниках и рефлогах, чтобы комментировать.
Астра Уварова - звезда Сатурна
Вы правы, но, возможно, вам следует подчеркнуть, что вы сделали местный клон. Но мой комментарий все еще актуален для тайников и журналов.
Корактор
Ладно, у меня больше нет опыта в этом комментарии, однако, он сработал для меня, и некоторые пользователи могут найти его полезным. Там нет необходимости понижать его.
Астра Уварова - звезда Сатурна
-7

Это смешно, но я только что перезагрузил свою машину (mac), и проблема исчезла, как будто ее никогда не было. Я ненавижу звучать как парень поддержки ...

Герман Леус
источник
-9

Вы также можете попробовать восстановить предыдущую версию файла (если вы используете Windows OS)

Shyamsundar
источник
1
Не ставь ответ, которого не знаешь.
Альтаф Патель