我经常使用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(你的哈希)

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

其他回答

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

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

只查看隐藏提交、它们附加的位置以及它们的内容

结果样本

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。。。

回收样品

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

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

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

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

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>应用它

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

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

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