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

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

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


当前回答

使用gitk的Windows PowerShell等效程序:

gitk--all$(git fsck--no reflog |选择字符串“(悬空提交)(.*)”|%{$_.Line.Split('')[2]})

也许有一种更有效的方法可以在一个管道中完成这项工作,但这确实有效。

其他回答

知道了大概的文件名及其位置,并且能够找到丢弃的隐藏文件,并将悬空提交添加到路径中

for i in $(git fsck --no-reflogs | awk '/dangling commit/ {print $3}'); do
  if git log -5 --name-only -u $i | grep -q "<path-to-files>/.*<partial-file-name>.*"; then
    echo "found something in commit $i";
  fi;
done

gitfsck——不可访问|grep提交应该显示sha1,尽管它返回的列表可能很大。gitshow<sha1>将显示它是否是您想要的提交。

gitcherry-pick-m1<sha1>将提交合并到当前分支。

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

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}' )

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

我想在已接受的解决方案中添加另一个好方法,以在您没有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”进入下一个差异。

我最喜欢的是这一行:

git log --oneline  $( git fsck --no-reflogs | awk '/dangling commit/ {print $3}' )

这与这个答案基本相同,但要短得多。当然,您仍然可以添加--graph以获得树状显示。

在列表中找到提交后,使用

git stash apply THE_COMMIT_HASH_FOUND

对我来说,使用--no reflogs确实揭示了丢失的存储条目,但--unareachable(正如许多其他答案中所发现的)并没有。

在Windows下,在gitbash上运行它。

致谢:以上命令的详细信息摘自https://gist.github.com/joseluisq/7f0f1402f05c45bac10814a9e38f81bf