如何修复不可打包的 Git 存储库?

Posted

技术标签:

【中文标题】如何修复不可打包的 Git 存储库?【英文标题】:How to fix unpackable Git repository? 【发布时间】:2018-01-19 22:27:32 【问题描述】:

我有一个 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 之后,我还 grep'd 为有问题的 SHA 找到了 git verify-pack -v 的输出,但在那里也没有发现任何东西。

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

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

所以,如果可能的话,我想找到解决这个问题的方法。此外,能够修复它会让我个人感到满足(而且我会在此过程中学到很多关于 Git 的知识——我已经学会了!)。

有什么想法吗?

【问题讨论】:

torek 给了我一些关于如何修复我的存储库的有用指示,我将在有机会时尝试它们。但是,我仍然对一些事情感到好奇,所以如果有人想与 cmets 权衡,我想知道,如果可能的话,如何找到warnings 的来源。我还想问为什么我找不到任何引用丢失提交的东西,但我想我可能已经弄清楚了。 【参考方案1】:

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

fatal: unable to read 12e33ebd327a094eaaf844722760cd303fe5bcc5

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

在这种情况下,您的状态要好得多,因为您可以简单地从“良好”存储库中提取该对象,然后通过将其放入 .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。

【讨论】:

啊,我错过了unpack 命令。我会考虑尝试一下。 (在我原来的帖子中,我忘了提到我的磁盘空间越来越少,所以我必须先释放一些空间,然后再尝试。)谢谢!

以上是关于如何修复不可打包的 Git 存储库?的主要内容,如果未能解决你的问题,请参考以下文章

如何修复存储库的来源?

如何将 git 补丁从一个存储库应用到另一个存储库?

如何修复还原的 git 提交?

如何修复这个 Python 脚本?

git-apply 神秘地失败了,我该如何排除/修复?

如何在 git clone 期间修复“文件名太长错误”