我经常使用gitstash和gitstashpop来保存和恢复工作树中的更改。昨天,我在我的工作树中做了一些修改,这些修改是我藏起来并弹出的,然后我对工作树做了更多的修改。我想回去回顾一下昨天隐藏的更改,但gitstashpop似乎删除了对相关提交的所有引用。
我知道如果我使用git stash,那么.git/refs/stash包含用于创建stash的提交的引用。git/logs/refs/stash包含整个存储。但这些参考资料在git stash pop之后就不见了。我知道提交仍在我的存储库中,但我不知道它是什么。
有没有一种简单的方法可以恢复昨天的存储提交引用?
只查看隐藏提交、它们附加的位置以及它们的内容
结果样本
Checking object directories: 100% (256/256), done.
2022-08-31 10:20:46 +0900 8d02f61 WIP on master: 243b594 add css
A favicon.ico
命令
git fsck --dangling | awk '/dangling commit/ {print $3}' | xargs -L 1 git --no-pager show -s --format="%ct %h" | sort | awk '{print $2}' | { while read hash; do status=$(git stash show $hash --name-status 2>/dev/null); if (( $? == 0 )); then git show $hash -s --format="%C(green)%ci %C(yellow)%h %C(blue)%B"; echo "$status"; fi; done; }
若要查看完整哈希,请将%h更改为%h为了减少时间,尾部fsck类似于gitfsck--悬挂|tail-100|awk。。。
回收样品
我无法在一个简单的命令窗口(在我的例子中是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(你的哈希)
也许不是最好的解决方案,但对我来说有效
我最喜欢的是这一行:
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
我来这里的目的是,不管我签了什么,都要如何真正拿回藏起来的东西。特别是,我藏了一些东西,然后检查了一个旧版本,然后打开了它,但在更早的时间点,这个藏的东西是不可用的,所以这个藏的就消失了;我不能只做git stash把它推回到堆栈上。这对我有用:
$ git checkout somethingOld
$ git stash pop
...
nothing added to commit but untracked files present (use "git add" to track)
Dropped refs/stash@{0} (27f6bd8ba3c4a34f134e12fe69bf69c192f71179)
$ git checkout 27f6bd8ba3c
$ git reset HEAD^ # Make the working tree differ from the parent.
$ git stash # Put the stash back in the stack.
Saved working directory and index state WIP on (no branch): c2be516 Some message.
HEAD is now at c2be516 Some message.
$ git checkout somethingOld # Now we are back where we were.
回想起来,我应该使用git stash apply而不是git stashpop。我在做二等分,在每一个二等分步骤上都有一个小补丁。现在我正在做这件事:
$ git reset --hard; git bisect good; git stash apply
$ # Run tests
$ git reset --hard; git bisect bad; git stash apply
etc.