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 

我注意到消息抱怨不同的对象。

我search了这个和networking,并尝试了一些不同的东西,但无济于事。

  • 我没有最近的备份副本。
  • 将存储库克隆到另一个目录并没有帮助; 新的存储库展现了完全相同的问题。
  • git stash提供与git commit相同的消息。 所有其他的git命令似乎正常工作。

我怎么知道什么是错的,并修复它?

编辑:build议(只是前几行)的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是断电前最后一次成功的提交。

看来git在.git / objects中为新的提交创build了文件,但没有成功写入它们。 我解决了它,一次删除一个,重新运行git fsck --fullfind下一个。 我从最初由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没有。 备份完成后,我创build了一个新的空存储库(–bare,因为否则你不能推送给master),然后取消我的更改并将两个分支都推送到新的存储库中。 然后这只是一个检查出来,恢复从我的备份最新的变化的问题。

如果有人关心这里的失败机制,仍然感兴趣。

简单的回答这个问题面对这个问题的任何人:git克隆命令是修复,如果有一个远程回购,然后克隆到本地文件夹(删除损坏的本地回购后),万一你没有远程回购,然后尝试把腐败的回购推到github,然后从那里克隆它,我认为,不会推动损坏的对象,它会解决问题

正如在这个答案中所述,我跑了:

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

这删除了我所有的悬挂的斑点和悬而未决的提交,以及腐败的分贝对象。

这比一个接一个的追踪要快得多!