Setup and Config
Getting and Creating Projects
Basic Snapshotting
Branching and Merging
Sharing and Updating Projects
Inspection and Comparison
Patching
Debugging
External Systems
Server Admin
Guides
- gitattributes
- Command-line interface conventions
- Everyday Git
- Frequently Asked Questions (FAQ)
- Glossary
- Hooks
- gitignore
- gitmodules
- Revisions
- Submodules
- Tutorial
- Workflows
- All guides...
Administration
Plumbing Commands
-
2.52.0
2025-11-17
- 2.51.2 no changes
-
2.51.1
2025-10-15
- 2.50.1 → 2.51.0 no changes
-
2.50.0
2025-06-16
- 2.49.1 no changes
-
2.49.0
2025-03-14
- 2.47.2 → 2.48.2 no changes
-
2.47.1
2024-11-25
- 2.45.4 → 2.47.0 no changes
-
2.45.3
2024-11-26
- 2.45.1 → 2.45.2 no changes
-
2.45.0
2024-04-29
- 2.43.1 → 2.44.4 no changes
-
2.43.0
2023-11-20
- 2.41.1 → 2.42.4 no changes
-
2.41.0
2023-06-01
- 2.40.1 → 2.40.4 no changes
-
2.40.0
2023-03-12
- 2.39.1 → 2.39.5 no changes
-
2.39.0
2022-12-12
- 2.38.1 → 2.38.5 no changes
-
2.38.0
2022-10-02
- 2.1.4 → 2.37.7 no changes
-
2.0.5
2014-12-17
概述
git merge-tree [--write-tree] [<选项>] <分支 1> <分支 2> git merge-tree [--trivial-merge] <基础目录树> <分支 1> <分支 2> (deprecated)
描述
该命令有现代的 --wirte-tree 模式和过时的 --trivial-merge 模式。 除了最后的 弃用说明 部分,本文档的其余部分描述的是现代的 --write-tree 模式。
执行合并,但不做任何新的提交,也不从工作区或索引中读取或写入。
执行的合并将使用与 “真正的” git-merge[1]相同的功能,包括:
-
单个文件的多路合并
-
rename detection
-
正确处理目录/文件冲突
-
递归祖先合并(即当有一个以上的合并基数时,通过合并基础创建一个虚拟合并基础)
-
等等。
合并完成后,会创建一个新的顶层树对象。 详见下面的 “输出”。
选项
- --stdin
-
Read the commits to merge from the standard input rather than the command-line. See INPUT FORMAT below for more information. Implies
-z. - -z
-
Do not quote filenames in the <Conflicted file info> section, and end each filename with a NUL character rather than newline. Also begin the messages section with a NUL character instead of a newline. See OUTPUT below for more information.
- --name-only
-
在冲突的文件信息部分,不要为冲突的文件写一个(mode, oid, stage, path)图元列表来输出,只需提供一个有冲突的文件名列表(如果文件有多个冲突的阶段,不多次列出文件名)。
- --messages
- --no-messages
-
将任何信息性的消息,如"Auto-merging <path>" 或冲突通知写到标准输出流的末尾。 如果没有指定,默认情况下,如果有合并冲突,就包括这些信息,否则就省略它们。
- --quiet
-
Disable all output from the program. Useful when you are only interested in the exit status. Allows merge-tree to exit early when it finds a conflict, and allows it to avoid writing most objects created by merges.
-
如果指定的两个分支没有共同的历史,merge-tree 默认会出错。 这个标志可以用来覆盖这个检查,并使合并继续进行。
- --merge-base=<tree-ish>
-
Instead of finding the merge-bases for <branch1> and <branch2>, specify a merge-base for the merge. This option is incompatible with
--stdin.Specifying multiple bases is currently not supported, which means that when merging two branches with more than one merge-base, using this option may cause merge results to differ from what
gitmergewould compute. This can include potentially losing some changes made on one side of the history in the resulting merge.With this option, since the merge-base is provided directly, <branch1> and <branch2> do not need to specify commits; trees are enough.
- -X<选项>
- --strategy-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
其中 <list-of-paths> 的形式为
<number-of-paths>NUL<path1>NUL<path2>NUL...<pathN>NUL
并包括受冲突影响的路径(或分支名称)或 <conflict-message> 中的信息消息。 另外,<conflict-type> 是一个稳定的字符串,解释了冲突的类型,比如说
-
"Auto-merging"
-
"CONFLICT (重命名/删除)"
-
"CONFLICT (子模块缺乏合并基础)"
-
"CONFLICT (二进制)"
和 <conflict-message> 是关于冲突的更详细的信息,通常(但不一定)会嵌入 <stable-short-type-description> 中。 这些字符串在未来的Git版本中可能会改变。 一些例子:
-
"Auto-merging <文件>"
-
"CONFLICT (rename/delete): <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]。 因此,它可以作为一系列步骤的一部分来使用,比如:
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] 得到的相同信息:
-
什么会被写入工作区(顶层目录树树的 OID)
-
将被写入索引的高阶阶段(冲突的文件信息)
-
任何会被打印到标准输出流的信息(信息性信息)
输入格式
git merge-tree --stdin 的输入格式是完全基于文本的。每一行都有这样的格式:
[<基础提交> -- ]<分支1> <分支2>
如果一行被 -- 分隔,分隔符前的字符串用于指定合并的基础,分隔符后的字符串描述要合并的分支。
应避免的错误
不要在产生的顶层目录树中寻找哪些文件有冲突,而要解析 冲突文件信息 部分。 在大型存储库中,不仅解析整个目录树会慢得吓人,而且有许多冲突类型无法用冲突标记来表示(修改/删除,模式冲突,二进制文件在两边都有改变,文件/目录冲突,各种重命名冲突的变种,等等。)
不要把一个空的 冲突文件信息 列表理解为一个干净的合并;检查退出状态。 一个合并可以有冲突而没有单个文件的冲突(有几种类型的目录重命名冲突属于这个类别,其他的也可能在将来被添加)。
不要试图猜测或让用户猜测 冲突文件信息 列表中的冲突类型。 那里的信息不足以做到这一点。 比如说: Rname/rename( 1 对 2 )冲突(双方以不同方式重命名同一文件)将导致三个不同的文件具有高阶阶段(但每个文件只有一个高阶阶段),没有办法(除了 信息消息 部分)确定哪三个文件是相关的。 文件/目录冲突也会导致一个文件正好有一个高阶阶段。 可能涉及目录重命名的冲突(当 "merge.directoryRenames" 未设置或设置为 "conflict" 时)也会导致一个文件正好有一个高阶阶段。 在所有情况下,消息性信息 部分都有必要的信息,尽管它不是被设计为可被机器解析的。
不要假设 冲突文件信息 中的每个路径和 信息消息 中的逻辑冲突有一对一的映射,也不要假设存在一对多的映射,更不要假设存在多对一的映射。 存在多对多的映射,意味着每个路径在一次合并中可以有许多逻辑冲突类型,每个逻辑冲突类型可以影响许多路径。
不要认为 信息消息 部分列出的所有文件名都有冲突。 对于没有冲突的文件,可以包括信息,如 "Auto-merging <文件>"。
弃用说明
根据 DESCRIPTION,与本文档的其他部分不同,本节描述了被废弃的 --trivial-merge 模式。
除了可选的 --trivial-merge 外,该模式不接受任何选项。
这种模式读取三个树状的,并将琐碎的合并结果和冲突的阶段以 semi-diff 格式输出到标准输出。 由于这是为更高级别的脚本设计的,以消耗并将结果合并回索引中,所以它省略了与 <branch1> 相匹配的条目。 第二种形式的结果类似于三方 "git read-tree -m" 的做法,但该命令不是将结果存储在索引中,而是将条目输出到标准输出。
这种形式不仅适用性有限(一个琐碎的合并不能处理单个文件的内容合并、重命名检测、适当的目录/文件冲突处理等),输出格式也很难处理,而且即使在成功的合并中,它的性能一般也不如第一种形式(特别是在大型仓库中工作)。
GIT
属于 git[1] 文档