设置和配置
获取和创建项目
基本快照
分支与合并
共享和更新项目
检查和比较
打补丁
调试
电子邮件
外部系统
服务器管理
指南
管理
底层命令
-
2.52.0
2025-11-17
- 2.51.2 无变更
-
2.51.1
2025-10-15
- 2.50.1 → 2.51.0 无变更
-
2.50.0
2025-06-16
- 2.49.1 无更改
-
2.49.0
2025-03-14
- 2.47.2 → 2.48.2 无更改
-
2.47.1
2024-11-25
- 2.45.4 → 2.47.0 无更改
-
2.45.3
2024-11-26
- 2.45.1 → 2.45.2 无更改
-
2.45.0
2024-04-29
- 2.43.1 → 2.44.4 无更改
-
2.43.0
2023-11-20
- 2.41.1 → 2.42.4 无更改
-
2.41.0
2023-06-01
- 2.40.1 → 2.40.4 无更改
-
2.40.0
2023-03-12
- 2.39.1 → 2.39.5 无变化
-
2.39.0
2022-12-12
- 2.38.1 → 2.38.5 无更改
-
2.38.0
2022-10-02
- 2.1.4 → 2.37.7 无更改
-
2.0.5
2014-12-17
概要
git merge-tree [--write-tree] [<options>] <branch1> <branch2> git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2> (deprecated)
描述
此命令具有现代的 --write-tree 模式和已弃用的 --trivial-merge 模式。除了末尾的 已弃用的描述 部分,本文档的其余部分描述的是现代的 --write-tree 模式。
执行合并,但不创建新提交,也不读取或写入工作目录或索引。
执行的合并将使用与“真正的” git-merge[1] 相同的特性,包括:
-
单个文件的三向内容合并
-
重命名检测
-
正确的目录/文件冲突处理
-
递归祖先合并(即当存在多个合并基时,通过合并合并基来创建虚拟合并基)
-
等等。
合并完成后,将创建一个新的顶层树对象。有关详细信息,请参阅下面的 输出。
选项
- --stdin
-
从标准输入读取要合并的提交,而不是从命令行读取。有关更多信息,请参阅下面的 输入格式。隐含
-z。 - -z
-
在 <冲突文件信息> 部分中不要引用文件名,并用 NUL 字符而不是换行符结束每个文件名。同时,用 NUL 字符而不是换行符开始消息部分。有关更多信息,请参阅下面的 输出。
- --name-only
-
在冲突文件信息部分,不为冲突文件编写 (模式, OID, 阶段, 路径) 元组列表,而是只提供冲突文件的文件名列表(如果一个文件名有多个冲突阶段,则不重复列出)。
- --messages
- --no-messages
-
将任何信息性消息(如“自动合并 <路径>”或 CONFLICT 通知)写入 stdout 的末尾。如果未指定,则默认情况下,如果存在合并冲突,则包含这些消息,否则省略它们。
- --quiet
-
禁用程序的所有输出。当您只关心退出状态时很有用。允许 merge-tree 在找到冲突时提前退出,并允许它避免写入合并创建的大部分对象。
-
默认情况下,如果指定的两个分支没有共同的历史记录,merge-tree 将会报错。可以给出此标志来覆盖该检查并继续合并。
- --merge-base=<tree-ish>
-
不查找 <branch1> 和 <branch2> 的合并基,而是指定一个合并基。此选项与
--stdin不兼容。目前不支持指定多个基,这意味着当合并具有多个合并基的两个分支时,使用此选项可能会导致合并结果与
gitmerge计算的结果不同。这可能包括在结果合并中丢失历史记录一侧的某些更改。使用此选项时,由于合并基直接提供,<branch1> 和 <branch2> 不需要指定提交;树就足够了。
- -X<option>
- --strategy-option=<option>
-
将合并策略特定的选项传递给合并策略。有关详细信息,请参阅 git-merge[1]。
输出
对于成功的合并,git-merge-tree 的输出只有一行。
<OID of toplevel tree>
而对于冲突的合并,输出默认格式为:
<OID of toplevel tree> <Conflicted file info> <Informational messages>
这些将在下面单独讨论。
但是,有一个例外。如果传递了 --stdin,则开头会有一个额外的部分,末尾有一个 NUL 字符,然后所有部分都会为每一行输入重复。因此,如果第一次合并有冲突而第二次合并是干净的,输出将是:
<Merge status> <OID of toplevel tree> <Conflicted file info> <Informational messages> NUL <Merge status> <OID of toplevel tree> NUL
顶层树的 OID
这是一个树对象,代表在 git merge 结束时将检出到工作目录的内容。如果存在冲突,则此树中的文件可能包含嵌入的冲突标记。此部分始终后跟一个换行符(如果传递了 -z,则为 NUL 字符)。
冲突文件信息
这是一系列格式为:
<mode> <object> <stage> <filename>
文件名将按照 core.quotePath 配置变量的说明进行引用(请参阅 git-config[1])。但是,如果传递了 --name-only 选项,则会省略模式、对象和阶段。如果传递了 -z,则“行”以 NUL 字符而不是换行符结尾。
信息性消息
此部分提供信息性消息,通常是关于冲突。该部分的格式在是否传递 -z 方面差异很大。
如果传递了 -z
输出格式为零个或多个冲突信息记录,每条记录的格式为:
<list-of-paths><conflict-type>NUL<conflict-message>NUL
其中 <paths> 的形式为:
<number-of-paths>NUL<path1>NUL<path2>NUL...<pathN>NUL
并包含受冲突或信息性消息影响的路径(或分支名称)。此外,<conflict-message> 是关于冲突的更详细的消息,通常(但不总是)嵌入了 <stable-short-type-description>。这些字符串在未来的 Git 版本中可能会发生变化。示例如下:
-
“自动合并”
-
“冲突(重命名/删除)”
-
“冲突(子模块缺少合并基)”
-
“冲突(二进制文件)”
而 <conflict-message> 是关于冲突的更详细消息,通常(但不总是)嵌入了 <stable-short-type-description>。这些字符串在未来的 Git 版本中可能会发生变化。一些示例:
-
“自动合并 <文件>”
-
“冲突(重命名/删除):<旧文件> 被重命名…但在…被删除”
-
“无法合并子模块 <submodule>(无合并基)”
-
“警告:无法合并二进制文件:<文件名>”
如果未传递 -z
此部分以一个空行开头,以将其与前面的部分分隔开,然后只包含前面部分中的 <conflict-message> 信息(用换行符分隔)。这些是非稳定的字符串,不应由脚本解析,仅供人类阅读。此外,请注意,虽然 <conflict-message> 字符串通常不包含嵌入的换行符,但有时会包含。(然而,自由格式的消息永远不会包含嵌入的 NUL 字符)。因此,整个信息块供人类读者作为所有冲突消息的集合。
退出状态
对于成功的、无冲突的合并,退出状态为 0。当合并有冲突时,退出状态为 1。如果合并因某种错误而无法完成(或启动),退出状态将不是 0 或 1(并且输出是未定义的)。当传递 --stdin 时,成功合并和有冲突的合并的返回状态均为 0,如果无法完成所有请求的合并,则返回状态将不是 0 或 1。
用法说明
此命令旨在作为低级命令,类似于 git-hash-object[1]、git-mktree[1]、git-commit-tree[1]、git-write-tree[1]、git-update-ref[1] 和 git-mktag[1]。因此,它可以作为一系列步骤的一部分,例如:
vi message.txt
BRANCH1=refs/heads/test
BRANCH2=main
NEWTREE=$(git merge-tree --write-tree $BRANCH1 $BRANCH2) || {
echo "There were conflicts..." 1>&2
exit 1
}
NEWCOMMIT=$(git commit-tree $NEWTREE -F message.txt \
-p $BRANCH1 -p $BRANCH2)
git update-ref $BRANCH1 $NEWCOMMIT
请注意,当退出状态非零时,此序列中的 NEWTREE 将包含比仅一个树更多的输出。
对于冲突,输出包含与 git-merge[1] 相同的信息:
输入格式
git merge-tree --stdin 的输入格式完全基于文本。每行格式如下:
[<base-commit> -- ]<branch1> <branch2>
如果一行被 -- 分隔,则分隔符前的字符串用于指定合并的合并基,分隔符后的字符串描述要合并的分支。
要避免的错误
请勿查看生成的顶层树来查找冲突的文件;而是解析 冲突文件信息 部分。不仅解析整个树在大型存储库中会非常慢,而且还有许多类型的冲突无法通过冲突标记表示(修改/删除、模式冲突、双方更改了二进制文件、文件/目录冲突、各种重命名冲突排列等)。
请勿将空的 冲突文件信息 列表解释为干净的合并;请检查退出状态。合并可能存在冲突而没有单个文件冲突(目录重命名冲突中有几种属于此类,将来也可能添加其他类型)。
请勿尝试猜测或让用户从 冲突文件信息 列表中猜测冲突类型。那里的信息不足以做到这一点。例如:重命名/重命名(1对2)冲突(双方将同一个文件重命名为不同的名称)将导致三个不同的文件具有更高阶的阶段(但每个文件只有一个更高阶的阶段),并且无法(通过 信息性消息 部分)确定这三个文件之间的关系。文件/目录冲突也会导致一个文件只有一个更高阶的阶段。可能涉及目录重命名的冲突(当“merge.directoryRenames”未设置或设置为“conflicts”时)也会导致一个文件只有一个更高阶的阶段。在所有情况下,信息性消息 部分都包含必要的信息,尽管它并非设计为机器可解析的。
请勿假设 冲突文件信息 中的每个路径以及 信息性消息 中的逻辑冲突存在一对一映射,或者存在一对多或多对一的映射。存在多对多映射,这意味着每个路径在一次合并中可以具有多种逻辑冲突类型,而每种逻辑冲突类型可以影响多个路径。
请勿假设 信息性消息 部分中列出的所有文件名都有冲突。消息可以包含没有冲突的文件,例如“自动合并 <文件>”。
已弃用的描述
根据 描述,与本文档的其余部分不同,本节描述了已弃用的 --trivial-merge 模式。
除了可选的 --trivial-merge 外,此模式不接受任何选项。
此模式读取三个 tree-ish,并以半 diff 格式将简单的合并结果和冲突阶段输出到标准输出。由于这是为更高级脚本消费和将结果合并回索引而设计的,因此它会省略与 <branch1> 匹配的条目。第二种形式的结果类似于三向 git read-tree -m 的功能,但它不是将结果存储在索引中,而是将条目输出到标准输出。
这种形式不仅适用性有限(简单的合并无法处理单个文件的内容合并、重命名检测、正确的目录/文件冲突处理等),而且输出格式也难以处理,即使在成功的合并中,它通常也比第一种形式性能差(尤其是在大型存储库中操作时)。