Is there a way to make Git mark a file as conflicted?
GitMergeMergetoolGit Problem Overview
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?
Git Solutions
Solution 1 - Git
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. :)
Solution 2 - Git
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.
Solution 3 - Git
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
Solution 4 - Git
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][1]), 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][2] comments, and illustrates in this [SO answer][3], 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.
[1]: http://pastebin.com/KKLtCZ35
[2]: https://stackoverflow.com/users/19563/charles-bailey
[3]: https://stackoverflow.com/questions/101752/aborting-a-merge-in-git
Solution 5 - Git
@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
<<<<<<< HEAD:README
testingtesting
hmm
>>>>>>> 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: READMENormal merge conflict for 'README': {local}: modified {remote}: modified Hit return to start merge resolution tool (emerge): caracal:
/test_clone2$ ls #merge#145962bz# README READMEREADME.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 vimdiffREADME: file does not need merging caracal:
/test_clone2$ ls #merge#145962bz# README READMEREADME.orig caracal:~/test_clone2$
Note here also that I did not commit after exiting git mergetool.
Solution 6 - Git
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