0

我已签出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"
4

1 回答 1

0

这是有道理的:即使 HEAD 和 dev 发生冲突,我们也可以看到一个分支更新了一行,而另一个分支更新了另一行。所以我们大概可以假设我们想要什么。

这是完全正确的。

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

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

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

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

(请注意,使用-X oursor-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 add或可能git rm覆盖较高编号的插槽。在想要将已解决的文件恢复到冲突状态的极少数情况下,git checkout -m可以这样做。

于 2020-04-08T20:43:52.027 回答