【发布时间】:2021-03-17 16:11:43
【问题描述】:
我遇到git fsck 调用返回几个断开的链接的情况。这是因为,对于此存储库,运行了 rm 命令并删除了几个写保护文件(发生了错误)。该存储库也没有最近的备份(同样,犯了错误)。因为 Git 被使用了,所以存储库并没有完全丢失,但是一些历史已经被打乱了。直到最近重新同步到源时,这才引起注意,并且由于历史记录损坏,这失败了。
我想修复此历史记录(如果可能),以便它可以与上游源合并。我知道我将无法取回完整的历史记录,因为有些文件刚刚消失,但我想尽可能多地保留它,以确保一切正常。
我查看了 Linus 的电子邮件“如何恢复损坏的 blob 对象”(MIT hosted copy),还查看了:
How to recover Git objects damaged by hard disk failure?
Repair corrupted Git repository
与许多其他人一起,但我没有看到太多关于从提交到提交错误的断开链接的建议。请注意,我确实复制了这个存储库,所以我没有擦除任何内容。
git fsck的结果是
$ git fsck
broken link from commit <SHA1>
to commit <SHA2>
broken link from tree <SHA3>
to blob <SHA4>
...
dangling blob <SHA5>
missing commit <SHA2>
missing blob <SHA4>
...
当我通过 git log 浏览 git 历史时,最终我得到了错误
error: Could not read <SHA2>
fatal: Failed to traverse parents of commit <SHA1>
它靠近(ish)最后一个备份存在的位置,但不完全在那里,所以我没有重叠覆盖。我想尝试反向遍历历史,认为我可以将日志从最旧的提交移动到最新的提交,但
$ git log --reverse
error: Could not read <SHA2>
fatal: Failed to traverse parents of commit <SHA1>
所以我不能尝试绑定双方的提交(除非有人知道如何做到这一点)。我尝试使用git repair,它似乎能够解决一些问题,但不是全部。从现在开始,git log
$ git log
...
error: Could not read <SHA6>
fatal: Failed to traverse parents of commit <SHA7>
这在历史上比问题发生得更早。有趣的是,这个提交确实存在于我原来未修复的存储库中。复制 sha 文件让我摆脱了失败,只是因为另一个同样存在的文件突然出现。
它建议我运行git repair --force,但最终完全重新初始化了存储库,这也不是我真正想要的。
我该怎么做才能将此存储库恢复到正常工作状态?
【问题讨论】:
-
“断开的链接”投诉实际上只是意味着
git fsck无法将给定的哈希 ID 检索为必要类型的有效对象。这就是为什么您在那之后不久就将它们视为“丢失”的原因:Git 根本无法检索它们。 fsck 可能会抱怨类似(但略有不同),例如,如果提交声称其父提交是 hashX 并且 hashX 存在但不是提交对象(是树、blob 或带注释的标签对象)。 -
我不太确定
git repair究竟做了什么,但阅读 this page 上的顶级声明表明,当且仅当它能够从它通过在配置中找到的各种远程 Git URL 找到相关的 Git 存储库。 -
@torek 好的,这对
git repair更有意义。我应该更彻底地阅读文档。我已经取得了一些进展,git log现在可以完全构建,但git fsck仍然显示丢失的提交,git gc也会阻塞。
标签: git commit corruption recovery