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

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

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


当前回答

要查看终端中的提交,只有过滤我们关心的提交,我们才能使用:

git log --oneline --all --grep="^WIP on .*: [a-f0-9]\+" --grep="^On [^ ]*:" --grep="^index on [^ ]*:" $( env LANG=C git fsck --no-reflog | awk '/dangling commit/ {print $3}' )

这是基于亚里斯多德·帕加尔茨的回答。

其他回答

这对我来说(在2022年)很有用,我从windows环境中恢复了我意外删除的git存储。

这些步骤概述了如何恢复任何已删除的git存储或分支(假设它未被垃圾收集永久删除)。

导航到项目所在的目录。输入命令:git fsck--no reflogs | find“悬空提交”将出现悬空提交的哈希列表。这些将包含已删除的分支和存储。从复制并粘贴列表末尾附近的哈希开始,以找到您的隐藏或分支。例如,使用命令:git-log-1[hash]如果相应的哈希值与您尝试恢复的哈希值匹配,请使用以下命令将其还原“git存储应用

我想在已接受的解决方案中添加另一个好方法,以在您没有gitk可用或没有X输出时完成所有更改。

git fsck --no-reflog | awk '/dangling commit/ {print $3}' > tmp_commits

for h in `cat tmp_commits`; do git show $h | less; done

然后,您将获得这些哈希值的所有差异。按“q”进入下一个差异。

不完全是一个获取隐藏的答案,但如果目标是获取未提交的更改,这些更改首先被隐藏,然后被弹出到另一个分支中,但这两种更改都适用,并按以下方式完成:

在分支中进行更改(_a)暂存从branch_a生成branch_b应用git存储

然后,要将未提交的更改还原到branch_a:

git结帐分支agit合并分支bgit重置HEAD~1

一旦你知道你丢弃的隐藏提交的哈希值,你就可以将其作为一个隐藏:

git stash apply $stash_hash

或者,可以使用

git branch recovered $stash_hash

之后,您可以使用所有常规工具做任何您想做的事情。完成后,把树枝吹走。

查找哈希

如果你刚刚弹出它,并且终端仍然打开,你仍然会在屏幕上看到git stash pop打印的哈希值(谢谢,Dolda)。

否则,您可以在Linux、Unix或Windows的Git Bash中找到它:

git fsck --no-reflog | awk '/dangling commit/ {print $3}'

…或使用PowerShell for Windows:

git fsck --no-reflog | select-string 'dangling commit' | foreach { $_.ToString().Split(" ")[2] }

这将在提交图的顶端显示所有提交,这些提交不再从任何分支或标记引用——每个丢失的提交,包括您创建的每个隐藏提交,都将位于该图的某个位置。

找到您想要的隐藏提交的最简单方法可能是将该列表传递给gitk:

gitk --all $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' )

…如果使用PowerShell for Windows,请查看emragins的答案。

这将启动一个存储库浏览器,显示存储库中的每一次提交,无论它是否可访问。

如果您更喜欢控制台上的图形而不是单独的GUI应用程序,那么可以用git-log-grap-online之类的东西来替换gitk。

要发现隐藏提交,请查找以下形式的提交消息:

某个分支上的WIP:commithash一些旧的提交消息

注意:如果您在执行git stash时没有提供消息,则提交消息将以这种形式出现(以“WIP on”开头)。

为什么人们会问这个问题?因为他们还不知道或不了解回流。

这个问题的大多数答案都给出了长命令和选项,几乎没有人会记得。因此,人们进入这个问题,复制粘贴他们认为需要的任何内容,然后几乎立即忘记。

我建议每个有这个问题的人只检查一下reflog(git reflog),不要太多。一旦您看到所有提交的列表,就有一百种方法可以找到您要查找的提交,并从中选择或创建分支。在此过程中,您将了解reflog以及各种基本git命令的有用选项。