从Git恢复无法读取blob,文件现在有不同的哈希? 我是在 Git ReBase< /C>中,并且对于Git是的错误不能读取cc95d563f90FD48C24824418B6AE5DDFB0A2A < /P>

从Git恢复无法读取blob,文件现在有不同的哈希? 我是在 Git ReBase< /C>中,并且对于Git是的错误不能读取cc95d563f90FD48C24824418B6AE5DDFB0A2A < /P>,git,blob,commit,rebase,Git,Blob,Commit,Rebase,我进行了调查,发现该blob在四次提交中被引用。我解包了其中一个提交并对blob进行了灰色处理,结果将我指向repo中的文件。我已将输出文件名替换为brokenfile,并且dc77f57d是引用blob的提交: $ git ls-tree -r dc77f57d | grep cc95d5463f90fd78c4382948418b6ae5ddfb0a2a 100644 blob cc95d5463f90fd78c4382948418b6ae5ddfb0a2a brokenfile $

我进行了调查,发现该blob在四次提交中被引用。我解包了其中一个提交并对blob进行了灰色处理,结果将我指向repo中的文件。我已将输出文件名替换为
brokenfile
,并且
dc77f57d
是引用blob的提交:

$ git ls-tree -r dc77f57d | grep cc95d5463f90fd78c4382948418b6ae5ddfb0a2a
100644 blob cc95d5463f90fd78c4382948418b6ae5ddfb0a2a    brokenfile
$ git hash-object brokenfile
695d542ba36a58012c928e999b3b5f36bbb8013d
git fsck
还报告:

broken link from    tree 4e6de279c5d48acc16457bf35cea9702c892ddd1
              to    blob cc95d5463f90fd78c4382948418b6ae5ddfb0a2a
...
missing blob cc95d5463f90fd78c4382948418b6ae5ddfb0a2a
然后我打算为该文件重新创建blob,但该文件的哈希不再与blob匹配:

$ git ls-tree -r dc77f57d | grep cc95d5463f90fd78c4382948418b6ae5ddfb0a2a
100644 blob cc95d5463f90fd78c4382948418b6ae5ddfb0a2a    brokenfile
$ git hash-object brokenfile
695d542ba36a58012c928e999b3b5f36bbb8013d
有没有办法从这种状态中恢复过来?这个blob在.git/objects/中根本不存在,这让我相信它是在重新基址期间被删除的


谢谢。

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

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
,然后重新开始

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

有两个,;两者都不令人愉快或有趣

更好的方法是找到存储库的某个副本,该副本中确实包含缺少的blob。可能没有这样的副本,但如果有,您可以将文件取出并粘贴到您的存储库中,现在一切都好了。如果您有存储库的一些备份副本或其克隆,只需输入每个备份副本并在每个备份副本中使用
git cat file-t cc95d5463f90fd78c4382948b6ae5ddfb0a2a
。如果这告诉您对象存在并且类型为
blob
,则您已经找到了它;如果它说
致命:git cat file:无法获取对象信息
,则此存储库没有该对象

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

git cat-file -p cc95d5463f90fd78c4382948418b6ae5ddfb0a2a > /tmp/the-file
cd <path to broken repository>
git hash-object -w -t blob /tmp/the-file
git cat文件-p cc95d5463f90fd78c438294848b6ae5ddfb0a2a>/tmp/the文件
光盘
git散列对象-w-t blob/tmp/the文件

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

不要忘记
mv
之后的
git init
:-)顺便说一句,我对问题的原因很好奇。我心里有个嫌疑犯。您在这里使用的是
git worktree add
?如果是这样,您的Git版本是否早于Git2.15?@torek很好!我已经更新了答案。我实际上没有使用git worktree,我的版本是2.16.3,所以可能不是你在mindHm中看到的,是的,显然这不是已知的
git worktree
bug。回答得好。在核化并重新初始化我的回购协议后,我意识到我可能在某处有一个时间机器备份它。。。这将是一个更直接的解决方案!我越了解git的设计,越了解如何构建这样的存储库,我就越喜欢它。