Aborting a stash pop in Git

后端 未结 14 2043
鱼传尺愫
鱼传尺愫 2020-12-22 17:47

I popped a stash and there was a merge conflict. Unlike the question that is listed as a duplicate, I already had some uncommitted changes in the directory which I wanted to

相关标签:
14条回答
  • 2020-12-22 17:50

    I could reproduce clean git stash pop on "dirty" directory, with uncommitted changes, but not yet pop that generates a merge conflict.

    If on merge conflict the stash you tried to apply didn't disappear, you can try to examine git show stash@{0} (optionally with --ours or --theirs) and compare with git statis and git diff HEAD. You should be able to see which changes came from applying a stash.

    0 讨论(0)
  • 2020-12-22 17:51

    If you don't have to worry about any other changes you made and you just want to go back to the last commit, then you can do:

    git reset .
    git checkout .
    git clean -f
    
    0 讨论(0)
  • 2020-12-22 17:51

    OK, I think I have managed to find a work-flow that will get you back to where you need to be (as if you had not done the pop).

    TAKE A BACKUP BEFOREHAND!! I don't know whether this will work for you, so copy your whole repo just in case it doesn't work.

    1) Fix the merge problems and fix all the conflict by selecting all the changes that come from the patch (in tortoisemerge, this shows up as one.REMOETE (theirs)).

    git mergetool
    

    2) Commit these changes (they will already be added via the mergetool command). Give it a commit message of "merge" or something you remember.

    git commit -m "merge"
    

    3) Now you will still have your local unstaged changes that you started originally, with a new commit from the patch (we can get rid of this later). Now commit your unstaged changes

    git add .
    git add -u .
    git commit -m "local changes"
    

    4) Reverse the patch. This can be done with the following command:

    git stash show -p | git apply -R
    

    5) Commit these changes:

    git commit -a -m "reversed patch"
    

    6) Get rid of the patch/unpatch commits

    git rebase -i HEAD^^^
    

    from this, remove the two lines with 'merge' and 'reversed patch' in it.

    7) Get your unstanged changes back and undo the 'local changes' commit

    git reset HEAD^
    

    I've run through it with a simple example and it gets you back to where you want to be - directly before the stash was popped, with your local changes and with the stash still being available to pop.

    0 讨论(0)
  • 2020-12-22 17:57

    Ok, I think I have worked out "git stash unapply". It's more complex than git apply --reverse because you need reverse merging action in case there was any merging done by the git stash apply.

    The reverse merge requires that all current changes be pushed into the index:

    • git add -u

    Then invert the merge-recursive that was done by git stash apply:

    • git merge-recursive stash@{0}: -- $(git write-tree) stash@{0}^1

    Now you will be left with just the non-stash changes. They will be in the index. You can use git reset to unstage your changes if you like.

    Given that your original git stash apply failed I assume the reverse might also fail since some of the things it wants to undo did not get done.

    Here's an example showing how the working copy (via git status) ends up clean again:

     $ git status
    # On branch trunk
    nothing to commit (working directory clean)
     $ git stash apply
    Auto-merging foo.c
    # On branch trunk
    # 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:   foo.c
    #
    no changes added to commit (use "git add" and/or "git commit -a")
     $ git add -u
     $ git merge-recursive stash@{0}: -- $(git write-tree) stash@{0}^1
    Auto-merging foo.c
     $ git status
    # On branch trunk
    nothing to commit (working directory clean)
    
    0 讨论(0)
  • 2020-12-22 17:57

    Simple one-liner

    I have always used

    git reset --merge

    I can't remember it ever failing.

    0 讨论(0)
  • 2020-12-22 18:03

    I'm posting here hoping that others my find my answer helpful. I had a similar problem when I tried to do a stash pop on a different branch than the one I had stashed from. On my case I had no files that were uncommitted or in the index but still got into the merge conflicts case (same case as @pid). As others pointed out previously, the failed git stash pop did indeed retain my stash, then A quick git reset HEAD plus going back to my original branch and doing the stash from there did resolve my problem.

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