在工作分支开发并且测试完成之后,对于如何将工作分支合并回主线分支,团队通常会有一些可选方式。你们团队使用什么样的合并策略?在本文中我们会分别介绍几种合并策略,以及对应的简单评述。以便在本文结束时,您可以根据团队情况选择合适的合并策略。

Git合并策略

每当我们尝试整合两个分支时,就需要用到合并操作。Git会尝试通过两个分支的commit指针,分别向前追溯,找到这两个commit指针在历史上最近的一次共同提交点。Git有几种不同的方法用来寻找这个共同提交,而这些方法就是所谓的“合并策略”。一旦Git找到这个共同提交就会创建一个新的“合并提交”,这个合并提交中的内容就是对于两个分支之间不同内容的合并。事实上一个合并提交本身也是一个不同的提交,只不过这次提交来自于两个父级提交。

git merge命令在进行合并操作时,如果没有被显式指定合并策略,则会自动选择一种合并方式。在执行git mergegit pull命令时,可以传递一个 -s (也就是 strategy 的缩写) 选项。跟在-s选项之后的是指定的合并策略名称。如果没有指定的话,Git会根据合并操作所涉及的分支自行选择一个最合适的合并策略。下面是关于合并策略选项的可选值描述。

Recursive

git merge -s recursive branch1 branch2

递归合并策略在两个分支的顶端开展操作。递归策略是使用pull或者merge命令合并分支时的默认合并策略。此外这种合并策略可以在合并过程中处理重命名操作,但不能完美处理复制出的文件。

Resolve

git merge -s resolve branch1 branch2

该策略使用三路合并算法来解析两个分支之间的差异。这种方法会小心的检测出现在十字交叉合并状况中产生的歧义,该方法通常被认为是安全且高效的。

Octopus

git merge -s octopus branch1 branch2 branch3 branchN

当需要合并的分支多于两个时,octopus策略就称为合并时的默认策略。在合并过程中一旦出现需要手动解决的冲突,octopus合并就会拒绝合并。这种策略通常用于合并一堆功能类似的开发分支。

Ours

git merge -s ours branch1 branch2 branchN

ours策略可以用于合并N个不同分支。合并的结果总是以当前分支的HEAD指针为基准。策略名称 “ours” 字面上也暗示着合并过程中会忽略来自于其他分支的改动。该策略用于合并内容相似的开发分支,忽略被合并分支的内容,仅保留合并记录。

Subtree

git merge -s subtree branchA branchB

该策略是基于recursive策略的一种扩展策略。当合并A和B分支时,如果B分支是A分支的一个subtree,B分支需要首先更新子树B的更新记录,并将其反映在分支A中。这一系列更新也是基于A和B的共同祖先进行判断。

Git合并策略的种类

显式合并

显式合并是默认的合并类型。所谓“显式”意味着在合并时会特意创建一个合并提交。创建的合并提交会显式在提交历史中,并且明确显示合并被执行的时间点。合并提交的内容也同样是显式的,因为通过合并提交产生的提交历史,可以明确看出哪些提交内容来自于哪个分支的提交。有些团队会避免使用显式合并,因为有争论认为合并提交会向提交历史中增加过多的“噪音”。

通过rebase 或者 fast-forward实现隐式合并

Recursive合并策略的相关选项

在上面介绍过的recursive策略中,其自身还有一组操作选项

ours

不要将该选项与ours合并策略混淆。ours合并策略会忽略合并分支的一切改动,而recursive策略中的ours选项只会在合并过程中发生冲突的状况下忽略合并分支的改动,而无条件的自动保留目标分支的改动。当合并过程中没有冲突发生时,来自于合并分支的改动仍然会自动合并进目标分支。

theirs

与ours选项相反。"theirs"选项会在冲突发生时无条件选择使用合并分支的内容,放弃目标分支的改动。

patience

patience选择会花更多的时间对一些代码行进行更精准的合并操作,以避免产生合并之后的错行漏行之类的现象发生。

diff-algorithim
ignore-*

    ignore-space-change
    ignore-all-space
    ignore-space-at-eol
    ignore-cr-at-eol

上面的选项是针对如何处理空白字符的策略。

renormalize

在解析三向合并时,这将运行虚拟签出并检入文件的所有三个阶段。

no-normalize

禁用renormalize选项。这会覆盖merge.renormalize配置变量。

no-renames

关闭重命名检测。这会覆盖merge.renames配置变量。

find-renames=n

打开重命名检测,可选择设置相似性阈值。这是默认值。这会覆盖 merge.renames 配置变量。

subtree

此选项是_子树_策略的更高级形式,其中策略猜测两个树在合并时必须如何移位以相互匹配。相反,指定的路径是前缀(或从头开始剥离),以使两个树的形状匹配。


swearer23
1 声望1 粉丝