2021 年 8 月更新,10 年后:不再有“递归合并”:
使用 Git 2.34(2021 年第四季度),默认 合并策略变为 ORT ("Ostensibly Recursive's Twin")
见commit 81483fe、commit 67feccd、commit 6320813、commit b36ade2、commit 4d15c85、commit 002a6df、commit 510415e、commit e80178e、commit e80178e、commit b378df7、commit e037c2e@@(8 月 4 日) 987654332@.
(由 Junio C Hamano -- gitster -- 合并于 commit aca13c2,2021 年 8 月 30 日)
签字人:Derrick Stolee
签字人:Johannes Schindelin
签字人:Elijah Newren
代码中有两个位置引用了“merge-recursive”,但也适用于“merge-ort”。
将它们更新为更一般的措辞。
使用 Git 2.34(2021 年第四季度),文档更新。
见commit 81483fe、commit 67feccd、commit 6320813、commit b36ade2、commit 4d15c85、commit 002a6df、commit 510415e、commit e80178e、commit e80178e、commit b378df7、commit e037c2e@@(8 月 4 日) 987654346@.
(由 Junio C Hamano -- gitster -- 合并于 commit aca13c2,2021 年 8 月 30 日)
merge-strategies 现在包含在其man page 中:
ort
这意味着作为recursive 的直接替代品
算法(反映在它的首字母缩写词中——“表面上
Recursive's Twin"),并且将来可能会取代它。
它修复了 recursive 策略处理的极端情况
次优,并且在大范围内明显更快
存储库——尤其是涉及到许多重命名时。
ort 策略采用与recursive 相同的所有选项。
但是,它忽略了其中三个选项:no-renames,
patience 和 diff-algorithm.
它总是以重命名运行
检测(它比recursive 处理它的速度要快得多),并且
它专门使用diff-algorithm=histogram。
还有:
在 Git 2.34(2021 年第四季度)中,使用 ort 而不是 recursive 作为默认合并策略。
参见commit f5a3c5e、commit 6a5fb96(2021 年 8 月 4 日)Elijah Newren (newren)。
(由 Junio C Hamano -- gitster -- 合并到 commit 8778fa8,2021 年 8 月 30 日)
签字人:Elijah Newren
明确ort 是现在的默认合并策略而不是recursive,包括将ort 移动到合并策略列表的前面。
git rebase 现在包含在其man page 中:
指定,-s ort。注意“我们的”和
git rebase 现在包含在其man page 中:
默认情况下,merge 命令将使用ort 合并策略
常规合并,octopus 用于章鱼合并。
可以指定一个
使用 --strategy 参数的所有合并的默认策略
调用 rebase,或者可以覆盖交互中的特定合并
使用exec 命令调用git merge 的命令列表
明确地使用 --strategy 参数。
请注意,当像这样显式调用 git merge 时,您可以利用以下事实:
标签是工作树本地参考(参考refs/rewritten/onto 将
对应于标签onto,例如),以便参考
要合并的分支。
gitfaq 现在包含在其man page 中:
默认情况下,当 Git 进行合并时,它使用称为 ort 的策略
merge-strategies 现在包含在其man page 中:
ort
这是拉取或合并一个时的默认合并策略
分支。
此策略只能使用
三向合并算法。
当有多个共同点时
可用于 3 路合并的祖先,它创建一个合并的
共同祖先的树并将其用作参考
三路合并的树。
据报道,这会导致
更少的合并冲突,而不会因完成的测试而导致错误合并
关于取自 Linux 2.6 内核的实际合并提交
发展历程。
此外,此策略可以检测和处理涉及重命名的合并。
它不使用检测到的副本。
此算法的名称是首字母缩略词
(“表面上递归的双胞胎”)并且来自于它
被写为替代以前的默认值
算法,recursive.
merge-strategies 现在包含在其man page 中:
“ort”策略可以采用以下选项:
recursive
这只能使用 3-way 合并解决两个头
算法。
当有多个共同点时
可用于 3 路合并的祖先,它创建一个
共同祖先的合并树并将其用作
三路合并的参考树。
这是
报告导致更少的合并冲突,没有
通过对实际合并提交进行的测试导致错误合并
取自 Linux 2.6 内核开发历史。
此外,这可以检测和处理涉及的合并
重命名。
它不使用检测到的副本。这是
从 Git v0.99.9k 解析两个头的默认策略
直到 v2.33.0。
“递归”策略采用与“ort”相同的选项。
然而,
'ort' 忽略了三个附加选项(未记录
以上)可能对“递归”策略有用:
耐心;;
diff-algorithm=patience 的同义词已弃用。
不重命名;;
关闭重命名检测。这将覆盖 merge.renames
配置变量。
原始答案(2011 年)
我see here the patch 在 Git1.7.2.2 的基础上,在递归合并策略中引入了耐心选项,但我在后续的任何发行说明中都没有看到它。
然而,耐心 diff 算法自 2009 年以来就已经提出,并且是 detailed here。
> grep -i patience *.c
diff.c: else if (!strcmp(arg, "--patience"))
diff.c: DIFF_XDL_SET(options, PATIENCE_DIFF);
merge-recursive.c: else if (!strcmp(s, "patience"))
merge-recursive.c: o->xdl_opts |= XDF_PATIENCE_DIFF;
合并命令应该理解这个选项...但是下面的这个函数似乎永远不会被调用(在merge-recursive.c 或任何其他*.c 文件中的任何地方都没有!):
int parse_merge_opt(struct merge_options *o, const char *s)
{
if (!s || !*s)
return -1;
if (!strcmp(s, "ours"))
o->recursive_variant = MERGE_RECURSIVE_OURS;
else if (!strcmp(s, "theirs"))
o->recursive_variant = MERGE_RECURSIVE_THEIRS;
else if (!strcmp(s, "subtree"))
o->subtree_shift = "";
else if (!prefixcmp(s, "subtree="))
o->subtree_shift = s + strlen("subtree=");
else if (!strcmp(s, "patience"))
o->xdl_opts |= XDF_PATIENCE_DIFF;
else if (!strcmp(s, "ignore-space-change"))
o->xdl_opts |= XDF_IGNORE_WHITESPACE_CHANGE;
else if (!strcmp(s, "ignore-all-space"))
o->xdl_opts |= XDF_IGNORE_WHITESPACE;
else if (!strcmp(s, "ignore-space-at-eol"))
o->xdl_opts |= XDF_IGNORE_WHITESPACE_AT_EOL;
else if (!strcmp(s, "renormalize"))
o->renormalize = 1;
else if (!strcmp(s, "no-renormalize"))
o->renormalize = 0;
else if (!prefixcmp(s, "rename-threshold=")) {
const char *score = s + strlen("rename-threshold=");
if ((o->rename_score = parse_rename_score(&score)) == -1 || *score != 0)
return -1;
}
else
return -1;
return 0;
}
“未知选项”错误消息仅由 git.c 中的 handle_options 函数打印。
XDF_PATIENCE_DIFF 在 git 源代码 (1.7.4) 中没有显示其他任何地方......所以是的,我不知道如何为合并实现这一点。