summaryrefslogtreecommitdiff
path: root/Documentation/git-merge-tree.txt
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/git-merge-tree.txt')
-rw-r--r--Documentation/git-merge-tree.txt235
1 files changed, 223 insertions, 12 deletions
diff --git a/Documentation/git-merge-tree.txt b/Documentation/git-merge-tree.txt
index 58731c1..d6c3567 100644
--- a/Documentation/git-merge-tree.txt
+++ b/Documentation/git-merge-tree.txt
@@ -3,26 +3,237 @@ git-merge-tree(1)
NAME
----
-git-merge-tree - Show three-way merge without touching index
+git-merge-tree - Perform merge without touching index or working tree
SYNOPSIS
--------
[verse]
-'git merge-tree' <base-tree> <branch1> <branch2>
+'git merge-tree' [--write-tree] [<options>] <branch1> <branch2>
+'git merge-tree' [--trivial-merge] <base-tree> <branch1> <branch2> (deprecated)
+[[NEWMERGE]]
DESCRIPTION
-----------
-Reads three tree-ish, and output trivial merge results and
-conflicting stages to the standard output. This 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 is meant to be used by higher level scripts to compute
-merge results outside of the index, and stuff the results back into the
-index. For this reason, the output from the command omits
-entries that match the <branch1> tree.
+
+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
---