Merge branch 'en/merge-strategy-docs'

Documentation updates.

* en/merge-strategy-docs:
  Update error message and code comment
  merge-strategies.txt: add coverage of the `ort` merge strategy
  git-rebase.txt: correct out-of-date and misleading text about renames
  merge-strategies.txt: fix simple capitalization error
  merge-strategies.txt: avoid giving special preference to patience algorithm
  merge-strategies.txt: do not imply using copy detection is desired
  merge-strategies.txt: update wording for the resolve strategy
  Documentation: edit awkward references to `git merge-recursive`
  directory-rename-detection.txt: small updates due to merge-ort optimizations
  git-rebase.txt: correct antiquated claims about --rebase-merges
This commit is contained in:
Junio C Hamano 2021-08-30 16:06:01 -07:00
commit aca13c2355
6 changed files with 55 additions and 42 deletions

View File

@ -340,9 +340,7 @@ See also INCOMPATIBLE OPTIONS below.
-m:: -m::
--merge:: --merge::
Use merging strategies to rebase. When the recursive (default) merge Using merging strategies to rebase (default).
strategy is used, this allows rebase to be aware of renames on the
upstream side. This is the default.
+ +
Note that a rebase merge works by replaying each commit from the working Note that a rebase merge works by replaying each commit from the working
branch on top of the <upstream> branch. Because of this, when a merge branch on top of the <upstream> branch. Because of this, when a merge
@ -354,9 +352,8 @@ See also INCOMPATIBLE OPTIONS below.
-s <strategy>:: -s <strategy>::
--strategy=<strategy>:: --strategy=<strategy>::
Use the given merge strategy. Use the given merge strategy, instead of the default
If there is no `-s` option 'git merge-recursive' is used `recursive`. This implies `--merge`.
instead. This implies --merge.
+ +
Because 'git rebase' replays each commit from the working branch Because 'git rebase' replays each commit from the working branch
on top of the <upstream> branch using the given strategy, using on top of the <upstream> branch using the given strategy, using
@ -530,7 +527,7 @@ The `--rebase-merges` mode is similar in spirit to the deprecated
where commits can be reordered, inserted and dropped at will. where commits can be reordered, inserted and dropped at will.
+ +
It is currently only possible to recreate the merge commits using the It is currently only possible to recreate the merge commits using the
`recursive` merge strategy; Different merge strategies can be used only via `recursive` merge strategy; different merge strategies can be used only via
explicit `exec git merge -s <strategy> [...]` commands. explicit `exec git merge -s <strategy> [...]` commands.
+ +
See also REBASING MERGES and INCOMPATIBLE OPTIONS below. See also REBASING MERGES and INCOMPATIBLE OPTIONS below.
@ -1219,12 +1216,16 @@ successful merge so that the user can edit the message.
If a `merge` command fails for any reason other than merge conflicts (i.e. If a `merge` command fails for any reason other than merge conflicts (i.e.
when the merge operation did not even start), it is rescheduled immediately. when the merge operation did not even start), it is rescheduled immediately.
At this time, the `merge` command will *always* use the `recursive` By default, the `merge` command will use the `recursive` merge
merge strategy for regular merges, and `octopus` for octopus merges, strategy for regular merges, and `octopus` for octopus merges. One
with no way to choose a different one. To work around can specify a default strategy for all merges using the `--strategy`
this, an `exec` command can be used to call `git merge` explicitly, argument when invoking rebase, or can override specific merges in the
using the fact that the labels are worktree-local refs (the ref interactive list of commands by using an `exec` command to call `git
`refs/rewritten/onto` would correspond to the label `onto`, for example). merge` explicitly with a `--strategy` argument. Note that when
calling `git merge` explicitly like this, you can make use of the fact
that the labels are worktree-local refs (the ref `refs/rewritten/onto`
would correspond to the label `onto`, for example) in order to refer
to the branches you want to merge.
Note: the first command (`label onto`) labels the revision onto which Note: the first command (`label onto`) labels the revision onto which
the commits are rebased; The name `onto` is just a convention, as a nod the commits are rebased; The name `onto` is just a convention, as a nod

View File

@ -144,8 +144,8 @@ endif::git-pull[]
Use the given merge strategy; can be supplied more than Use the given merge strategy; can be supplied more than
once to specify them in the order they should be tried. once to specify them in the order they should be tried.
If there is no `-s` option, a built-in list of strategies If there is no `-s` option, a built-in list of strategies
is used instead ('git merge-recursive' when merging a single is used instead (`recursive` when merging a single head,
head, 'git merge-octopus' otherwise). `octopus` otherwise).
-X <option>:: -X <option>::
--strategy-option=<option>:: --strategy-option=<option>::

View File

@ -6,13 +6,6 @@ backend 'merge strategies' to be chosen with `-s` option. Some strategies
can also take their own options, which can be passed by giving `-X<option>` can also take their own options, which can be passed by giving `-X<option>`
arguments to `git merge` and/or `git pull`. arguments to `git merge` and/or `git pull`.
resolve::
This can only resolve two heads (i.e. the current branch
and another branch you pulled from) using a 3-way merge
algorithm. It tries to carefully detect criss-cross
merge ambiguities and is considered generally safe and
fast.
recursive:: recursive::
This can only resolve two heads using a 3-way merge This can only resolve two heads using a 3-way merge
algorithm. When there is more than one common algorithm. When there is more than one common
@ -23,9 +16,9 @@ recursive::
causing mismerges by tests done on actual merge commits causing mismerges by tests done on actual merge commits
taken from Linux 2.6 kernel development history. taken from Linux 2.6 kernel development history.
Additionally this can detect and handle merges involving Additionally this can detect and handle merges involving
renames, but currently cannot make use of detected renames. It does not make use of detected copies. This
copies. This is the default merge strategy when pulling is the default merge strategy when pulling or merging one
or merging one branch. branch.
+ +
The 'recursive' strategy can take the following options: The 'recursive' strategy can take the following options:
@ -44,17 +37,14 @@ theirs;;
no 'theirs' merge strategy to confuse this merge option with. no 'theirs' merge strategy to confuse this merge option with.
patience;; patience;;
With this option, 'merge-recursive' spends a little extra time Deprecated synonym for `diff-algorithm=patience`.
to avoid mismerges that sometimes occur due to unimportant
matching lines (e.g., braces from distinct functions). Use
this when the branches to be merged have diverged wildly.
See also linkgit:git-diff[1] `--patience`.
diff-algorithm=[patience|minimal|histogram|myers];; diff-algorithm=[patience|minimal|histogram|myers];;
Tells 'merge-recursive' to use a different diff algorithm, which Use a different diff algorithm while merging, which can help
can help avoid mismerges that occur due to unimportant matching avoid mismerges that occur due to unimportant matching lines
lines (such as braces from distinct functions). See also (such as braces from distinct functions). See also
linkgit:git-diff[1] `--diff-algorithm`. linkgit:git-diff[1] `--diff-algorithm`. Defaults to the
`diff.algorithm` config setting.
ignore-space-change;; ignore-space-change;;
ignore-all-space;; ignore-all-space;;
@ -105,6 +95,26 @@ subtree[=<path>];;
is prefixed (or stripped from the beginning) to make the shape of is prefixed (or stripped from the beginning) to make the shape of
two trees to match. two trees to match.
ort::
This is meant as a drop-in replacement for the `recursive`
algorithm (as reflected in its acronym -- "Ostensibly
Recursive's Twin"), and will likely replace it in the future.
It fixes corner cases that the `recursive` strategy handles
suboptimally, and is significantly faster in large
repositories -- especially when many renames are involved.
+
The `ort` strategy takes all the same options as `recursive`.
However, it ignores three of those options: `no-renames`,
`patience` and `diff-algorithm`. It always runs with rename
detection (it handles it much faster than `recursive` does), and
it specifically uses `diff-algorithm=histogram`.
resolve::
This can only resolve two heads (i.e. the current branch
and another branch you pulled from) using a 3-way merge
algorithm. It tries to carefully detect criss-cross
merge ambiguities. It does not handle renames.
octopus:: octopus::
This resolves cases with more than two heads, but refuses to do This resolves cases with more than two heads, but refuses to do
a complex merge that needs manual resolution. It is a complex merge that needs manual resolution. It is

View File

@ -2,9 +2,9 @@ Directory rename detection
========================== ==========================
Rename detection logic in diffcore-rename that checks for renames of Rename detection logic in diffcore-rename that checks for renames of
individual files is aggregated and analyzed in merge-recursive for cases individual files is also aggregated there and then analyzed in either
where combinations of renames indicate that a full directory has been merge-ort or merge-recursive for cases where combinations of renames
renamed. indicate that a full directory has been renamed.
Scope of abilities Scope of abilities
------------------ ------------------
@ -88,9 +88,11 @@ directory rename detection support in:
Folks have requested in the past that `git diff` detect directory Folks have requested in the past that `git diff` detect directory
renames and somehow simplify its output. It is not clear whether this renames and somehow simplify its output. It is not clear whether this
would be desirable or how the output should be simplified, so this was would be desirable or how the output should be simplified, so this was
simply not implemented. Further, to implement this, directory rename simply not implemented. Also, while diffcore-rename has most of the
detection logic would need to move from merge-recursive to logic for detecting directory renames, some of the logic is still found
diffcore-rename. within merge-ort and merge-recursive. Fully supporting directory
rename detection in diffs would require copying or moving the remaining
bits of logic to the diff machinery.
* am * am

View File

@ -739,7 +739,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
for (x = 0; x < xopts_nr; x++) for (x = 0; x < xopts_nr; x++)
if (parse_merge_opt(&o, xopts[x])) if (parse_merge_opt(&o, xopts[x]))
die(_("Unknown option for merge-recursive: -X%s"), xopts[x]); die(_("unknown strategy option: -X%s"), xopts[x]);
o.branch1 = head_arg; o.branch1 = head_arg;
o.branch2 = merge_remote_util(remoteheads->item)->name; o.branch2 = merge_remote_util(remoteheads->item)->name;

View File

@ -2065,7 +2065,7 @@ static int do_pick_commit(struct repository *r,
/* /*
* We do not intend to commit immediately. We just want to * We do not intend to commit immediately. We just want to
* merge the differences in, so let's compute the tree * merge the differences in, so let's compute the tree
* that represents the "current" state for merge-recursive * that represents the "current" state for the merge machinery
* to work on. * to work on.
*/ */
if (write_index_as_tree(&head, r->index, r->index_file, 0, NULL)) if (write_index_as_tree(&head, r->index, r->index_file, 0, NULL))