Skip to content

Debug merge-recursive.[ch] #1898

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 20 additions & 31 deletions Documentation/merge-strategies.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -87,44 +87,33 @@ no-renames;;
configuration variable.
See also linkgit:git-diff[1] `--no-renames`.

subtree[=<path>];;
This option is a more advanced form of 'subtree' strategy, where
the strategy makes a guess on how two trees must be shifted to
match with each other when merging. Instead, the specified path
is prefixed (or stripped from the beginning) to make the shape of
two trees to match.

recursive::
This can only resolve two heads using a 3-way merge
algorithm. When there is more than one common
ancestor that can be used for 3-way merge, it creates a
merged tree of the common ancestors and uses that as
the reference tree for the 3-way merge. This has been
reported to result in fewer merge conflicts without
causing mismerges by tests done on actual merge commits
taken from Linux 2.6 kernel development history.
Additionally this can detect and handle merges involving
renames. It does not make use of detected copies. This was
the default strategy for resolving two heads from Git v0.99.9k
until v2.33.0.
+
For a path that is a submodule, the same caution as 'ort' applies to this
strategy.
+
The 'recursive' strategy takes the same options as 'ort'. However,
there are two additional options that 'ort' ignores (not documented
above) that are potentially useful with the 'recursive' strategy:
histogram;;
Deprecated synonym for `diff-algorithm=histogram`.

patience;;
Deprecated synonym for `diff-algorithm=patience`.

diff-algorithm=[patience|minimal|histogram|myers];;
diff-algorithm=[histogram|minimal|myers|patience];;
Use a different diff algorithm while merging, which can help
avoid mismerges that occur due to unimportant matching lines
(such as braces from distinct functions). See also
linkgit:git-diff[1] `--diff-algorithm`. Note that `ort`
specifically uses `diff-algorithm=histogram`, while `recursive`
defaults to the `diff.algorithm` config setting.
defaults to `diff-algorithm=histogram`, while regular diffs
currently default to the `diff.algorithm` config setting.

subtree[=<path>];;
This option is a more advanced form of 'subtree' strategy, where
the strategy makes a guess on how two trees must be shifted to
match with each other when merging. Instead, the specified path
is prefixed (or stripped from the beginning) to make the shape of
two trees to match.

recursive::
This is now a synonym for `ort`. It was an alternative
implementation until v2.49.0, but was redirected to mean `ort`
in v2.50.0. The previous recursive strategy was the default
strategy for resolving two heads from Git v0.99.9k until
v2.33.0.

resolve::
This can only resolve two heads (i.e. the current branch
Expand All @@ -145,7 +134,7 @@ ours::
ignoring all changes from all other branches. It is meant to
be used to supersede old development history of side
branches. Note that this is different from the -Xours option to
the 'recursive' merge strategy.
the 'ort' merge strategy.

subtree::
This is a modified `ort` strategy. When merging trees A and
Expand Down
2 changes: 0 additions & 2 deletions Documentation/technical/sparse-checkout.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -356,8 +356,6 @@ understanding these differences can be beneficial.
The behavior for these commands somewhat depends upon the merge
strategy being used:
* `ort` behaves as described above
* `recursive` tries to not vivify files unnecessarily, but does sometimes
vivify files without conflicts.
* `octopus` and `resolve` will always vivify any file changed in the merge
relative to the first parent, which is rather suboptimal.

Expand Down
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1069,7 +1069,6 @@ LIB_OBJS += merge-blobs.o
LIB_OBJS += merge-ll.o
LIB_OBJS += merge-ort.o
LIB_OBJS += merge-ort-wrappers.o
LIB_OBJS += merge-recursive.o
LIB_OBJS += merge.o
LIB_OBJS += midx.o
LIB_OBJS += midx-write.o
Expand Down
10 changes: 5 additions & 5 deletions builtin/checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include "merge-ll.h"
#include "lockfile.h"
#include "mem-pool.h"
#include "merge-recursive.h"
#include "merge-ort-wrappers.h"
#include "object-name.h"
#include "object-store-ll.h"
#include "parse-options.h"
Expand Down Expand Up @@ -907,10 +907,10 @@ static int merge_working_tree(const struct checkout_opts *opts,
o.branch1 = new_branch_info->name;
o.branch2 = "local";
o.conflict_style = opts->conflict_style;
ret = merge_trees(&o,
new_tree,
work,
old_tree);
ret = merge_ort_nonrecursive(&o,
new_tree,
work,
old_tree);
if (ret < 0)
exit(128);
ret = reset_tree(new_tree,
Expand Down
4 changes: 2 additions & 2 deletions builtin/merge-recursive.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "advice.h"
#include "gettext.h"
#include "hash.h"
#include "merge-recursive.h"
#include "merge-ort-wrappers.h"
#include "object-name.h"

static const char builtin_merge_recursive_usage[] =
Expand Down Expand Up @@ -89,7 +89,7 @@ int cmd_merge_recursive(int argc,
if (o.verbosity >= 3)
printf(_("Merging %s with %s\n"), o.branch1, o.branch2);

failed = merge_recursive_generic(&o, &h1, &h2, bases_count, bases, &result);
failed = merge_ort_generic(&o, &h1, &h2, bases_count, bases, &result);

free(better1);
free(better2);
Expand Down
23 changes: 3 additions & 20 deletions builtin/merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
#include "rerere.h"
#include "help.h"
#include "merge.h"
#include "merge-recursive.h"
#include "merge-ort-wrappers.h"
#include "resolve-undo.h"
#include "remote.h"
Expand Down Expand Up @@ -171,7 +170,7 @@ static struct strategy *get_strategy(const char *name)
struct strategy *ret;
static struct cmdnames main_cmds = {0}, other_cmds = {0};
static int loaded;
char *default_strategy = getenv("GIT_TEST_MERGE_ALGORITHM");
char *default_strategy = NULL;

if (!name)
return NULL;
Expand Down Expand Up @@ -750,12 +749,8 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,

repo_hold_locked_index(the_repository, &lock,
LOCK_DIE_ON_ERROR);
if (!strcmp(strategy, "ort"))
clean = merge_ort_recursive(&o, head, remoteheads->item,
reversed, &result);
else
clean = merge_recursive(&o, head, remoteheads->item,
reversed, &result);
clean = merge_ort_recursive(&o, head, remoteheads->item,
reversed, &result);
free_commit_list(reversed);
strbuf_release(&o.obuf);

Expand Down Expand Up @@ -1316,12 +1311,6 @@ int cmd_merge(int argc,
if (branch)
skip_prefix(branch, "refs/heads/", &branch);

if (!pull_twohead) {
char *default_strategy = getenv("GIT_TEST_MERGE_ALGORITHM");
if (default_strategy && !strcmp(default_strategy, "ort"))
pull_twohead = xstrdup("ort");
}

init_diff_ui_defaults();
git_config(git_merge_config, NULL);

Expand Down Expand Up @@ -1522,12 +1511,6 @@ int cmd_merge(int argc,
fast_forward = FF_NO;
}

if (!use_strategies && !pull_twohead &&
remoteheads && !remoteheads->next) {
char *default_strategy = getenv("GIT_TEST_MERGE_ALGORITHM");
if (default_strategy)
append_strategy(get_strategy(default_strategy));
}
if (!use_strategies) {
if (!remoteheads)
; /* already up-to-date */
Expand Down
5 changes: 0 additions & 5 deletions builtin/rebase.c
Original file line number Diff line number Diff line change
Expand Up @@ -1575,11 +1575,6 @@ int cmd_rebase(int argc,
options.default_backend);
}

if (options.type == REBASE_MERGE &&
!options.strategy &&
getenv("GIT_TEST_MERGE_ALGORITHM"))
options.strategy = xstrdup(getenv("GIT_TEST_MERGE_ALGORITHM"));

switch (options.type) {
case REBASE_MERGE:
options.state_dir = merge_dir();
Expand Down
2 changes: 0 additions & 2 deletions builtin/revert.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,6 @@ static int run_sequencer(int argc, const char **argv, const char *prefix,
free(opts->strategy);
opts->strategy = xstrdup_or_null(strategy);
}
if (!opts->strategy && getenv("GIT_TEST_MERGE_ALGORITHM"))
opts->strategy = xstrdup(getenv("GIT_TEST_MERGE_ALGORITHM"));
free(options);

if (cmd == 'q') {
Expand Down
1 change: 0 additions & 1 deletion ci/run-build-and-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ linux-breaking-changes)
linux-TEST-vars)
export OPENSSL_SHA1_UNSAFE=YesPlease
export GIT_TEST_SPLIT_INDEX=yes
export GIT_TEST_MERGE_ALGORITHM=recursive
export GIT_TEST_FULL_IN_PACK_ARRAY=true
export GIT_TEST_OE_SIZE=10
export GIT_TEST_OE_DELTA_SIZE=5
Expand Down
2 changes: 1 addition & 1 deletion merge-ort-wrappers.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef MERGE_ORT_WRAPPERS_H
#define MERGE_ORT_WRAPPERS_H

#include "merge-recursive.h"
#include "merge-ort.h"

/*
* rename-detecting three-way merge, no recursion.
Expand Down
Loading
Loading