我经常使用gitstash和gitstashpop来保存和恢复工作树中的更改。昨天,我在我的工作树中做了一些修改,这些修改是我藏起来并弹出的,然后我对工作树做了更多的修改。我想回去回顾一下昨天隐藏的更改,但gitstashpop似乎删除了对相关提交的所有引用。

我知道如果我使用git stash,那么.git/refs/stash包含用于创建stash的提交的引用。git/logs/refs/stash包含整个存储。但这些参考资料在git stash pop之后就不见了。我知道提交仍在我的存储库中,但我不知道它是什么。

有没有一种简单的方法可以恢复昨天的存储提交引用?


当前回答

您可以一步一步地执行以下过程:

1-使用下面列出所有无法访问的提交git fsck—无法访问

2-显示无法访问的提交哈希git显示哈希

3-复制所有日志,您可以看到类似日志的、无法访问的blob、提交和树。

4-使用具有提交哈希的日志应用git stashgit stash apply[替换哈希]

其他回答

要获取仍在存储库中但无法访问的存储列表,请执行以下操作:

git fsck --unreachable | grep commit | cut -d" " -f3 | xargs git log --merges --no-walk --grep=WIP

如果您给了存储的标题,请将命令末尾的-grep=WIP中的“WIP”替换为消息的一部分,例如-grep=Tesselation。

该命令是“WIP”的grepping,因为存储的默认提交消息的格式为mybranch上的WIP:[先前提交哈希]先前提交的消息。

找到提交后,使用git stash apply<commit_hash>应用它

我刚刚构造了一个命令,帮助我找到丢失的藏匿物品:

for ref in `find .git/objects | sed -e 's#.git/objects/##' | grep / | tr -d /`; do if [ `git cat-file -t $ref` = "commit" ]; then git show --summary $ref; fi; done | less

这将列出.git/objects树中的所有对象,查找属于commit类型的对象,然后显示每个对象的摘要。从这一点来看,只需要仔细查看提交,找到合适的“WIP on work:6a9b2”(“work”是我的分支,619bb2是最近的提交)。

我注意到,如果我使用“git stash apply”而不是“git stash pop”,我就不会有这个问题,如果我用“git sash save message”,那么提交可能会更容易找到。

更新:根据内森的想法,这变得更短:

for ref in `git fsck --unreachable | grep commit | cut -d' ' -f3`; do git show --summary $ref; done | less

我喜欢亚里士多德的方法,但不喜欢使用GITK。。。因为我习惯于从命令行使用GIT。

相反,我接受了悬空提交,并将代码输出到DIFF文件,以便在代码编辑器中查看。

git show $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' ) > ~/stash_recovery.diff

现在,您可以将生成的diff.txt文件(位于主文件夹中)加载到txt编辑器中,并查看实际代码和生成的SHA。

那就用

git stash apply ad38abbf76e26c803b27a6079348192d32f52219

我只是想在公认的解决方案中提及这一点。第一次尝试这个方法时,我并没有立即意识到这一点(也许应该是这样),但要从哈希值应用存储,只需使用“git stash apply”:

$ git stash apply ad38abbf76e26c803b27a6079348192d32f52219

当我刚接触git时,我并不清楚这一点,我尝试了“git show”、“git apply”、“patch”等不同的组合。

通过在终端中写入此命令,可以列出所有无法访问的提交-

git fsck --unreachable

检查无法访问的提交哈希-

git show hash

如果你找到了隐藏的物品,最后申请-

git stash apply hash