139

我正在尝试应用我之前存储的更改git stash pop并收到消息:

Cannot apply to a dirty working tree, please stage your changes

关于如何处理的任何建议?

4

11 回答 11

206

当我必须将隐藏的更改应用于脏工作副本时,例如从存储中弹出多个变更集,我使用以下内容:

$ git stash show -p | git apply -3 && git stash drop

基本上它

  1. 创建补丁
  2. 将其传递给应用命令
  3. 如果有任何冲突,则需要通过 3 路合并解决
  4. 如果应用(或合并)成功,它会丢弃刚刚应用的存储项...

我想知道为什么没有-f(强制)选项git stash pop应该完全像上面的单线一样。

同时,您可能希望将此单行代码添加为 git 别名:

$ git config --global --replace-all alias.unstash \
   '!git stash show -p | git apply -3 && git stash drop'
$ git unstash

感谢@SamHasler 指出-3允许通过 3 路合并直接解决冲突的参数。

于 2010-09-17T08:21:45.040 回答
62

我这样做:

git add -A
git stash apply

然后(可选):

git reset
于 2012-07-24T08:59:03.243 回答
9

您可以通过将所需的存储导出为补丁文件并手动应用它来执行此操作,而无需存储当前更改。

例如,假设您要应用于stash@{0}脏树:

  1. 导出stash@{0}为补丁:

    git stash show -p stash@{0} > Stash0.patch
    
  2. 手动应用更改:

    git apply Stash0.patch
    

如果第二步失败,您将不得不编辑Stash0.patch文件以修复任何错误,然后git apply重试。

于 2010-03-30T22:44:18.563 回答
8

使用 git reset 清理您的工作目录,提交更改,或者,如果您想存储当前更改,请尝试:

$ git stash save "当前更改的描述"
$ git stash pop stash@{1}

这将存储当前更改,然后从存储堆栈中弹出第二个存储。

于 2009-09-01T05:53:06.257 回答
6

Mathias 的解决方案绝对是最接近于 a 的git stash pop --force(真的,来吧 Git 开发人员,让我们已经获得这个选项!)

但是,如果你想只使用 Git 命令来做同样的事情,你可以:

  1. git commit -a -m "Fixme"
  2. git stash pop
  3. git commit -a --amend
  4. git reset HEAD~

换句话说,对您当前的更改进行提交(我们永远不会推送)。现在您的工作区已经干净了,请弹出您的存储区。现在,提交存储更改作为对之前提交的修正。完成后,您现在将两组更改组合在一个提交中(“Fixme”);只是git reset--soft不是--hard所以实际上什么都没有丢失)你的结帐到“那个提交之前的一个”,现在你有两组更改,完全未提交。

编辑

我刚刚意识到这实际上更容易;您可以完全跳过第 3 步,所以...

  1. git commit -a -m "Fixme"
  2. git stash pop
  3. git reset HEAD~

(提交当前更改,弹出隐藏的更改,重置第一次提交以使两组更改组合在未提交状态。)

于 2012-04-17T18:17:36.957 回答
4

如果您发现自己像我今天那样处于这种情况下,那么这些答案都不会真正起作用。不管我做了多少git reset --hard,它让我无处可去。我的回答(无论如何都不是官方的):

  1. 找出存储的哈希使用git reflog --all
  2. 将该哈希与您感兴趣的分支合并
于 2010-10-28T05:35:14.140 回答
4

我还发现Mathias Leppich 的解决方案效果很好,所以我为它添加了一个别名到我的全局 .gitconfig

[alias]
        apply-stash-to-dirty-working-tree = !git stash show -p | git apply && git stash drop

现在我可以输入

git apply-stash-to-dirty-working-tree

这对我很有用。

(你的里程可能会因这个长别名而有所不同。但我喜欢在 bash 完成时有点冗长。)

于 2011-04-26T09:09:25.570 回答
3

您可以通过暂存您所做的任何更改来将存储应用到“脏”树git add,从而清理树。然后你可以git stash pop应用隐藏的更改,没问题。

于 2012-01-20T19:33:58.977 回答
2

您有已修改但未提交的文件。任何一个:

git reset --hard HEAD (to bring everything back to HEAD)

或者,如果您想保存更改:

git checkout -b new_branch
git add ...
git commit
git checkout -b old_branch
git stash pop
于 2009-09-01T05:54:01.763 回答
0

我无法让其中大部分工作。由于某种原因,它总是认为我对文件进行了本地更改。我无法应用存储,补丁不会应用,checkout并且reset --hard失败。最终起作用的是将存储保存为带有 的分支git stash branch tempbranchname,然后进行正常的分支合并:git checkout mastergit merge tempbranchname. 来自http://git-scm.com/book/en/Git-Tools-Stashing

如果您想要一种更简单的方法来再次测试隐藏的更改,您可以运行 git stash branch,它会为您创建一个新分支,检查您在隐藏工作时所做的提交,在那里重新应用您的工作,然后删除stash 如果应用成功

于 2013-03-22T23:28:54.637 回答
0

我有同样的问题,但 git 有零更改的文件。原来我有一个 index.lock 文件。删除它解决了这个问题。

于 2012-01-16T15:19:11.787 回答