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

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

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


当前回答

我无法在一个简单的命令窗口(在我的例子中是Windows7)中获得在Windows上工作的任何答案。awk、grep和Select字符串未被识别为命令。所以我尝试了一种不同的方法:

第一次运行:git fsck--无法访问| findstr“commit”将输出复制到记事本查找用start cmd/k git show替换“无法访问的提交”

将看起来像这样:

启动cmd/k git show 8506d235f935b92df65d58e7d75e9441220537a4启动cmd/k git show 44078733e1b36962571019126243782421fcd8ae启动cmd/k git show ec09069ec893db4ec1901f94eefc8dc606b1dbf1启动cmd/k git show d00aab9198e8b81d052d90720165e48b287c302e

保存为.bat文件并运行它脚本将打开一组命令窗口,显示每个提交如果你找到了你要找的,运行:git stash apply(你的哈希)

也许不是最好的解决方案,但对我来说有效

其他回答

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

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

我建议每个有这个问题的人只检查一下reflog(git reflog),不要太多。一旦您看到所有提交的列表,就有一百种方法可以找到您要查找的提交,并从中选择或创建分支。在此过程中,您将了解reflog以及各种基本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”进入下一个差异。

如果您没有关闭终端,只需查看git stash pop的输出,您将获得丢弃的stash的对象ID。通常情况如下:

$ git stash pop
[...]
Dropped refs/stash@{0} (2ca03e22256be97f9e40f08e6d6773c7d41dbfd1)

(请注意,git stash drop也会生成相同的行。)

要取回存储,只需运行gitbranchtmp2cae03e,就可以将其作为一个分支获取。要将其转换为存储,请运行:

git stash apply tmp
git stash

把它作为一个分支也可以让你自由地操纵它;例如,樱桃采摘或合并它。

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

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

如果你想重新存放丢失的东西,你需要先找到丢失的东西的散列。

正如亚里斯多德·帕加尔茨所建议的那样,一个git fsck应该可以帮助你。

就我个人而言,我使用显示每次提交(可恢复提交)的log-all别名来更好地了解情况:

git log --graph --decorate --pretty=oneline --abbrev-commit --all $(git fsck --no-reflogs | grep commit | cut -d' ' -f3)

如果只查找“WIP on”消息,则可以执行更快的搜索。

一旦你知道你的sha1,你只需改变你的存储reflog,添加旧的存储:

git update-ref refs/stash ed6721d

你可能更希望有一个相关的消息,所以

git update-ref -m "$(git log -1 --pretty=format:'%s' ed6721d)" refs/stash ed6721d

您甚至希望将其用作别名:

restash = !git update-ref -m $(git log -1 --pretty=format:'%s' $1) refs/stash $1