I have not commited changes in my branch. I decided to apply some of my stash. Stash applied with Auto-merging and conflicts. I realize, that stashed changes are not appropriate for me and want to unstash changes, but not loose my changes before stash. Tried to do
git stash show -p | git apply -R
but it is not work for me. I have error with message: error: patch failed, ...error: patch does not apply
How to undo stash apply and not loose my not committed changes?
To undo a git stash , use the git stash pop command. It will re-apply your stash to your working copy.
You can reapply stashed changes with the commands git stash apply and git stash pop . Both commands reapply the changes stashed in the latest stash (that is, stash@{0} ).
The problem with reverse-applying the stash is due to the merge conflicts. I'll go into more detail about that at the end if you want to dig into that, but more importantly: what to do instead?
Generally git stash apply
is a fairly safe command. It requires that the work tree match the index, and it is only expected to write to the work tree, so it would seem easy to undo.
It can be a bit of a pain when there are conflicts, though, because now it updates the index for conflict resolution. So now there are (at least) five possible states for each file:
1) Neither your local changes nor the stash applied changes to the file. Nothing to see here.
2) You applied local changes to the file, and the stash did not apply changes to the file. Your locally-changed version is in the index, and you can leave this file alone.
3) You had not applied local changes to the file, and the stash did apply changes to it. The index contains the file as modified by the stash. This looks pretty much like case 2, so knowing the difference is the first challenge (see below); once you identify a file in this state, you could revert this file to the previously-committed version (but might not want to just yet; again, see below)
git checkout HEAD -- file/with/only/stashed/changes
4) You had applied local changes to the file, and the stash applied conflicting changes to the same file. In this case, the conflict-marked version of the file is in the work tree. You can restore your version by saying
git checkout --ours -- file/with/conflicting/changes
5) You had applied local changes to the file, and the stash applied changes to the same file, but the changes are not in conflict (i.e. automatic merge resolution combined the changes successfully). This is the biggest problem case. It again looks pretty much like cases 2 and 3, and to fix it you need to separate your changes from those added by the stash.
Ok, so cases 1 and 2 take no action, and 4 is easy to find and resolve. The problems are 3 and 5. There are two ways to go about fixing this:
Building on what you were trying to do before, you could store the patch from the stash and remove the entries for files that were conflicted. Then you would resolve the conflicts with checkout --ours
, and reverse-apply the rest of the patch.
Of you could handle it file by file, using
git stash show --name-only
to see if the stash modified a file, and something like
git diff stash -- path/to/file
to see if the file contains local modifications. You'd still have to do something like reverse-patching for files that were modified in both places without conflict.
Why the patch doesn't work
The stash can't be reverse-applied as a patch because of the conflict markers. For example, maybe you started with a file
this
is
content
and the stash wants to change it to
here
is
content
but you had locally changed it to
this
file contains
content
so the stash apply
got a conflict. Well, now the working copy says
<<<<<<< Updated upstream
this
file contains
=======
here
is
>>>>>>> stashed changes
content
The reverse patch from the stash would change line 1 from here
to this
, but it doesn't find here
at line 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With