开发者

Is there a way to make Git mark a file as conflicted?

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 m开发者_Go百科erge tool?


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. :)


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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜