【问题标题】:Git merge using recursive strategy and patience option使用递归策略和耐心选项的 Git 合并
【发布时间】:2021-09-01 06:35:46
【问题描述】:

如何使用递归策略提供的耐心选项将分支与git合并?我在用着 git 版本 1.7.3.1.msysgit.0

甚至文档也不一致,而且,与实际命令输出的内容不同。

Docs say:

git 合并 [-s <strategy>] [-X <strategy-option>] <commit>

以及进一步的文字:

-X<option>

(没有空格)

命令的输出显示:

-X, --strategy-option <option=value>

option for selected merge strategy

所以我尝试了几个版本,结果如​​下:

$ git merge -s recursive -Xpatience sourceBranch
fatal: Unknown option for merge-recursive: -Xpatience

$ git merge -X patience sourceBranch
fatal: Unknown option for merge-recursive: -Xpatience

$ git merge -Xpatience sourceBranch
fatal: Unknown option for merge-recursive: -Xpatience

$ git merge --strategy-option patience sourceBranch
fatal: Unknown option for merge-recursive: -Xpatience

$ git merge -X option=patience sourceBranch
fatal: Unknown option for merge-recursive: -Xoption=patience

$ git merge --strategy-option option=patience sourceBranch
fatal: Unknown option for merge-recursive: -Xoption=patience

$ git merge option=patience sourceBranch
fatal: 'option=patience' does not point to a commit

$ git merge -X option=patience sourceBranch
fatal: Unknown option for merge-recursive: -Xoption=patience

看起来好像该选项没有实现......

【问题讨论】:

    标签: git


    【解决方案1】:

    git merge-recursive--patience 选项是在提交 58a1ece478c6038a7eb0b6e494d563bd5e6d5978 中引入的。您可以在git.git 的克隆中找到哪些版本包含此更改,git tag --contains 58a1ece478

    v1.7.4
    v1.7.4-rc0
    v1.7.4-rc1
    v1.7.4-rc2
    v1.7.4-rc3
    v1.7.4.1
    

    所以我怀疑您只是在使用稍微太旧的 mSysGit 版本。现在有 1.7.4 的预览版 - 我认为您应该尝试一下。

    我刚刚用 git 版本 1.7.4 尝试过这个,以下命令行语法对我有用:

    git merge -s recursive -X patience other-branch
    

    【讨论】:

    • 从 1.7.3 更新。到 1.7.4(仅在 3 周前在 mSysGit 中发布)有帮助!谢谢详细解答!
    【解决方案2】:

    2021 年 8 月更新,10 年后:不再有“递归合并”:

    使用 Git 2.34(2021 年第四季度),默认 合并策略变为 ORT ("Ostensibly Recursive's Twin")

    commit 81483fecommit 67feccdcommit 6320813commit b36ade2commit 4d15c85commit 002a6dfcommit 510415ecommit e80178ecommit e80178ecommit b378df7commit e037c2e@@(8 月 4 日) 987654332@.
    (由 Junio C Hamano -- gitster -- 合并于 commit aca13c2,2021 年 8 月 30 日)

    81483fe613:更新错误信息和代码注释

    签字人:Derrick Stolee
    签字人:Johannes Schindelin
    签字人:Elijah Newren

    代码中有两个位置引用了“merge-recursive”,但也适用于“merge-ort”。
    将它们更新为更一般的措辞。

    使用 Git 2.34(2021 年第四季度),文档更新。

    commit 81483fecommit 67feccdcommit 6320813commit b36ade2commit 4d15c85commit 002a6dfcommit 510415ecommit e80178ecommit e80178ecommit b378df7commit 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-renamespatiencediff-algorithm.
    它总是以重命名运行 检测(它比recursive 处理它的速度要快得多),并且 它专门使用diff-algorithm=histogram

    还有:

    在 Git 2.34(2021 年第四季度)中,使用 ort 而不是 recursive 作为默认合并策略。

    参见commit f5a3c5ecommit 6a5fb96(2021 年 8 月 4 日)Elijah Newren (newren)
    (由 Junio C Hamano -- gitster -- 合并到 commit 8778fa8,2021 年 8 月 30 日)

    f5a3c5e637:更新文档以更改默认合并后端

    签字人: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) 中没有显示其他任何地方......所以是的,我不知道如何为合并实现这一点。

    【讨论】:

    • @Filip:我只是建议我不了解代码当前如何使用合并策略的选项(但我的 C 技能一开始并不十分出色)。
    • 在 1.7.4 中,parse_merge_optmerge.cmerge-recursive.c 调用。但是,@Filip 在任何情况下都使用 1.7.3.1。引入 patience 合并选项的提交仅存在于 1.7.4 中 - 请参阅我的答案...
    猜你喜欢
    • 1970-01-01
    • 2018-04-19
    • 2018-09-08
    • 2014-07-12
    • 2020-11-21
    • 2018-01-06
    • 1970-01-01
    • 2013-10-19
    • 2020-02-05
    相关资源
    最近更新 更多