有没有一种方法可以让Git将文件标记为冲突?

59

可能会提交包含冲突数据的文件。 是否有一种方式将这些文件重新标记为有冲突,以便运行git mergetool将生成必要的文件并运行合并工具?

6个回答

47
如果索引已经处于冲突状态,只需使用--conflict=merge标志签出文件即可:
git checkout --conflict=merge file

如果索引是干净的,因为未解决的文件已经[错误地]添加了,只需在检出之前重置它:

如果索引因为误添加未解决的文件而干净,请在检出之前先重置它:
git reset file
git checkout --conflict=merge file

这将允许您正常恢复冲突解决(例如,git mergetool)。

注意:根据@fourpastmidnight的请求,将评论晋升为@jakub-narębski的答案。 :)


1
谢谢@Gingi。我收藏了这个书签,因为我知道我会再次需要它,今天就是那一天。如承诺所述,+1!! - fourpastmidnight

33
你可以使用 git checkout --conflict=merge -- file 命令获取带有冲突标记的文件内容,但是如果你已经通过 git add file(或者GUI操作)清理了索引,它将无法工作。 git update-index --unresolve 命令可以解决这个问题,但这种方法并不可靠,并且不能很好地支持 git-mergetool。我认为它所恢复的状态不足以满足需要。
你可能需要重新执行合并操作,或者使用 git update-index --cacheinfo 手动设置版本号来解决冲突。git-stash 可以帮助你保留正确解决的冲突。

2
它有什么不可靠和不专业的地方? - Christian Neverdal
1
git update-index --unresolve 是在“古老”的时代创建的,允许在(意外的)git add 确认冲突解决后恢复 git diff --ours 等操作。它将 HEAD 版本(未自动解决冲突的版本)放入第二阶段,将 MERGE_HEAD 版本放入第三阶段,并不会将任何内容放入第一阶段,即祖先版本。 - Jakub Narębski
1
如果有人提交了一些冲突的合并和实际工作,我不明白这是“Git如何轻松破坏存储库”的情况。Git已经保存了提交者所请求的状态的逐字副本,无论该状态多么疯狂。最终,我可能会重新执行合并,然后使用重新执行的合并和这个混乱的合并提交进行git diff那个差异希望包含最初打算提交的变更集,因此您不需要手动重新创建所有这些工作。 - Mikko Rantalainen
9
如果索引是干净的,因为未解决的文件被错误地添加了,你可以重置它:git reset file; git checkout --conflict=merge file - Gingi
1
@Gingi 太棒了!!正是我一直在寻找的。我已经想知道如何做这个很长一段时间了。你应该把它作为一个答案--我会点赞的! - fourpastmidnight
显示剩余4条评论

7
最优雅的解决方案是从一开始就避免这个问题:
git config --global mergetool.[tool].cmd [命令行调用]
git config --global mergetool.[tool].trustExitCode false

2
是的。这将导致Git每次都询问文件是否成功合并,而不是依赖于合并工具本身真实地报告成功或失败。 - Christian Neverdal
1
那是否意味着除非你回答“是”,否则它不会“git add”这些文件?我还有“mergetool.prompt = false”,这会影响吗? - Superole
没错。我认为mergetool.prompt必须是true。 - Christian Neverdal

2
据我所知,如果文件中仍然存在冲突标记,您将无法提交。但这并不完全正确:
原帖提到您可以这样做(我在此复制他的pastbin),但这还不足以再次触发合并工具。
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$

根据Charles BaileySO回答中的评论和示例,mergetool被查询是因为在索引中有3个相同文件的实例。

对于冲突中的未合并文件,git在索引中提供了文件的公共基础、本地和远程版本。(这是它们被git mergetool用于三路比较工具的读取位置。)您可以使用git show查看它们:

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

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

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

git add命令(包括冲突标记)会自动移除其中两个,确保mergetool不会再次被调用。


当然可以。只需执行“git add <文件名>”命令即可去除标记,然后您就可以自由地提交了。 - Christian Neverdal
@Christian:很有趣(我已经修改了答案以反映它),但是git mergetool会检测到它并重新触发合并吗? - VonC
如果一个文件在索引中有多个条目,而不是通常的一个条目,git 就会确定该文件存在冲突。为了帮助用户解决冲突,git 在工作树版本中放置了冲突标记,但这并不是 git 计算文件未合并的方式。调用 git add 命令告诉 git 将工作树版本的文件添加到索引中,并“删除所有其他条目”。在执行 git add 命令之后,由于现在只有一个索引条目,因此该文件不再是“未解决的”,因此您可以提交它。 - CB Bailey
@Christian:在查尔斯的评论后,我完成了我的回答。 - VonC
1
@CharlesBailey 有没有可能在索引中为文件添加额外的条目,以故意导致Git将文件解释为冲突?我认为,在运行自定义合并驱动程序后,在索引中制造冲突版本会很好。 - Mikko Rantalainen

0

@VonC:我一开始没有创建帐户(现在已经创建了),所以我无法发表评论。 调用git mergetool无法检测到它,似乎:

自动合并README
冲突(内容):README中的合并冲突
自动合并失败;解决冲突,然后提交结果。
lynx:~/test_clone$ ls
README
lynx:~/test_clone$ git add README
lynx:~/test_clone$ git commit -a
创建提交46ee062:它有效!
lynx:~/test_clone$ ls
README
lynx:~/test_clone$ cat README
>>>>>> 881d60f5f738bc5716f5c9a9384e262b535717fd:README
lynx:~/test_clone$ git mergetool
合并工具候选项:opendiff emerge vimdiff
没有需要合并的文件
lynx:~/test_clone$

git mergetool可以接受一个文件名,但那也不起作用:

自动合并 README 冲突 (内容): 合并冲突在 README 中 自动合并失败;修复冲突,然后提交结果。 caracal:~/test_clone2$ git mergetool 合并工具候选者 : opendiff emerge vimdiff 正在合并文件:README
'Readme' 的普通合并冲突: {本地的}: 修改了 {远程的}: 修改了 按回车键启动合并解决工具 (emerge): caracal:~/test_clone2$ ls #*merge*#145962bz# README README~ README.orig caracal:~/test_clone2$ git mergetool 合并工具候选者 : opendiff emerge vimdiff 没有需要合并的文件 caracal:~/test_clone2$ git mergetool README 合并工具候选者 : opendiff emerge vimdiff
README:文件不需要合并 caracal:~/test_clone2$ ls #*merge*#145962bz# README README~ README.orig caracal:~/test_clone2$

需要注意的是,在退出 git mergetool 后我没有进行提交。


在查看了Charles的评论后,我刚刚完成了我的回答。 - VonC
s/lynx:.*$/\n#/g - user1133275

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接