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

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

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


当前回答

我来这里的目的是,不管我签了什么,都要如何真正拿回藏起来的东西。特别是,我藏了一些东西,然后检查了一个旧版本,然后打开了它,但在更早的时间点,这个藏的东西是不可用的,所以这个藏的就消失了;我不能只做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.

其他回答

我想在已接受的解决方案中添加另一个好方法,以在您没有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 v2.6.4的OSX中,我只是意外地运行了git stash drop,然后我通过以下步骤找到了它

若你们知道储藏物的名称,那个么使用:

$git fsck--无法访问|grep commit |cut-c 20-|xargs git show |grep-B 6-A 2<存储的名称>

否则,您将通过以下方式手动从结果中找到ID:

$git fsck--无法访问|grep commit |cut-c 20-|xargs git show

然后,当您找到提交id时,只需点击git stash apply{commit id}

希望这能帮助到某人

我只是想在公认的解决方案中提及这一点。第一次尝试这个方法时,我并没有立即意识到这一点(也许应该是这样),但要从哈希值应用存储,只需使用“git stash apply”:

$ git stash apply ad38abbf76e26c803b27a6079348192d32f52219

当我刚接触git时,我并不清楚这一点,我尝试了“git show”、“git apply”、“patch”等不同的组合。

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

结果样本

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

回收样品

我来这里的目的是,不管我签了什么,都要如何真正拿回藏起来的东西。特别是,我藏了一些东西,然后检查了一个旧版本,然后打开了它,但在更早的时间点,这个藏的东西是不可用的,所以这个藏的就消失了;我不能只做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.