Git合并一个文件……而且是真正的三向合并,而不仅仅是签出我们和他们的文件,这不被认为是共同的祖先 [英] git merge a single file....and a TRUE 3-WAY MERGE, not just a checkout of ours vs theirs which doesn't consider common ancestor
问题描述
我希望能够通过Git在单个文件上使用不同的合并策略,该策略使用典型合并处理的公共祖先提交的知识实际执行合并。不幸的是,这个问题的普遍答案是使用git checkout
,它实际上并不执行真正的三向合并,而是简单地选择"我们的"或"他们的"。让我们来看一个例子。
git checkout --theirs
合并单个文件的错误信息在SO和博客上传播。这只会有效地执行一个简单的补丁,选择其中一个。这不是真正的三向合并,使用共同的祖先作为基本文件!未选择的一方的非冲突更改将丢失!
我在我的repo的根目录下有一个配置文件(config.toml),它需要通过选择"他们的"(有时根据其他条件选择"我们的")进行自动解析。从‘Main’分支开始,第一个条目成为公共提交。
path = "some/path"
description = "this is a description"
owner = "username"
foo = "bar"
log = "some stuff"
然后我签出此提交的一个新分支,名为‘newBranch’,并添加一行并更改日志行。
path = "some/path"
description = "this is a description"
owner = "username"
new = "line"
foo = "bar"
log = "new branch"
然后我返回到我开始的‘Main’分支,只更改日志行。
path = "some/path"
description = "this is a description"
owner = "username"
foo = "bar"
log = "main updates"
我又回到了‘新分支’分支。如果我执行git merge -Xtheirs main
,一切都会按您的预期运行。
path = "some/path"
description = "this is a description"
owner = "username"
new = "line"
foo = "bar"
log = "main updates"
唯一真正的冲突是日志行,它是通过选择‘Theys’(他们的)(来自‘Main’分支)自动解决的。添加的行new = "line"
在已知分支分支所在的公共祖先提交的情况下被保留。
但这显然适用于所有文件,我不能让每个冲突都以这种方式自动解决。我希望它只应用于这一个文件。
此问题的常见答案是使用
git checkout --theirs main -- config.toml
new = "line"
。同样,git checkout --patch main -- config.toml
也不使用公共祖先提交的知识,并再次将new = "line"
条目视为应该删除的内容。
我见过将.gitattributes
作为提供每文件合并策略的解决方案的建议,但我还没有幸运地将其付诸实践。而且看起来有点僵化,没有能力在合并时选择我想要的是他们的还是我们的。
有没有办法对考虑共同祖先的单个文件执行真正的三向合并?我有点惊讶,没有更明显的答案。谢谢!
更新:我想一种解决方案是将公共祖先、文件的"主"版本和"新分支"签出到一个临时目录中。然后在提交之前,使用‘Diff3’手动执行三向合并,覆盖‘newBranch’版本。 UPDATE2:似乎我不能使用‘Diff3’自动解析,所以这真的不是一个可行的选项。似乎最简单的做法是首先将我想要合并的单个文件git merge -Xtheirs --no-commit main
复制到一个临时目录中。git merge --abort
以退出。git merge --no-commit main
执行合并。自然会与这些文件发生冲突。将这些单独的文件复制回回购中。git add <those_files>
。到目前为止,我完全是通过编程完成这项工作的。如果有其他文件需要解析,则由用户手动完成。否则git commit -m "merged 'main' into 'newbranch'
以完成合并。
推荐答案
虽然有点迂回,但似乎最简单的操作如下所示。
git merge -Xtheirs --no-commit main
这为我在这些文件上实现了我想要的3向合并,并使用‘Their’自动解决冲突行将我想要的那些文件与他们的自动解析三向合并到/tmp目录
git merge --abort
退出合并git merge --no-commit main
开始合并而不自动解析。自然,这些特定文件会有冲突将合并后的版本从/tmp目录复制回repo
git add <those_files>
如果任何其他文件有冲突,则需要由用户手动解决
git commit -m "merged 'main' into 'newbranch'"
以完成合并。或git merge --continue
可以使用。
一个糟糕的Git没有提供更直接的工具来三次合并单个文件,但这也可以。
这篇关于Git合并一个文件……而且是真正的三向合并,而不仅仅是签出我们和他们的文件,这不被认为是共同的祖先的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!