为什么 git mergetool 没有显示冲突,即使合并后文件中存在冲突标记?



我在feature/my-branch上签出并运行git merge dev.添加到文件的冲突标记包括:

<<<<<<< HEAD
let foo = "foo"
let bar = "bar"
||||||| merged common ancestors
let baz = "baz"
let bar = "bar"
=======
let baz = "baz"
let qux = "qux"
>>>>>>> dev

然后我跑git mergetool.我p4mergetool设置为我的合并工具,它似乎正在工作。我的.gitconfig

[merge]
tool = p4mergetool
conflictstyle = diff3
[mergetool "p4mergetool"]
cmd = /Applications/p4merge.app/Contents/Resources/launchp4merge $PWD/$BASE $PWD/$REMOTE $PWD/$LOCAL $PWD/$MERGED
trustExitCode = true

git mergetool自动将上述冲突(工具中显示的 0 个冲突)解决为:

let foo = "foo"
let qux = "qux"

这是有道理的:即使 HEAD 和 dev 存在冲突,我们也可以看到一个分支更新了一行,另一个分支更新了另一行。因此,我们可能可以假设我们想要什么。

我的问题是:

  1. 有没有办法专门运行/配置git-mergetoolp4mergetool,以免做出此假设并且仍然显示冲突?
  2. 我是否需要运行这两个命令:

    git merge dev
    git mergetool
    

    让这个冲突自动解决这个问题? 即产生输出:

    let foo = "foo"
    let qux = "qux"
    

换句话说:是否有一个 git 合并策略/参数,我可以用来简单地运行merge命令来生成:

let foo = "foo"
let qux = "qux"

这是有道理的:即使 HEAD 和 dev 存在冲突,我们也可以看到一个分支更新了一行,另一个分支更新了另一行。因此,我们可能可以假设我们想要什么。

这是完全正确的。

  1. 有没有办法专门运行/配置git-mergetoolp4mergetool,以不做出此假设并且仍然显示冲突?

git mergetool没有做出假设,因此我们可以得出结论,p4mergetool一定是做这件事的人。 我没有p4mergetool,所以我不知道它是否有配置旋钮来改变这一点。

  1. 我需要运行这两个命令吗?

是的:Git 自己的合并有点愚蠢,只是注意到,天哪,左侧的这个更改范围相邻(触摸)或重叠右侧的其他更改范围,所以让我们称之为冲突并让用户处理它。 在这种情况下,左侧更改(从 baz 到 foo)发生在右侧更改(bar 到 qux)之前,因此两个范围在边缘接触,Git 本身声明了冲突。 如果中间有一条线,git merge会自行合并更改,而不会将其称为冲突。

(请注意,使用-X ours-X theirs将通过放弃一方的更改并仅使用另一方的更改来解决冲突。 再一次,你甚至永远不会达到让p4mergetool做自己的事情的地步。

git mergetool所做的是提取三个文件——合并基文件、左文件、本地文件或--ours文件,以及某个文件的右版本、远程版本或--theirs版本——并在这三个文件上运行其他一些非 Git 程序。 当该程序完成后,git mergetool可以信任其退出代码来决定工具本身是否正确合并了文件,或者运行一些文件比较,或者直接询问您:文件的工作树副本现在是正确的合并副本吗?

如果工作树副本现在是正确的最终结果(或者至少git mergetool相信这一点),则git mergetool运行git add,这标志着冲突已解决。1否则,冲突就会留在原地。

(我倾向于只在我的编辑器中解决合并冲突。


1如果文件的任何非零索引插槽中有任何副本,则文件将取消合并如果文件有一个副本,则合并该文件,位于插槽 0 中 - 正常的插槽编号。 除了使用 Git 的一些低级诊断式命令(真的是git ls-index --stage),你实际上看不到这些暂存槽号,但git status调用未合并的文件,并告诉你它是在所有三个槽中(UU)还是在左边或右边(分别为UDDU)。 我不确定git status对插槽 1 中的文件有何看法,该文件将代表具有重命名/重命名冲突的文件的合并基本副本。

通常我们只是使用git addgit rm来覆盖编号较高的插槽。 在极少数情况下,希望将已解决的文件还原到冲突状态,git checkout -m可以做到这一点。

相关内容

  • 没有找到相关文章