从 Git 中恢复无法读取 blob,文件现在有不同的哈希?

Posted

技术标签:

【中文标题】从 Git 中恢复无法读取 blob,文件现在有不同的哈希?【英文标题】:Recover from Git unable to read blob, file now has a different hash? 【发布时间】:2021-03-17 14:05:30 【问题描述】:

我在 git rebase 的中间,得到一个关于 git 是 unable to read cc95d5463f90fd78c4382948418b6ae5ddfb0a2a 的错误

我进行了调查,发现该 blob 在四个提交中被引用。我解压缩了其中一个提交并 grep 了 blob,输出将我指向我的 repo 中的文件。我已将输出文件名替换为brokenfile,而dc77f57d 是引用该blob 的提交:

$ git ls-tree -r dc77f57d | grep cc95d5463f90fd78c4382948418b6ae5ddfb0a2a
100644 blob cc95d5463f90fd78c4382948418b6ae5ddfb0a2a    brokenfile

git fsck 还报告:

broken link from    tree 4e6de279c5d48acc16457bf35cea9702c892ddd1
              to    blob cc95d5463f90fd78c4382948418b6ae5ddfb0a2a
...
missing blob cc95d5463f90fd78c4382948418b6ae5ddfb0a2a

然后我打算为文件重新创建 blob,但文件的哈希不再匹配 blob:

$ git hash-object brokenfile
695d542ba36a58012c928e999b3b5f36bbb8013d

有没有办法从这种状态中恢复?该 blob 在 .git/objects/ 中根本不存在,这让我相信它在 rebase 期间以某种方式被删除了。

谢谢。

【问题讨论】:

【参考方案1】:

有没有办法从这种状态中恢复?

有两个;既不愉快也不有趣。

更好的方法是找到一些 确实 缺少 blob 的存储库副本。 可能没有这样的副本,但如果有,您可以将文件取出并将其粘贴到您的存储库中,现在一切都很好了。如果您有存储库的一些备份副本或它的克隆,只需输入每个副本并在每个副本中使用 git cat-file -t cc95d5463f90fd78c4382948418b6ae5ddfb0a2a。如果这告诉您该对象存在并且类型为blob,那么您已经找到它;如果它显示fatal: git cat-file: could not get object info,则此存储库没有该对象。

(一旦找到,有几种方法可以将对象复制回稍微损坏的存储库。最简单的是:

git cat-file -p cc95d5463f90fd78c4382948418b6ae5ddfb0a2a > /tmp/the-file
cd <path to broken repository>
git hash-object -w -t blob /tmp/the-file

另一种方法是丢弃错误提交及其所有后代。 (Your own method——丢弃整个存储库并创建一个新存储库——只是这种方法的极端版本​​。)

【讨论】:

好答案。在 nuking 和重新初始化我的 repo 之后,我意识到我可能在某个地方有一个 Time Machine 备份......这将是一个更直接的解决方案! 我越了解 git 的设计方式,越了解如何构建这样的存储库,我就越喜欢它。【参考方案2】:

我最终通过删除 .git 并重新初始化 repo 解决了这个问题。遇到相同问题的步骤:

mv .git .git.bak  #Make a copy in case something goes wrong
git init
git remote add origin MY_REPO_URL
git fetch && git reset origin/master --mixed

--mixed on git reset 将确保它保留您的本地文件更改。

就是这样!如果您在这种状态下破坏了某些内容,只需将备份复制到 .git 并重新开始。

【讨论】:

不要忘记git init 之后的mv :-) 顺便说一句,我很好奇问题的原因。我心里有个嫌疑人。你在这里使用git worktree add 吗?如果是,您的 Git 版本是否早于 Git 2.15? @torek 不错!我已经更新了答案。我其实并没有使用 git worktree,而且我的版本是 2.16.3,所以可能不是你想的那样 嗯,是的,显然这不是已知的git worktree 错误。

以上是关于从 Git 中恢复无法读取 blob,文件现在有不同的哈希?的主要内容,如果未能解决你的问题,请参考以下文章

需要通过oledb连接从azure存储blob容器中读取excel文件

无法从 synapse spark scala notebook 读取 csv 文件

如何从 GIT 恢复旧的拉取请求

从 .gitmodules 恢复 git 子模块

DataFlow 无法读取存储在 Blob 存储中的 API 响应 json 文件

git删除了本地文件,从远程仓库中恢复