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

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

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


当前回答

我最喜欢的是这一行:

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

其他回答

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

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

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

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

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

正如亚里斯多德·帕加尔茨所建议的那样,一个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

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

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

通过以下步骤恢复:

识别已删除的隐藏哈希代码:gitk--all$(git fsck--no reflog | awk‘/悬空提交/{print$3}‘)樱桃摘葡萄:git cherry pick-m 1$stash_hash_code使用以下方法解决冲突(如果有):git合并工具

此外,如果使用gerrit,您可能会遇到提交消息的问题。在执行下一个备选方案之前,请先保存您的更改:

使用硬重置到上一次提交,然后重新提交此更改。你也可以把零钱藏起来,重新放在底座上,然后重新提交。

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

结果样本

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

回收样品