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

查看:0
本文介绍了Git合并一个文件……而且是真正的三向合并,而不仅仅是签出我们和他们的文件,这不被认为是共同的祖先的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够通过Git在单个文件上使用不同的合并策略,该策略使用典型合并处理的公共祖先提交的知识实际执行合并。不幸的是,这个问题的普遍答案是使用git checkout,它实际上并不执行真正的三向合并,而是简单地选择"我们的"或"他们的"。让我们来看一个例子。

有很多关于使用<[2-1]或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

这实际上并不执行3向合并,而只是选择文件的版本。并删除添加的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'以完成合并。

推荐答案

虽然有点迂回,但似乎最简单的操作如下所示。

  1. git merge -Xtheirs --no-commit main 这为我在这些文件上实现了我想要的3向合并,并使用‘Their’自动解决冲突行

  2. 将我想要的那些文件与他们的自动解析三向合并到/tmp目录

  3. git merge --abort退出合并

  4. git merge --no-commit main开始合并而不自动解析。自然,这些特定文件会有冲突

  5. 将合并后的版本从/tmp目录复制回repo

  6. git add <those_files>

  7. 如果任何其他文件有冲突,则需要由用户手动解决

  8. git commit -m "merged 'main' into 'newbranch'"以完成合并。或git merge --continue可以使用。

一个糟糕的Git没有提供更直接的工具来三次合并单个文件,但这也可以。

这篇关于Git合并一个文件……而且是真正的三向合并,而不仅仅是签出我们和他们的文件,这不被认为是共同的祖先的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆