Подтвердить что ты не робот

Git поврежден репозиторий (некорректная проверка заголовка, свободный объект поврежден)

Вчера вечером я испытал отказ от питания при написании сообщения о фиксации. Когда я загрузил машину, я не смог выполнить коммит. Я запустил git reset, добавил обратно измененные файлы и попытался снова, и получил следующее:

% git commit
error: inflate: data stream error (incorrect header check)
error: unable to unpack a94406345ac44982b00cf57b4b9660a35436637f header
fatal: a94406345ac44982b00cf57b4b9660a35436637f is not a valid object

git fsck показывает следующее:

% git fsck --full
Checking object directories: 100% (256/256), done.
error: inflate: data stream error (incorrect header check)
error: unable to unpack 4346883490a0990e68db0187241abc1642765a73 header
error: inflate: data stream error (incorrect header check)
fatal: loose object 4346883490a0990e68db0187241abc1642765a73 (stored in .git/objects/43/46883490a0990e68db0187241abc1642765a73) is corrupt

Я замечаю, что сообщения жалуются на разные объекты.

Я искал SO и Web и пробовал несколько разных вещей, но безрезультатно.

  • У меня нет последней резервной копии.
  • Клонирование репозитория в другой каталог не помогает; в новом репозитории имеются те же проблемы.
  • git stash дает то же сообщение, что и git commit. Все остальные команды git работают нормально.

Как я могу сказать, что не так и исправить?

Изменить: git log вывод как предлагается (только первые несколько строк):

% git log --oneline --decorate --all |head -n 8
253b086 (HEAD, new_tokenize) Normalized tokenizer interface slightly
0f2425a (master) Added procs to eval layer
a4d4c22 Added procedures as a type
d1e15ad (tag: v0.10) Added `if' form with tail call semantics
f94a992 (tag: v0.9) Completed environments
031116e Fixed bug where # on a line by itself caused segfault
3d8b09f Added environments, define and set!
01cc624 Put symbol table implementation into types.c

Это небольшой персональный проект; Обычно я просто работаю (мастер), но в то время я экспериментировал (new_tokenize). 253b086 был последним успешным фиксацией перед сбоем питания.

4b9b3361

Ответ 1

Похоже, что git создал файлы в .git/objects для нового коммита, но не смог их успешно записать. Я решил это, удалив их по одному и перезапустив git fsck --full, чтобы найти следующий. Я начал с того, что изначально сообщалось git fsck:

% rm -f .git/objects/43/46883490a0990e68db0187241abc1642765a73
% git fsck --full
Checking object directories: 100% (256/256), done.
error: inflate: data stream error (incorrect header check)
error: unable to unpack 86e7247af5865e857a3b61eed99986e2d9538df1 header
error: inflate: data stream error (incorrect header check)
fatal: loose object 86e7247af5865e857a3b61eed99986e2d9538df1 (stored in .git/objects/86/e7247af5865e857a3b61eed99986e2d9538df1) is corrupt
% rm -f .git/objects/86/e7247af5865e857a3b61eed99986e2d9538df1
% git fsck --full
Checking object directories: 100% (256/256), done.
error: inflate: data stream error (incorrect header check)
error: unable to unpack a94406345ac44982b00cf57b4b9660a35436637f header
error: inflate: data stream error (incorrect header check)
fatal: loose object a94406345ac44982b00cf57b4b9660a35436637f (stored in .git/objects/a9/4406345ac44982b00cf57b4b9660a35436637f) is corrupt

И так далее. Я удалил пять объектов до того, как git fsck появился чистым, соответствующим (как я полагаю) пяти файлам в комманде, который я пытался сделать. Я предполагаю, что история файла не была повреждена вообще.

Кстати, я думал о другом методе, который, похоже, тоже работает. git clone копирует плохие объекты, но git push нет. После создания резервной копии я создал новый пустой репозиторий (-bare, потому что в противном случае вы не можете нажать на master), а затем не выполнил мои изменения и переместил обе ветки в новый репозиторий. Тогда это просто вопрос проверки и восстановление последних изменений из моих резервных копий.

По-прежнему интересно, если кто-то хочет пролить свет на механизм сбоев здесь.

Ответ 2

Простой ответ на этот вопрос для тех, кто сталкивается с этой проблемой: команда git clone - это исправление, если у вас есть удаленное репо, затем клонируйте его в локальную папку (после удаления поврежденного локального репо), если у вас нет удаленное репо, тогда попробуйте нажать коррумпированное репо на github и затем клонировать его оттуда, я думаю, что поврежденные объекты не будут нажаты, и он устранит проблему.

Ответ 3

Как описано в этом ответе, я побежал:

git reflog expire --expire-unreachable=now --all
git gc --prune=now

Который удалил все мои оборванные капли и оборванные коммиты, а также поврежденные объекты db.

Это было намного быстрее, чем отслеживать их один за другим!