如何修复无法打包的Git存储库?

时间:2018-01-19 22:27:33

标签: git garbage-collection

我有一个git存储库,它有几个工作树目录。出现在过去几个月的某个时候,出现了问题,可能是因为我的计算机挂了几次而且我不得不重新启动。 :(

无论如何,每当我现在尝试运行git gc时(或者更常见的是gc在我fetch时在后台运行),我会得到以下错误输出:

warning: reflog of 'HEAD' references pruned commits
warning: reflog of 'HEAD' references pruned commits
warning: reflog of 'HEAD' references pruned commits
warning: reflog of 'HEAD' references pruned commits
warning: reflog of 'HEAD' references pruned commits
warning: reflog of 'HEAD' references pruned commits
warning: reflog of 'HEAD' references pruned commits
warning: reflog of 'HEAD' references pruned commits
warning: reflog of 'HEAD' references pruned commits
warning: reflog of 'HEAD' references pruned commits
Counting objects: 1255885, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (220739/220739), done.
fatal: unable to read 12e33ebd327a094eaaf844722760cd303fe5bcc5
error: failed to run repack

我已经检查过,.git目录中没有包含该SHA的对象。 (是的,我知道要查看.git/objects/12

我试图找到几种方式可能引用SHA的位置。首先,我在我的.git目录上为完整的SHA和(以防万一)除了前2位数之外的所有进行了递归grep。除了日志条目(在各种工作树目录中)之外什么也没找到,报告与上面相同的“致命”错误。

在进行了大量阅读(包括各种SO答案和网络上的文章,特别是this one)后,我还grepgit verify-pack -v输出了有问题的SHA和在那里也找不到任何东西。

我假设,从多个warning行,我有一个reflog或某些引用该ID,但我无法在任何地方找到这样的引用。< / p>

复杂性:我知道标准的“补救措施”之一就是“从原点重新克隆回购并重新开始”。我宁愿不这样做有几个原因:我真的不想重建我所有的工作树,而且;我有一些我无法推送的提交和分支)(因为它们不属于远程仓库)但对我有用,我不想失去它们。

所以,如果可能的话,我想找到一种方法来修复这个问题。此外,它将是个人满意(并且我将在过程中学到很多关于Git的知识 - 我已经有了!)以便能够解决它。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

直接的,最基本的问题是这一个:

fatal: unable to read 12e33ebd327a094eaaf844722760cd303fe5bcc5

如果这个问题是可修复的,那么可能是通过查找具有该哈希ID的对象的副本,可能在其他一些Git存储库中。例如,如果您的存储库是从 url 克隆的,并且您有另一个克隆来自 url (或者现在只创建一个新的克隆),也许另一个克隆(或你现在创建的那个)有缺少的对象。

在这种情况下,你可以更好地塑造,因为你可以简单地从&#34;好&#34;中提取该对象。存储库并将其插入到.git/objects/12/e33ebd327a094eaaf844722760cd303fe5bcc5中,将其插入到损坏的存储库中。这可能是复制现有的松散对象,或使用git unpack-objects(或提取原始数据并构建新对象,即有多种方法可以做到这一点)。

但是,很可能缺少的对象是仅在此特定存储库中的对象。在这种情况下,您有一个更加困难的恢复过程。您可以创建一个新的克隆,它将具有您已发布(推送)的提交,然后尽可能提取从损坏的存储库中可访问的任何对象,并使用它们添加新的良好提交(在您想要的任何分支上)继续添加或重新创建)减去任何依赖于现在丢失的对象的东西。

请注意,如果丢失的对象位于损坏的包中,您可以使用-r标记恢复该包的部分或大部分内容git unpack-objects。请参阅How to unpack all objects of a git repository?the git unpack-objects documentation