Question

It's possible to commit files that contains conflict data. Is there a way to mark these files as conflicted again, so that running git mergetool will generate the necessary files and run the merge tool?

Was it helpful?

Solution

You can get contents of file with conflict markers using git checkout --conflict=merge -- file, but if you have cleaned up index by using git add file (or if GUI did that for you) it wouldn't work.

There is git update-index --unresolve, but it is hacky, and does not work very reliably. I think the state it restores would be not enough for git-mergetool.

You would probably have to redo merge, or use git update-index --cacheinfo to manually set stages version... git-stash can help you preserve correctly resolved conflicts.

OTHER TIPS

If the index is already in a conflict state, simply check out the file with the --conflict=merge flag:

git checkout --conflict=merge file

If the index is clean because the unresolved file has been [erroneously] added, just reset it before checking it out:

git reset file
git checkout --conflict=merge file

This will allow you to resume conflict resolution normally (e.g., git mergetool).

NOTE: Promoting a comment to @jakub-narębski's answer into its own answer by request from @fourpastmidnight. :)

The most elegant solution would be to prevent this problem from the very beginning:
git config --global mergetool.[tool].cmd [command-line call]
git config --global mergetool.[tool].trustExitCode false

As far as I know, you won't be able to commit while a file still contain conflict markers in it.... which is not exactly true:
The OP mentions that you can (I copy here his pastbin), but that won't be enough for the mergetool to be trigger again:

Auto-merged README
CONFLICT (content): Merge conflict in README
Automatic merge failed; fix conflicts and then commit the result.
lynx:~/test_clone$ ls
README
lynx:~/test_clone$ git add README
lynx:~/test_clone$ git commit -a
Created commit 46ee062: It works!
lynx:~/test_clone$ ls
README
lynx:~/test_clone$ cat README
<<<<<<< HEAD:README
testingtesting
=======
hmm
>>>>>>> 881d60f5f738bc5716f5c9a9384e262b535717fd:README
lynx:~/test_clone$

As Charles Bailey comments, and illustrates in this SO answer, the mergetool is queried because there are 3 instances of the same file in the index:

For an unmerged file in a conflict git makes available the common base, local and remote versions of the file in the index. (This is where they are read from for use in a 3-way diff tool by git mergetool.) You can use git show to view them:

# common base:
git show :1:afile.txt

# 'ours'
git show :2:afile.txt

# 'theirs'
git show :3:afile.txt

git add (with whatever content, including conflict markers) will automatically removes 2 of them, ensuring the mergetool won't be called again.

@VonC: I did not create an account at first (I have now), so I could not post a comment. Invoking git mergetool does not detect it, it seems:

Auto-merged README
CONFLICT (content): Merge conflict in README
Automatic merge failed; fix conflicts and then commit the result.
lynx:~/test_clone$ ls
README
lynx:~/test_clone$ git add README
lynx:~/test_clone$ git commit -a
Created commit 46ee062: It works!
lynx:~/test_clone$ ls
README
lynx:~/test_clone$ cat README
>>>>>> 881d60f5f738bc5716f5c9a9384e262b535717fd:README
lynx:~/test_clone$ git mergetool
merge tool candidates:  opendiff emerge vimdiff
No files need merging
lynx:~/test_clone$

git mergetool can accept a file name, but that does not work either:

Auto-merged README
CONFLICT (content): Merge conflict in README
Automatic merge failed; fix conflicts and then commit the result.
caracal:~/test_clone2$ git mergetool
merge tool candidates:  opendiff emerge vimdiff
Merging the files: README

Normal merge conflict for 'README':
  {local}: modified
  {remote}: modified
Hit return to start merge resolution tool (emerge): 
caracal:~/test_clone2$ ls
#*merge*#145962bz#  README  README~  README.orig
caracal:~/test_clone2$ git mergetool
merge tool candidates:  opendiff emerge vimdiff
No files need merging
caracal:~/test_clone2$ git mergetool README
merge tool candidates:  opendiff emerge vimdiff

README: file does not need merging
caracal:~/test_clone2$ ls
#*merge*#145962bz#  README  README~  README.orig
caracal:~/test_clone2$ 

Note here also that I did not commit after exiting git mergetool.

Please use git update-index --unresolve

Since git 1.7 it uses resolve-undo info from the index to restore all 3 stages (1:base, 2:ours, 3:theirs): https://github.com/git/git/commit/8aa38563b22c84b06ea1fff9638cc1f44fda726f

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top