2

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

JaedenRuiner
  • 329
  • 4
  • 18
  • hm, when I have a conflict in stash pop, mergetool seems to work. – orion elenzil Jan 05 '22 at 19:03
  • `echo 'hello' > file ; git commit -m "commit A" ; echo 'world' >> file ; git stash ; echo 'there' >> file ; git commit -m "commit B" ; git stash pop` at this point git tells me there's a conflict. `git mergetool` runs with the conflict as I'd expect. Once the conflict is resolved, things are in kind of a funny state tho. `git status` shows `file` is modified, but `git diff` shows no changes. But then `git commit -m 'commit C' ; git diff HEAD^ HEAD` shows the expected difference between B and my resolution of the conflict. – orion elenzil Jan 05 '22 at 19:19

1 Answers1

2

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.

torek
  • 448,244
  • 59
  • 642
  • 775
  • Agreed. This is pretty standard revision control system behaviour. – Mort Sep 21 '17 at 02:41
  • well, when i run git merge, say of Revision_5 branch and develop branch, and suppose there is a conflict. it will attempt to auto merge. If it can great, but if not, it doesn't add those annoying tags of theirs and ours in the file, it simply leaves them both and the active branch in the command line become (develop|MERGING). Are you saying that even though that doesn't happen with git stash apply, and it simply merges both version into the single file, git mergetool will still function and allow me to repair the merge? – JaedenRuiner Sep 22 '17 at 14:26
  • In *all* merge-conflict cases, Git is supposed to leave the work-tree file marked up like this. The originals are all stored in the index, so that instead of the usual three active versions of a file (HEAD, index stage 0, work-tree) you wind up with *five* active versions (HEAD; index stages 1, 2, 3; work-tree). Running `git add` or `git rm` on one of the paths reduces the three high-order index stage copies back down to the single stage-0 index copy, by taking the work-tree version. The `git mergetool` script runs the `git add` for you if it believe the tool it ran succeeded. – torek Sep 22 '17 at 14:34
  • Whatever it is that your prompt uses to decide to set this "|MERGING" flag isn't being set (if you're using the distributed `git-prompt.sh`, that's because there's no `.git/MERGE_HEAD` file), but yes, `git mergetool` will still run. Probably the prompt-setter should be checking for non-zero stage numbers in the index, too. – torek Sep 22 '17 at 14:41