如何通过关键字在GIT存储库中找到无法访问的提交哈希?

时间:2015-07-13 16:42:59

标签: git

我对GIT情况感到有些困惑。

我正在开发一个GIT版本的项目,我刚刚注意到我们认为几周前已经在主分支上的一些提交实际上已经丢失了。我记得这些提交是由其他人在功能分支“功能/某事物”上推动的,不再存在。

我试图找到那些丢失的提交来修复我们的错误并将它们推到永久分支上。 在此团队中,每个开发人员都会在提交消息中提供他正在处理的故障单的ID。所以我肯定知道票证ID(例如1234) 在我正在寻找的提交消息中,所以我尝试了:

git log --all --grep=1234
git log -g --grep=1234
git log --all | grep 1234
git reflog | grep 1234

所有这些命令都没有返回任何内容。

此时,我正要放弃,然后我记得我们的git repo与Slack集成,所以我在松弛的历史中搜索了1234 并发现了提交哈希。我马上试过了:

git show hash1
git show hash2

令人惊讶的工作!它显示了所有提交信息。所以提交就在那里,不知何故仍在我的本地存储库中。 所以我想仔细检查一下我是如何错过的:

git reflog | grep hash1
git branch --contains hash1
git fsck --lost-found | grep hash1

没有

git fsck --unreachable | grep hash1
unreachable commit hash1

就在这里,在无法访问的提交列表中。

但这是一个很大的项目,而git fsck --unreachable会返回大量的提交,我怎么能通过关键字找到这个丢失的提交? 如果我们没有第三方工具记录git活动,也许我会尝试将git fsck的输出重新导入git show以某种方式 并且对结果进行了嘲讽,但为了找到一个我知道的提交就在这里似乎要做很多事情。

P.S:对不起,我不能分享回购,这是一个私人项目,但以下应该重现这种情况:

用户A:

git clone <repo>
git checkout -b feature/something
# add something to commit
git commit -m “special-keyword"
git push origin feature/something

用户B:

git clone <repo>
git push origin :feature/something

现在用户B工作数周,然后尝试查找用户A推送的提交“特殊关键字”。

2 个答案:

答案 0 :(得分:9)

删除分支时,还会删除其reflog。 HEAD有一个单独的reflog,它将保留对已删除分支上的提交的引用,但只有在您已签出的情况下

--lost-found--unreachable之间的差异很微妙: 1 请参阅git glossary和/或下图。通常,使用--lost-found和/或--unreachable会发现此类提交(以及--lost-found,也会将ID写入.git/lost-found/commit目录,我认为具有保护他们免受垃圾收集的副作用。)

在这种特殊情况下,您正在寻找的提交不是已删除分支的提示最多提交。也就是说,假设在删除feature/something之前我们有这个,并且在功能分支上进行了两次最近的提交:

A <- B <- C   <-- master
  \
    D <- E    <-- feature/something

现在我们删除了feature/something,丢失了提交ED的ID。这两个ID都会显示在git fsck --unreachable的输出中,但只有E的ID会显示(并保存)git fsck --lost-found,因为提交D是&#34;可达&#34;来自E if / when恢复该提交。

查找您的提交

  

我怎么能通过关键字找到这个丢失的提交?

这有点棘手。可能你最好的选择是在所有无法访问的提交上使用git show,例如:

git show $(git fsck --unreachable | git cat-file --batch-check |
    awk '/commit/ { print $3 }')

现在,您可以在日志消息(或差异)中搜索关键字。内部$(...)序列是提取所有候选ID的方法:我们只需要提交,而不是标签,树和blob。获得ID后,所有常规git命令(git log -1git show等)都可以与这些命令一起使用。

1 事实上,我刚刚自己写了这个答案。

答案 1 :(得分:-1)

似乎你有提交哈希值,所以你可以做

git checkout <HASH>