我在我的私房钱里存了一小块。我已经使用git stash apply将它应用到我的工作副本。现在,我想通过反向应用补丁来撤销这些更改(有点像git revert会做的事情,但针对的是stash)。

有人知道怎么做吗?

澄清:在我的工作副本中有其他更改。我的具体情况很难描述,但您可以想象在存储库中有一些调试或实验代码。现在,它混合在我的工作副本与其他一些变化,我想看看效果与不从隐藏的变化。

目前看来stash还不支持这个功能,但是git的stash apply—reverse将是一个不错的功能。


当前回答

我自己也有类似的问题,我认为你所需要做的就是git重置——很难,你不会失去你的变化或任何未跟踪的变化。

如果你阅读git stash——help中的文档,它声明apply是“像pop一样,但不从stash列表中删除状态”,所以状态仍然驻留在那里,你可以取回它。

或者,如果没有冲突,您可以在测试更改后再次git stash。

如果你确实有冲突,不要担心,git重置-hard不会失去他们,因为 “应用状态可能会因冲突而失败;在这种情况下,它不会从收藏列表中删除。你需要手动解决冲突,然后手动调用git stash drop。”

其他回答

V1 git手册页有一个关于取消应用存储的参考。节选如下。

更新的V2 git手册页不包括任何关于取消应用stash的参考,但下面的内容仍然可以很好地工作

取消应用Stash 在某些用例场景中,您可能希望应用存储的更改,做一些工作,但随后取消应用最初来自存储的那些更改。Git没有提供这样的stash unapply命令,但是可以通过简单地检索与stash相关的补丁并反向应用它来达到这个效果:

$ git stash show -p stash@{0} | git apply -R

同样,如果你没有指定一个存储,Git假设是最近的存储:

$ git stash show -p | git apply -R

您可能想要创建一个别名,并有效地向Git添加一个stash-unapply命令。例如:

$ git config --global alias.stash-unapply '!git stash show -p | git apply -R'
$ git stash apply
$ #... work work work
$ git stash-unapply

如何反向应用收藏?

除了别人提到的,最简单的方法是先做

git reset HEAD

然后签出所有本地更改

git checkout . 

git stash[save]获取你的工作目录状态和索引状态,并将它们存储起来,将索引和工作区域设置为HEAD版本。

Git stash apply会带回这些更改,所以Git reset—hard会再次删除它们。

Git stash pop带回这些更改并删除顶部存储的更改,因此Git stash [save]将在这种情况下返回到之前(预弹出)状态。

根据git-stash手册,“一个stash被表示为一个提交,它的树记录了工作目录的状态,它的第一个父级是创建stash时在HEAD处的提交,”git stash show -p给我们“记录在stash中的更改,作为隐藏状态与其原始父级之间的差异”。

为了保持其他更改不变,使用git stash show -p | patch——reverse如下所示:

$ git init
Initialized empty Git repository in /tmp/repo/.git/

$ echo Hello, world >messages

$ git add messages

$ git commit -am 'Initial commit'
[master (root-commit)]: created 1ff2478: "Initial commit"
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 messages

$ echo Hello again >>messages

$ git stash

$ git status
# On branch master
nothing to commit (working directory clean)

$ git stash apply
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   messages
#
no changes added to commit (use "git add" and/or "git commit -a")

$ echo Howdy all >>messages

$ git diff
diff --git a/messages b/messages
index a5c1966..eade523 100644
--- a/messages
+++ b/messages
@@ -1 +1,3 @@
 Hello, world
+Hello again
+Howdy all

$ git stash show -p | patch --reverse
patching file messages
Hunk #1 succeeded at 1 with fuzz 1.

$ git diff
diff --git a/messages b/messages
index a5c1966..364fc91 100644
--- a/messages
+++ b/messages
@@ -1 +1,2 @@
 Hello, world
+Howdy all

编辑:

一个轻微的改进是使用git apply来代替patch:

git stash show -p | git apply --reverse

或者,你也可以使用git apply -R作为git apply——reverse的简写。

我最近发现这真的很方便……

我自己也有类似的问题,我认为你所需要做的就是git重置——很难,你不会失去你的变化或任何未跟踪的变化。

如果你阅读git stash——help中的文档,它声明apply是“像pop一样,但不从stash列表中删除状态”,所以状态仍然驻留在那里,你可以取回它。

或者,如果没有冲突,您可以在测试更改后再次git stash。

如果你确实有冲突,不要担心,git重置-hard不会失去他们,因为 “应用状态可能会因冲突而失败;在这种情况下,它不会从收藏列表中删除。你需要手动解决冲突,然后手动调用git stash drop。”