Git Stash Pop - Resolve Conflicts with mergetool

2019-08-29 05:07发布

问题:

So,

I've come across this suddenly, as it, in epic blundering form, rendered my application useless, but git stash pop (or apply) automatically handles the merge conflicts. When it does this, it adds both versions to the file like so:

<<<<<<< Updated [remote]
     Change from Remote
=======
     Change from Stash
>>>>>>> Stashed changes

Not knowing this at first cost me some time, as those added lines invalidated the xml file.

So, i am wondering if there is a way to enforce git stash to not auto-merge but to leave the conflicts in place so they can be resolved with the git mergetool, instead of requiring me to open each file in the editor and handle the "merte" process without the benefit of the tool designed for merge conflicts.

Thanks Jaeden "Sifo Dyas" al'Raec Ruiner

回答1:

The merge process used by git stash apply—this is the first half of git stash pop—is the same as any other merge, in terms of effect left behind:

$ git status
On branch master
nothing to commit, working tree clean
$ git log --all --decorate --oneline --graph
* f9a96c0 (HEAD -> master) conflicting changes for stash
| *   069a595 (refs/stash) WIP on master: 6fee57d add file "file"
| |\  
|/ /  
| * c466c42 index on master: 6fee57d add file "file"
|/  
* 6fee57d add file "file"
* 2353af8 initial

At this point, regardless of whether I run git stash apply or git stash pop, I get a merge conflict and then the process stops (does not do the second half of git stash pop):

$ git stash apply
Auto-merging file
CONFLICT (content): Merge conflict in file
$ git reset --hard HEAD
HEAD is now at f9a96c0 conflicting changes for stash
$ git stash pop
Auto-merging file
CONFLICT (content): Merge conflict in file
$ git stash list
stash@{0}: WIP on master: 6fee57d add file "file"

What's in the index now is the unmerged state, with all three copies of file file present:

$ git ls-files --stage
100644 239c0dc4252320079890fff28cd408eb825776f5 0   README
100644 2983120c0897fea017d8398b5ffdc5e3ef0e17ad 1   file
100644 27b6da381575999c9ba975e9df9ba6caa45e3165 2   file
100644 080f90d42698e258e3efa8059c78ebfd5fdd7bd8 3   file

and git mergetool is happy enough to run at this point:

$ git mergetool 
[snip configuration complaint - I never use git mergetool
 so it is not configured]
Merging:
file

Normal merge conflict for 'file':
  {local}: modified file
  {remote}: modified file
Hit return to start merge resolution tool (bc): 

So, i am wondering if there is a way to enforce git stash to not auto-merge but to leave the conflicts in place ...

All three versions of the file are present in the index at this point. Only two of them, --ours (usually the same as the HEAD commit version) and --theirs (the stashed-commit version, in this case), have convenient git checkout command syntax, but you can extract the merge base version too, using the :<number>:path syntax. Running git mergetool does that for you—extracts the base, left-side/local/ours, and right-side/remote/theirs versions—just before running your configured merge tool.

Hence, I'm not really sure what your question was.