Undo git stash pop that results in merge conflict
Asked Answered
L

6

951

I began making changes to my codebase, not realizing I was on an old topic branch. To transfer them, I wanted to stash them and then apply them to a new branch off of master. I used git stash pop to transfer work-in-progress changes to this new branch, forgetting that I hadn't pulled new changes into master before creating the new branch. This resulted in a bunch of merge conflicts and loss of a clean stash of my changes (since I used pop).

Once I recreate the new branch correctly, how I can I recover my stashed changes to apply them properly?

Leghorn answered 5/3, 2014 at 19:25 Comment(3)
Git is smart enough not to drop a stash if it doesn't apply cleanlyWiretap
... and knowing that your stash is still on the git stash list, be free to use git reset --hard. i.e. when you stash-poped on the wrong branch and your conflict is obvious.Crossbill
Here's a duplicate question with a far simpler resolution to stash pop conflicts with a limited number of files affected https://mcmap.net/q/21237/-how-to-specify-default-merge-strategy-on-git-stash-popDanelledanete
L
1079

As it turns out, Git is smart enough not to drop a stash if it doesn't apply cleanly. I was able to get to the desired state with the following steps:

  1. To unstage the merge conflicts: git reset HEAD . (note the trailing dot)
  2. To save the conflicted merge (just in case): git stash
  3. To return to master: git checkout master
  4. To pull latest changes: git fetch upstream; git merge upstream/master
  5. To correct my new branch: git checkout new-branch; git rebase master
  6. To apply the correct stashed changes (now 2nd on the stack): git stash apply stash@{1}
Leghorn answered 5/3, 2014 at 19:25 Comment(11)
Excellent thanks! #6 is really the answer I was looking for. Could add a git stash drop as the last step to get rid of the unwanted stash from #2.Dysphoria
#2 will not work if there are unmerged paths, it will instead output the error described here: #5483713Debonair
Not totally true--Git will keep the stash in the stash list if it failed to apply cleanly. See these docs about git stash pop: "Applying the state can fail with conflicts; in this case, it is not removed from the stash list. You need to resolve the conflicts by hand and call git stash drop manually afterwards." (git-scm.com/docs/git-stash)Triple
This doesn't work properly. :-( It undid the changes but it left a bunch of noise in my files like: <<<<<<< Updated upstream >>>>>>> Stashed changesHydrodynamic
@Hydrodynamic You might try git checkout -- . to get back to a clean state. Or git stash, if you're worried you might possibly lose something important.Leghorn
@call-me This is something I think people should actually do more often! Notice how the "Ask a question" form has a checkbox that let's you answer your own question in the same form :). This happens to me sometimes when I'm in the process of authoring a question that is stumping me, but in trying to tune the question to be good for StackOverflow, I end up figuring out the solution. This was a while ago, so I don't remember if that was the case here, but I'm guessing that's what happened.Leghorn
@Leghorn Exactly! Sometimes I come to Stackoverflow to write a question when I'm stuck because the process of making sure I write a good question often helps me answer it myself (or even just find the correct question) :)Hoem
Some shells need additional quotes for #6: git stash apply 'stash@{1}', otherwise you get the error: unknown option: -encodedCommandBeora
this answer is unnecessarily complex because it's involving branches, and they were not mentioned in the questionLaaspere
Step 1.5) git add --allHalpin
Step 4 could also be git pull origin master. Does the same, but is a bit more conciseFoulk
P
519

Luckily git stash pop does not change the stash in the case of a conflict!

So nothing, to worry about, just clean up your code and try it again.

Say your codebase was clean before, you could go back to that state with: git checkout -f
Then do the stuff you forgot, e.g. git merge missing-branch
After that just fire git stash pop again and you get the same stash, that conflicted before.

Keep in mind: The stash is safe, however, uncommitted changes in the working directory are of course not. They can get messed up.

Paperback answered 6/12, 2015 at 21:5 Comment(9)
What I understand is that you can simply cleanup and pop again, but you can't undo it. If the pop gets mixed with other uncommitted changes, then you have to clean up manually.Simasimah
This is a very simple solution and worked great for me. It assumes that you can revert everything that has changed locally (there were no changes before/after the stash was popped) which I think works for most situations. If you needed to save some additional changes that happened before realizing that this was a problem, you should be able to commit those files before forcing a checkout in most cases.Juxtapose
This was not the case for me. I called git stash pop it attempted to auto-merge, conflicted, and kept it.Scintillator
@TrevorHickey The point of this answer was that the stash stays as it is in case of a conflict, that you can call git stash pop as often you need until it ends without a conflict. So after your conflict, yes, the working directory is in mess, however, you can clean it up and call git stash pop again.Paperback
this command to undo last stash apply is very useful: git checkout -f !Zymogenesis
what does git checkout -f mean?Arvillaarvin
I was partially wrong. The stash that had some of my work was @1, not pop (not sure why exactly). However, the new files weren't included in that stash. I'm sure I did something more convoluted that messed this up.Abstain
git checkout -f branchname means "checkout branchname, and f = force, meaning I know there are uncommitted changes where I am right now, I don't care just dump everything. Since git stash pop doesn't actually "pop" if there are conflicts, I was able to do the force checkout and then git stash pop again on the correct branch. Easy peasy.Terrain
This is the correct answer. One thing that I always do after I fix all the conflicts is git stash drop to get rid of the saved stash that had the conflicts.Doubleacting
V
134

The simplest command, it works everywhere including git stash pop, git merge etc.

But careful! You'll lose all changes on untracked files. Tracked files stays intact

git reset --merge
Vickeyvicki answered 14/4, 2021 at 21:21 Comment(5)
Careful here! You'll lose all changes on untracked files.Ratafia
And you'll lose all changes on staged, tracked files too it seems.Dagney
This was exactly what I needed, since I've had changes in tracked files, so I didn't want a hard reset, and they were left in place.Lepper
This is dangerous! I ran this after running git stash pop while I already had files indexed, and I lost all of my indexed files!Abraham
TOO BAD I DIDNT RESEARCH WHAT UNTRACKED FILES WERE BEFOREHAND!!!! Good Friggin grief!!!!!!!!!!!Adrienneadrift
D
47

Instructions here are a little complicated so I'm going to offer something more straightforward:

  1. git reset HEAD --hard Abandon all changes to the current branch

  2. ... Perform intermediary work as necessary

  3. git stash pop Re-pop the stash again at a later date when you're ready

Dimitris answered 30/9, 2019 at 22:30 Comment(0)
S
36
git checkout -f

must work, if your previous state is clean.

CAUTION: Beware–you'll lose all untracked changes to your files.

Sorption answered 12/2, 2020 at 7:5 Comment(2)
Beware–you'll lose all untracked changes to your files.Madriene
well this removed some of my tracked, staged, but not committed changes!Lunetta
K
2

If you're like me and had unstaged changes that you want to preserve, you can avoid losing that work by checking out a known stable version of each individual file from the stash. Hopefully those files are different than the ones you were working on. Also, this is why we use small commits as we go, dumb dumb.

git checkout main -- <file_with_conflicts>
Kym answered 29/6, 2022 at 22:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.