Git stash: “Cannot apply to a dirty working tree, please stage your changes”

后端 未结 11 1651
青春惊慌失措
青春惊慌失措 2020-12-12 09:04

I am trying to apply changes I stashed earlier with git stash pop and get the message:

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


        
相关标签:
11条回答
  • 2020-12-12 09:04

    Mathias's solution is definitely the closest to a git stash pop --force (and really, c'mon Git devs, let's get this option already!)

    However, if you want to do the same thing using only git commands, you can:

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

    In other words, make a commit (which we will never push) of your current changes. Now that your workspace is clean, pop your stash. Now, commit the stash changes as an amendment to your previous commit. Having done that you now have both sets of changes combined in a single commit ("Fixme"); just reset (--soft NOT --hard so nothing is actually lost) your checkout to "one before that commit", and now you have both sets of changes, completely uncommitted.

    **EDIT**

    I just realized it's actually even easier; you can completely skip step 3, so ...

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

    (Commit current changes, pop off the stashed changes, reset that first commit to get both sets of changes combined in an uncommitted state.)

    0 讨论(0)
  • 2020-12-12 09:06

    I had the same problem but git had zero changed files. Turns out I had a index.lock file that was lying around. Deleting it solved the problem.

    0 讨论(0)
  • 2020-12-12 09:10

    Either clean your working directory with git reset, commit the changes, or, if you want to stash the current changes, try:

    $ git stash save "description of current changes"
    $ git stash pop stash@{1}
    

    This will stash the current changes, and then pop the second stash from the stash stack.

    0 讨论(0)
  • 2020-12-12 09:13

    When I have to apply stashed changes to a dirty working copy, e.g. pop more than one changeset from the stash, I use the following:

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

    Basically it

    1. creates a patch
    2. pipes that to the apply command
    3. if there are any conflicts they will need to be resolved via 3-way merge
    4. if apply (or merge) succeeded it drops the just applied stash item...

    I wonder why there is no -f (force) option for git stash pop which should exactly behave like the one-liner above.

    In the meantime you might want to add this one-liner as a git alias:

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

    Thanks to @SamHasler for pointing out the -3 parameter which allows to resolve conflicts directly via 3-way merge.

    0 讨论(0)
  • 2020-12-12 09:19

    You can apply a stash to a "dirty" tree by doing a git add to stage any changes you've made, thus cleaning up the tree. Then you can git stash pop and apply the stashed changes, no problem.

    0 讨论(0)
  • 2020-12-12 09:20

    I also found Mathias Leppich's solution to work great so I added an alias for it to my global .gitconfig

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

    Now I can just type

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

    which works great for me.

    (Your mileage may vary on this long alias name. But I like a dose of verbosity when it comes with bash completion.)

    0 讨论(0)
提交回复
热议问题