|
| 1 | +git-merge-tree(1) |
| 2 | +================= |
| 3 | + |
| 4 | +NAME |
| 5 | +---- |
| 6 | +git-merge-tree - Perform merge without touching index or working tree |
| 7 | + |
| 8 | + |
| 9 | +SYNOPSIS |
| 10 | +-------- |
| 11 | +[verse] |
| 12 | +'git merge-tree' [--write-tree] [<options>] <branch1> <branch2> |
| 13 | +'git merge-tree' [--trivial-merge] <base-tree> <branch1> <branch2> (deprecated) |
| 14 | + |
| 15 | +[[NEWMERGE]] |
| 16 | +DESCRIPTION |
| 17 | +----------- |
| 18 | + |
| 19 | +This command has a modern `--write-tree` mode and a deprecated |
| 20 | +`--trivial-merge` mode. With the exception of the |
| 21 | +<<DEPMERGE,DEPRECATED DESCRIPTION>> section at the end, the rest of |
| 22 | +this documentation describes the modern `--write-tree` mode. |
| 23 | + |
| 24 | +Performs a merge, but does not make any new commits and does not read |
| 25 | +from or write to either the working tree or index. |
| 26 | + |
| 27 | +The performed merge will use the same features as the "real" |
| 28 | +linkgit:git-merge[1], including: |
| 29 | + |
| 30 | + * three way content merges of individual files |
| 31 | + * rename detection |
| 32 | + * proper directory/file conflict handling |
| 33 | + * recursive ancestor consolidation (i.e. when there is more than one |
| 34 | + merge base, creating a virtual merge base by merging the merge bases) |
| 35 | + * etc. |
| 36 | + |
| 37 | +After the merge completes, a new toplevel tree object is created. See |
| 38 | +`OUTPUT` below for details. |
| 39 | + |
| 40 | +OPTIONS |
| 41 | +------- |
| 42 | + |
| 43 | +-z:: |
| 44 | + Do not quote filenames in the <Conflicted file info> section, |
| 45 | + and end each filename with a NUL character rather than |
| 46 | + newline. Also begin the messages section with a NUL character |
| 47 | + instead of a newline. See <<OUTPUT>> below for more information. |
| 48 | + |
| 49 | +--name-only:: |
| 50 | + In the Conflicted file info section, instead of writing a list |
| 51 | + of (mode, oid, stage, path) tuples to output for conflicted |
| 52 | + files, just provide a list of filenames with conflicts (and |
| 53 | + do not list filenames multiple times if they have multiple |
| 54 | + conflicting stages). |
| 55 | + |
| 56 | +--[no-]messages:: |
| 57 | + Write any informational messages such as "Auto-merging <path>" |
| 58 | + or CONFLICT notices to the end of stdout. If unspecified, the |
| 59 | + default is to include these messages if there are merge |
| 60 | + conflicts, and to omit them otherwise. |
| 61 | + |
| 62 | +--allow-unrelated-histories:: |
| 63 | + merge-tree will by default error out if the two branches specified |
| 64 | + share no common history. This flag can be given to override that |
| 65 | + check and make the merge proceed anyway. |
| 66 | + |
| 67 | +--merge-base=<tree-ish>:: |
| 68 | + Instead of finding the merge-bases for <branch1> and <branch2>, |
| 69 | + specify a merge-base for the merge, and specifying multiple bases is |
| 70 | + currently not supported. This option is incompatible with `--stdin`. |
| 71 | ++ |
| 72 | +As the merge-base is provided directly, <branch1> and <branch2> do not need |
| 73 | +to specify commits; trees are enough. |
| 74 | + |
| 75 | +-X<option>:: |
| 76 | +--strategy-option=<option>:: |
| 77 | + Pass the merge strategy-specific option through to the merge strategy. |
| 78 | + See linkgit:git-merge[1] for details. |
| 79 | + |
| 80 | +[[OUTPUT]] |
| 81 | +OUTPUT |
| 82 | +------ |
| 83 | + |
| 84 | +For a successful merge, the output from git-merge-tree is simply one |
| 85 | +line: |
| 86 | + |
| 87 | + <OID of toplevel tree> |
| 88 | + |
| 89 | +Whereas for a conflicted merge, the output is by default of the form: |
| 90 | + |
| 91 | + <OID of toplevel tree> |
| 92 | + <Conflicted file info> |
| 93 | + <Informational messages> |
| 94 | + |
| 95 | +These are discussed individually below. |
| 96 | + |
| 97 | +However, there is an exception. If `--stdin` is passed, then there is |
| 98 | +an extra section at the beginning, a NUL character at the end, and then |
| 99 | +all the sections repeat for each line of input. Thus, if the first merge |
| 100 | +is conflicted and the second is clean, the output would be of the form: |
| 101 | + |
| 102 | + <Merge status> |
| 103 | + <OID of toplevel tree> |
| 104 | + <Conflicted file info> |
| 105 | + <Informational messages> |
| 106 | + NUL |
| 107 | + <Merge status> |
| 108 | + <OID of toplevel tree> |
| 109 | + NUL |
| 110 | + |
| 111 | +[[MS]] |
| 112 | +Merge status |
| 113 | +~~~~~~~~~~~~ |
| 114 | + |
| 115 | +This is an integer status followed by a NUL character. The integer status is: |
| 116 | + |
| 117 | + 0: merge had conflicts |
| 118 | + 1: merge was clean |
| 119 | + <0: something prevented the merge from running (e.g. access to repository |
| 120 | + objects denied by filesystem) |
| 121 | + |
| 122 | +[[OIDTLT]] |
| 123 | +OID of toplevel tree |
| 124 | +~~~~~~~~~~~~~~~~~~~~ |
| 125 | + |
| 126 | +This is a tree object that represents what would be checked out in the |
| 127 | +working tree at the end of `git merge`. If there were conflicts, then |
| 128 | +files within this tree may have embedded conflict markers. This section |
| 129 | +is always followed by a newline (or NUL if `-z` is passed). |
| 130 | + |
| 131 | +[[CFI]] |
| 132 | +Conflicted file info |
| 133 | +~~~~~~~~~~~~~~~~~~~~ |
| 134 | + |
| 135 | +This is a sequence of lines with the format |
| 136 | + |
| 137 | + <mode> <object> <stage> <filename> |
| 138 | + |
| 139 | +The filename will be quoted as explained for the configuration |
| 140 | +variable `core.quotePath` (see linkgit:git-config[1]). However, if |
| 141 | +the `--name-only` option is passed, the mode, object, and stage will |
| 142 | +be omitted. If `-z` is passed, the "lines" are terminated by a NUL |
| 143 | +character instead of a newline character. |
| 144 | + |
| 145 | +[[IM]] |
| 146 | +Informational messages |
| 147 | +~~~~~~~~~~~~~~~~~~~~~~ |
| 148 | + |
| 149 | +This section provides informational messages, typically about |
| 150 | +conflicts. The format of the section varies significantly depending |
| 151 | +on whether `-z` is passed. |
| 152 | + |
| 153 | +If `-z` is passed: |
| 154 | + |
| 155 | +The output format is zero or more conflict informational records, each |
| 156 | +of the form: |
| 157 | + |
| 158 | + <list-of-paths><conflict-type>NUL<conflict-message>NUL |
| 159 | + |
| 160 | +where <list-of-paths> is of the form |
| 161 | + |
| 162 | + <number-of-paths>NUL<path1>NUL<path2>NUL...<pathN>NUL |
| 163 | + |
| 164 | +and includes paths (or branch names) affected by the conflict or |
| 165 | +informational message in <conflict-message>. Also, <conflict-type> is a |
| 166 | +stable string explaining the type of conflict, such as |
| 167 | + |
| 168 | + * "Auto-merging" |
| 169 | + * "CONFLICT (rename/delete)" |
| 170 | + * "CONFLICT (submodule lacks merge base)" |
| 171 | + * "CONFLICT (binary)" |
| 172 | + |
| 173 | +and <conflict-message> is a more detailed message about the conflict which often |
| 174 | +(but not always) embeds the <stable-short-type-description> within it. These |
| 175 | +strings may change in future Git versions. Some examples: |
| 176 | + |
| 177 | + * "Auto-merging <file>" |
| 178 | + * "CONFLICT (rename/delete): <oldfile> renamed...but deleted in..." |
| 179 | + * "Failed to merge submodule <submodule> (no merge base)" |
| 180 | + * "Warning: cannot merge binary files: <filename>" |
| 181 | + |
| 182 | +If `-z` is NOT passed: |
| 183 | + |
| 184 | +This section starts with a blank line to separate it from the previous |
| 185 | +sections, and then only contains the <conflict-message> information |
| 186 | +from the previous section (separated by newlines). These are |
| 187 | +non-stable strings that should not be parsed by scripts, and are just |
| 188 | +meant for human consumption. Also, note that while <conflict-message> |
| 189 | +strings usually do not contain embedded newlines, they sometimes do. |
| 190 | +(However, the free-form messages will never have an embedded NUL |
| 191 | +character). So, the entire block of information is meant for human |
| 192 | +readers as an agglomeration of all conflict messages. |
| 193 | + |
| 194 | +EXIT STATUS |
| 195 | +----------- |
| 196 | + |
| 197 | +For a successful, non-conflicted merge, the exit status is 0. When the |
| 198 | +merge has conflicts, the exit status is 1. If the merge is not able to |
| 199 | +complete (or start) due to some kind of error, the exit status is |
| 200 | +something other than 0 or 1 (and the output is unspecified). When |
| 201 | +--stdin is passed, the return status is 0 for both successful and |
| 202 | +conflicted merges, and something other than 0 or 1 if it cannot complete |
| 203 | +all the requested merges. |
| 204 | + |
| 205 | +USAGE NOTES |
| 206 | +----------- |
| 207 | + |
| 208 | +This command is intended as low-level plumbing, similar to |
| 209 | +linkgit:git-hash-object[1], linkgit:git-mktree[1], |
| 210 | +linkgit:git-commit-tree[1], linkgit:git-write-tree[1], |
| 211 | +linkgit:git-update-ref[1], and linkgit:git-mktag[1]. Thus, it can be |
| 212 | +used as a part of a series of steps such as: |
| 213 | + |
| 214 | + vi message.txt |
| 215 | + BRANCH1=refs/heads/test |
| 216 | + BRANCH2=main |
| 217 | + NEWTREE=$(git merge-tree --write-tree $BRANCH1 $BRANCH2) || { |
| 218 | + echo "There were conflicts..." 1>&2 |
| 219 | + exit 1 |
| 220 | + } |
| 221 | + NEWCOMMIT=$(git commit-tree $NEWTREE -F message.txt \ |
| 222 | + -p $BRANCH1 -p $BRANCH2) |
| 223 | + git update-ref $BRANCH1 $NEWCOMMIT |
| 224 | + |
| 225 | +Note that when the exit status is non-zero, `NEWTREE` in this sequence |
| 226 | +will contain a lot more output than just a tree. |
| 227 | + |
| 228 | +For conflicts, the output includes the same information that you'd get |
| 229 | +with linkgit:git-merge[1]: |
| 230 | + |
| 231 | + * what would be written to the working tree (the |
| 232 | + <<OIDTLT,OID of toplevel tree>>) |
| 233 | + * the higher order stages that would be written to the index (the |
| 234 | + <<CFI,Conflicted file info>>) |
| 235 | + * any messages that would have been printed to stdout (the |
| 236 | + <<IM,Informational messages>>) |
| 237 | + |
| 238 | +INPUT FORMAT |
| 239 | +------------ |
| 240 | +'git merge-tree --stdin' input format is fully text based. Each line |
| 241 | +has this format: |
| 242 | + |
| 243 | + [<base-commit> -- ]<branch1> <branch2> |
| 244 | + |
| 245 | +If one line is separated by `--`, the string before the separator is |
| 246 | +used for specifying a merge-base for the merge and the string after |
| 247 | +the separator describes the branches to be merged. |
| 248 | + |
| 249 | +MISTAKES TO AVOID |
| 250 | +----------------- |
| 251 | + |
| 252 | +Do NOT look through the resulting toplevel tree to try to find which |
| 253 | +files conflict; parse the <<CFI,Conflicted file info>> section instead. |
| 254 | +Not only would parsing an entire tree be horrendously slow in large |
| 255 | +repositories, there are numerous types of conflicts not representable by |
| 256 | +conflict markers (modify/delete, mode conflict, binary file changed on |
| 257 | +both sides, file/directory conflicts, various rename conflict |
| 258 | +permutations, etc.) |
| 259 | + |
| 260 | +Do NOT interpret an empty <<CFI,Conflicted file info>> list as a clean |
| 261 | +merge; check the exit status. A merge can have conflicts without having |
| 262 | +individual files conflict (there are a few types of directory rename |
| 263 | +conflicts that fall into this category, and others might also be added |
| 264 | +in the future). |
| 265 | + |
| 266 | +Do NOT attempt to guess or make the user guess the conflict types from |
| 267 | +the <<CFI,Conflicted file info>> list. The information there is |
| 268 | +insufficient to do so. For example: Rename/rename(1to2) conflicts (both |
| 269 | +sides renamed the same file differently) will result in three different |
| 270 | +files having higher order stages (but each only has one higher order |
| 271 | +stage), with no way (short of the <<IM,Informational messages>> section) |
| 272 | +to determine which three files are related. File/directory conflicts |
| 273 | +also result in a file with exactly one higher order stage. |
| 274 | +Possibly-involved-in-directory-rename conflicts (when |
| 275 | +"merge.directoryRenames" is unset or set to "conflicts") also result in |
| 276 | +a file with exactly one higher order stage. In all cases, the |
| 277 | +<<IM,Informational messages>> section has the necessary info, though it |
| 278 | +is not designed to be machine parseable. |
| 279 | + |
| 280 | +Do NOT assume that each path from <<CFI,Conflicted file info>>, and |
| 281 | +the logical conflicts in the <<IM,Informational messages>> have a |
| 282 | +one-to-one mapping, nor that there is a one-to-many mapping, nor a |
| 283 | +many-to-one mapping. Many-to-many mappings exist, meaning that each |
| 284 | +path can have many logical conflict types in a single merge, and each |
| 285 | +logical conflict type can affect many paths. |
| 286 | + |
| 287 | +Do NOT assume all filenames listed in the <<IM,Informational messages>> |
| 288 | +section had conflicts. Messages can be included for files that have no |
| 289 | +conflicts, such as "Auto-merging <file>". |
| 290 | + |
| 291 | +AVOID taking the OIDS from the <<CFI,Conflicted file info>> and |
| 292 | +re-merging them to present the conflicts to the user. This will lose |
| 293 | +information. Instead, look up the version of the file found within the |
| 294 | +<<OIDTLT,OID of toplevel tree>> and show that instead. In particular, |
| 295 | +the latter will have conflict markers annotated with the original |
| 296 | +branch/commit being merged and, if renames were involved, the original |
| 297 | +filename. While you could include the original branch/commit in the |
| 298 | +conflict marker annotations when re-merging, the original filename is |
| 299 | +not available from the <<CFI,Conflicted file info>> and thus you would |
| 300 | +be losing information that might help the user resolve the conflict. |
| 301 | + |
| 302 | +[[DEPMERGE]] |
| 303 | +DEPRECATED DESCRIPTION |
| 304 | +---------------------- |
| 305 | + |
| 306 | +Per the <<NEWMERGE,DESCRIPTION>> and unlike the rest of this |
| 307 | +documentation, this section describes the deprecated `--trivial-merge` |
| 308 | +mode. |
| 309 | + |
| 310 | +Other than the optional `--trivial-merge`, this mode accepts no |
| 311 | +options. |
| 312 | + |
| 313 | +This mode reads three tree-ish, and outputs trivial merge results and |
| 314 | +conflicting stages to the standard output in a semi-diff format. |
| 315 | +Since this was designed for higher level scripts to consume and merge |
| 316 | +the results back into the index, it omits entries that match |
| 317 | +<branch1>. The result of this second form is similar to what |
| 318 | +three-way 'git read-tree -m' does, but instead of storing the results |
| 319 | +in the index, the command outputs the entries to the standard output. |
| 320 | + |
| 321 | +This form not only has limited applicability (a trivial merge cannot |
| 322 | +handle content merges of individual files, rename detection, proper |
| 323 | +directory/file conflict handling, etc.), the output format is also |
| 324 | +difficult to work with, and it will generally be less performant than |
| 325 | +the first form even on successful merges (especially if working in |
| 326 | +large repositories). |
| 327 | + |
| 328 | +GIT |
| 329 | +--- |
| 330 | +Part of the linkgit:git[1] suite |
0 commit comments