设置和配置
获取和创建项目
基本快照
分支和合并
共享和更新项目
检查和比较
补丁
调试
电子邮件
外部系统
服务器管理
指南
管理
管道命令
- 2.43.1 → 2.44.0 无更改
- 2.43.0 11/20/23
- 2.42.0 → 2.42.1 无更改
- 2.41.0 06/01/23
- 2.40.1 无更改
- 2.40.0 03/12/23
- 2.39.1 → 2.39.3 无更改
- 2.39.0 12/12/22
- 2.38.1 → 2.38.5 无更改
- 2.38.0 10/02/22
概要
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]相同的功能,包括
-
单个文件的三个内容合并
-
重命名检测
-
正确的目录/文件冲突处理
-
递归祖先合并(即当存在多个合并基时,通过合并合并基来创建虚拟合并基)
-
等
合并完成后,将创建一个新的顶级树对象。有关详细信息,请参见下面的 OUTPUT
。
选项
- -z
-
不要在 <冲突文件信息> 部分引用文件名,并用 NUL 字符而不是换行符结束每个文件名。另请用 NUL 字符而不是换行符开始消息部分。有关更多信息,请参见下面的 OUTPUT。
- --name-only
-
在冲突文件信息部分,不要为冲突文件写一个 (mode, oid, stage, path) 元组列表到输出,只需提供带有冲突的文件名列表(如果它们有多个冲突阶段,则不要多次列出文件名)。
- --[no-]messages
-
将任何信息消息(例如“自动合并 <path>”或 CONFLICT 通知)写入 stdout 的末尾。如果未指定,则默认情况下在存在合并冲突时包含这些消息,否则省略这些消息。
-
如果指定的两个分支没有共同的历史记录,merge-tree 默认会出错。可以给定此标志来覆盖该检查,并使合并继续进行。
- --merge-base=<commit>
-
指定合并的合并基准,而不是查找 <branch1> 和 <branch2> 的合并基准,并且目前不支持指定多个基准。此选项与
--stdin
不兼容。
输出
对于成功的合并,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
合并状态
这是一个整数状态,后面跟着一个 NUL 字符。整数状态为
0: merge had conflicts 1: merge was clean <0: something prevented the merge from running (e.g. access to repository objects denied by filesystem)
顶层树的 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
其中 <list-of-paths> 的格式为
<number-of-paths>NUL<path1>NUL<path2>NUL...<pathN>NUL
并且包括受 <conflict-message> 中的冲突或信息消息影响的路径(或分支名称)。此外,<conflict-type> 是一个稳定的字符串,用于解释冲突类型,例如
-
"自动合并"
-
"冲突(重命名/删除)"
-
"冲突(子模块缺少合并基准)"
-
"冲突(二进制)"
并且 <conflict-message> 是关于冲突的更详细的消息,通常(但并非总是)嵌入 <stable-short-type-description>。这些字符串可能会在将来的 Git 版本中更改。一些示例
-
"自动合并 <file>"
-
"冲突(重命名/删除):<oldfile> 已重命名…但在…中删除"
-
"无法合并子模块 <submodule>(没有合并基准)"
-
"警告:无法合并二进制文件:<filename>"
如果未传递 -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]。因此,它可以用作一系列步骤的一部分,例如
NEWTREE=$(git merge-tree --write-tree $BRANCH1 $BRANCH2) test $? -eq 0 || die "There were conflicts..." NEWCOMMIT=$(git commit-tree $NEWTREE -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
,此模式不接受任何选项。
此模式读取三个树状,并将琐碎合并结果和冲突阶段以半 diff 格式输出到标准输出。由于此模式设计为供更高级别的脚本使用,并将其结果合并回索引,因此它会忽略与 <branch1> 匹配的条目。此第二种形式的结果类似于三向 git read-tree -m 所执行的操作,但此命令不会将结果存储在索引中,而是将条目输出到标准输出。
此形式不仅适用性有限(琐碎合并无法处理单个文件的合并内容、重命名检测、正确的目录/文件冲突处理等),其输出格式也难以处理,并且即使在成功合并的情况下,其性能通常也会低于第一种形式(尤其是在大型存储库中工作时)。
GIT
git[1] 套件的一部分