你什么时候会使用不同的git合并策略?
从git-merge的手册页中,可以使用一些合并策略。
解决方案 - 这只能使用3路合并算法解决两个头(即当前分支和另一个分支)。 它试图仔细检测交叉融合歧义,并且通常被认为是安全和快速的。
递归 - 这只能使用3路合并算法来解析两个头。 当有多个可用于三路合并的共同祖先时,它将创建一个共同祖先的合并树并将其用作三路合并的参考树。 据报道,这会导致更少的合并冲突,而不会导致通过从Linux 2.6内核开发历史中取得的实际合并提交进行的测试错误合并。 此外,这可以检测并处理涉及重命名的合并。 这是拉取或合并一个分支时的默认合并策略。
章鱼 - 这解决了两个以上的情况,但拒绝做复杂的合并,需要手动解决。 它主要用于将主题分支主题捆绑在一起。 这是拉动或合并多个分支时的默认合并策略。
我们的 - 这解决了任何数量的头,但合并的结果总是当前的分支头。 它是用来取代侧枝的旧发展历史。
子树 - 这是一个修改后的递归策略。 合并树A和B时,如果B对应于A的子树,则首先调整B以匹配A的树结构,而不是读取处于同一级别的树。 这种调整也对共同的祖先树进行。
何时应该指定与默认值不同的内容? 哪些场景最适合?
我不熟悉解决方案,但我已经使用了其他方法:
递归
递归是非快进合并的默认值。 我们都熟悉那个。
章鱼
当我有几棵需要合并的树时,我使用了章鱼。 您在大型项目中看到了这一点,许多分支机构都有独立开发,并且已经准备好将它们合并为一个头。
章鱼分支在一次提交中合并多个头,只要它可以干净地完成。
为了说明,假设你有一个有主人的项目,然后有三个分支合并(称为a,b和c)。
一系列递归合并看起来像这样(请注意,第一次合并是快进,因为我没有强制递归):
但是,单个章鱼合并看起来像这样:
commit ae632e99ba0ccd0e9e06d09e8647659220d043b9
Merge: f51262e... c9ce629... aa0f25d...
我们的
我的==我想拉另一个头,但扔掉头引入的所有变化。
这保持了分支的历史,而没有任何分支的影响。
(阅读:它甚至没有看到这些分支之间的变化,分支只是合并,并没有对文件做任何事情,如果你想在其他分支合并,每次有问题“我们的文件版本或他们的版本“你可以使用git merge -X ours
)
子树
当您想要将另一个项目合并到当前项目的子目录中时,子树很有用。 当你有一个你不想作为子模块包含的库时很有用。
实际上,如果你想放弃分支带来的变化,但是让分支保持在历史中,并且子树(如果你将独立项目合并到超级项目的子目录中),那么你希望选择的唯一两种策略就是我们的选择(例如'git-gui'in' git'仓库)。
章鱼合并在合并两个以上分支时自动使用。 这里的解决主要是出于历史原因,以及何时受到递归合并策略角落案例的影响。
“解决”与“递归”合并策略
递归是当前默认的双头策略,但经过一番搜索后,我终于找到了关于“解决方案”合并策略的一些信息。
从O'Reilly着作版本控制与Git(亚马逊)(释义):
最初,“解决”是Git合并的默认策略。
在纵横交错的情况下,如果存在多个可能的合并基础,则解决策略的工作方式如下:选择可能的合并基础之一,并希望获得最佳结果。 这实际上并不像听起来那么糟糕。 通常情况下,用户一直在处理代码的不同部分。 在这种情况下,Git会检测到它正在重新构建已经存在的一些更改,并跳过重复的更改,从而避免冲突。 或者,如果这些细微变化确实会引起冲突,至少冲突对于开发人员来说应该很容易处理。
我已成功地合并树使用“解决”,失败与默认递归策略。 我变得fatal: git write-tree failed to write a tree
错误,并且感谢这篇博文(镜像),我尝试了“-s resolve”,它工作正常。 我仍然不确定为什么......但我认为这是因为我在两棵树上都有重复的更改,并且正确解决了它们的“跳过”。
上一篇: When would you use the different git merge strategies?
下一篇: Git commit style: All changed files at once or one at a time?