mirror of
https://github.com/git/git
synced 2024-11-05 18:59:29 +00:00
7260e87248
Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
240 lines
9 KiB
Text
240 lines
9 KiB
Text
git-merge-tree(1)
|
|
=================
|
|
|
|
NAME
|
|
----
|
|
git-merge-tree - Perform merge without touching index or working tree
|
|
|
|
|
|
SYNOPSIS
|
|
--------
|
|
[verse]
|
|
'git merge-tree' [--write-tree] [<options>] <branch1> <branch2>
|
|
'git merge-tree' [--trivial-merge] <base-tree> <branch1> <branch2> (deprecated)
|
|
|
|
[[NEWMERGE]]
|
|
DESCRIPTION
|
|
-----------
|
|
|
|
This command has a modern `--write-tree` mode and a deprecated
|
|
`--trivial-merge` mode. With the exception of the
|
|
<<DEPMERGE,DEPRECATED DESCRIPTION>> section at the end, the rest of
|
|
this documentation describes modern `--write-tree` mode.
|
|
|
|
Performs a merge, but does not make any new commits and does not read
|
|
from or write to either the working tree or index.
|
|
|
|
The performed merge will use the same feature as the "real"
|
|
linkgit:git-merge[1], including:
|
|
|
|
* three way content merges of individual files
|
|
* rename detection
|
|
* proper directory/file conflict handling
|
|
* recursive ancestor consolidation (i.e. when there is more than one
|
|
merge base, creating a virtual merge base by merging the merge bases)
|
|
* etc.
|
|
|
|
After the merge completes, a new toplevel tree object is created. See
|
|
`OUTPUT` below for details.
|
|
|
|
OPTIONS
|
|
-------
|
|
|
|
-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::
|
|
In the Conflicted file info section, instead of writing a list
|
|
of (mode, oid, stage, path) tuples to output for conflicted
|
|
files, just provide a list of filenames with conflicts (and
|
|
do not list filenames multiple times if they have multiple
|
|
conflicting stages).
|
|
|
|
--[no-]messages::
|
|
Write any informational messages such as "Auto-merging <path>"
|
|
or CONFLICT notices to the end of stdout. If unspecified, the
|
|
default is to include these messages if there are merge
|
|
conflicts, and to omit them otherwise.
|
|
|
|
--allow-unrelated-histories::
|
|
merge-tree will by default error out if the two branches specified
|
|
share no common history. This flag can be given to override that
|
|
check and make the merge proceed anyway.
|
|
|
|
[[OUTPUT]]
|
|
OUTPUT
|
|
------
|
|
|
|
For a successful merge, the output from git-merge-tree is simply one
|
|
line:
|
|
|
|
<OID of toplevel tree>
|
|
|
|
Whereas for a conflicted merge, the output is by default of the form:
|
|
|
|
<OID of toplevel tree>
|
|
<Conflicted file info>
|
|
<Informational messages>
|
|
|
|
These are discussed individually below.
|
|
|
|
[[OIDTLT]]
|
|
OID of toplevel tree
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
|
This is a tree object that represents what would be checked out in the
|
|
working tree at the end of `git merge`. If there were conflicts, then
|
|
files within this tree may have embedded conflict markers. This section
|
|
is always followed by a newline (or NUL if `-z` is passed).
|
|
|
|
[[CFI]]
|
|
Conflicted file info
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
|
This is a sequence of lines with the format
|
|
|
|
<mode> <object> <stage> <filename>
|
|
|
|
The filename will be quoted as explained for the configuration
|
|
variable `core.quotePath` (see linkgit:git-config[1]). However, if
|
|
the `--name-only` option is passed, the mode, object, and stage will
|
|
be omitted. If `-z` is passed, the "lines" are terminated by a NUL
|
|
character instead of a newline character.
|
|
|
|
[[IM]]
|
|
Informational messages
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
This always starts with a blank line (or NUL if `-z` is passed) to
|
|
separate it from the previous sections, and then has free-form
|
|
messages about the merge, such as:
|
|
|
|
* "Auto-merging <file>"
|
|
* "CONFLICT (rename/delete): <oldfile> renamed...but deleted in..."
|
|
* "Failed to merge submodule <submodule> (<reason>)"
|
|
* "Warning: cannot merge binary files: <filename>"
|
|
|
|
Note that these free-form messages will never have a NUL character
|
|
in or between them, even if -z is passed. It is simply a large block
|
|
of text taking up the remainder of the output.
|
|
|
|
EXIT STATUS
|
|
-----------
|
|
|
|
For a successful, non-conflicted merge, the exit status is 0. When the
|
|
merge has conflicts, the exit status is 1. If the merge is not able to
|
|
complete (or start) due to some kind of error, the exit status is
|
|
something other than 0 or 1 (and the output is unspecified).
|
|
|
|
USAGE NOTES
|
|
-----------
|
|
|
|
This command is intended as low-level plumbing, similar to
|
|
linkgit:git-hash-object[1], linkgit:git-mktree[1],
|
|
linkgit:git-commit-tree[1], linkgit:git-write-tree[1],
|
|
linkgit:git-update-ref[1], and linkgit:git-mktag[1]. Thus, it can be
|
|
used as a part of a series of steps such as:
|
|
|
|
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
|
|
|
|
Note that when the exit status is non-zero, `NEWTREE` in this sequence
|
|
will contain a lot more output than just a tree.
|
|
|
|
For conflicts, the output includes the same information that you'd get
|
|
with linkgit:git-merge[1]:
|
|
|
|
* what would be written to the working tree (the
|
|
<<OIDTLT,OID of toplevel tree>>)
|
|
* the higher order stages that would be written to the index (the
|
|
<<CFI,Conflicted file info>>)
|
|
* any messages that would have been printed to stdout (the
|
|
<<IM,Informational messages>>)
|
|
|
|
MISTAKES TO AVOID
|
|
-----------------
|
|
|
|
Do NOT look through the resulting toplevel tree to try to find which
|
|
files conflict; parse the <<CFI,Conflicted file info>> section instead.
|
|
Not only would parsing an entire tree be horrendously slow in large
|
|
repositories, there are numerous types of conflicts not representable by
|
|
conflict markers (modify/delete, mode conflict, binary file changed on
|
|
both sides, file/directory conflicts, various rename conflict
|
|
permutations, etc.)
|
|
|
|
Do NOT interpret an empty <<CFI,Conflicted file info>> list as a clean
|
|
merge; check the exit status. A merge can have conflicts without having
|
|
individual files conflict (there are a few types of directory rename
|
|
conflicts that fall into this category, and others might also be added
|
|
in the future).
|
|
|
|
Do NOT attempt to guess or make the user guess the conflict types from
|
|
the <<CFI,Conflicted file info>> list. The information there is
|
|
insufficient to do so. For example: Rename/rename(1to2) conflicts (both
|
|
sides renamed the same file differently) will result in three different
|
|
file having higher order stages (but each only has one higher order
|
|
stage), with no way (short of the <<IM,Informational messages>> section)
|
|
to determine which three files are related. File/directory conflicts
|
|
also result in a file with exactly one higher order stage.
|
|
Possibly-involved-in-directory-rename conflicts (when
|
|
"merge.directoryRenames" is unset or set to "conflicts") also result in
|
|
a file with exactly one higher order stage. In all cases, the
|
|
<<IM,Informational messages>> section has the necessary info, though it
|
|
is not designed to be machine parseable.
|
|
|
|
Do NOT assume that each paths from <<CFI,Conflicted file info>>, and
|
|
the logical conflicts in the <<IM,Informational messages>> have a
|
|
one-to-one mapping, nor that there is a one-to-many mapping, nor a
|
|
many-to-one mapping. Many-to-many mappings exist, meaning that each
|
|
path can have many logical conflict types in a single merge, and each
|
|
logical conflict type can affect many paths.
|
|
|
|
Do NOT assume all filenames listed in the <<IM,Informational messages>>
|
|
section had conflicts. Messages can be included for files that have no
|
|
conflicts, such as "Auto-merging <file>".
|
|
|
|
AVOID taking the OIDS from the <<CFI,Conflicted file info>> and
|
|
re-merging them to present the conflicts to the user. This will lose
|
|
information. Instead, look up the version of the file found within the
|
|
<<OIDTLT,OID of toplevel tree>> and show that instead. In particular,
|
|
the latter will have conflict markers annotated with the original
|
|
branch/commit being merged and, if renames were involved, the original
|
|
filename. While you could include the original branch/commit in the
|
|
conflict marker annotations when re-merging, the original filename is
|
|
not available from the <<CFI,Conflicted file info>> and thus you would
|
|
be losing information that might help the user resolve the conflict.
|
|
|
|
[[DEPMERGE]]
|
|
DEPRECATED DESCRIPTION
|
|
----------------------
|
|
|
|
Per the <<NEWMERGE,DESCRIPTION>> and unlike the rest of this
|
|
documentation, this section describes the deprecated `--trivial-merge`
|
|
mode.
|
|
|
|
Other than the optional `--trivial-merge`, this mode accepts no
|
|
options.
|
|
|
|
This mode reads three tree-ish, and outputs trivial merge results and
|
|
conflicting stages to the standard output in a semi-diff format.
|
|
Since this was designed for higher level scripts to consume and merge
|
|
the results back into the index, it omits entries that match
|
|
<branch1>. The result of this second form is similar to what
|
|
three-way 'git read-tree -m' does, but instead of storing the results
|
|
in the index, the command outputs the entries to the standard output.
|
|
|
|
This form not only has limited applicability (a trivial merge cannot
|
|
handle content merges of individual files, rename detection, proper
|
|
directory/file conflict handling, etc.), the output format is also
|
|
difficult to work with, and it will generally be less performant than
|
|
the first form even on successful merges (especially if working in
|
|
large repositories).
|
|
|
|
GIT
|
|
---
|
|
Part of the linkgit:git[1] suite
|