aboutsummaryrefslogtreecommitdiffstats
path: root/merge-ort.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2025-03-29 16:39:07 +0900
committerJunio C Hamano <gitster@pobox.com>2025-03-29 16:39:07 +0900
commiteb7923be1ff0a81e9ce5849f6a6202a4d9e9d0f2 (patch)
tree8e047980a95ba3bd635db1ea0b48ca9351c225c0 /merge-ort.c
parent8d6413a1bef7876b9c17a79358bd70b764ffacba (diff)
parent947e219fb6b1acc3d276d0b50ebf411c252a40bd (diff)
downloadgit-eb7923be1ff0a81e9ce5849f6a6202a4d9e9d0f2.tar.gz
Merge branch 'en/merge-ort-prepare-to-remove-recursive'
First step of deprecating and removing merge-recursive. * en/merge-ort-prepare-to-remove-recursive: am: switch from merge_recursive_generic() to merge_ort_generic() merge-ort: fix merge.directoryRenames=false t3650: document bug when directory renames are turned off merge-ort: support having merge verbosity be set to 0 merge-ort: allow rename detection to be disabled merge-ort: add new merge_ort_generic() function
Diffstat (limited to 'merge-ort.c')
-rw-r--r--merge-ort.c53
1 files changed, 46 insertions, 7 deletions
diff --git a/merge-ort.c b/merge-ort.c
index b0ff2236af..e328511e19 100644
--- a/merge-ort.c
+++ b/merge-ort.c
@@ -3405,6 +3405,11 @@ static int collect_renames(struct merge_options *opt,
pool_diff_free_filepair(&opt->priv->pool, p);
continue;
}
+ if (opt->detect_directory_renames == MERGE_DIRECTORY_RENAMES_NONE &&
+ p->status == 'R' && 1) {
+ possibly_cache_new_pair(renames, p, side_index, NULL);
+ goto skip_directory_renames;
+ }
new_path = check_for_directory_rename(opt, p->two->path,
side_index,
@@ -3422,6 +3427,7 @@ static int collect_renames(struct merge_options *opt,
if (new_path)
apply_directory_rename_modifications(opt, p, new_path);
+skip_directory_renames:
/*
* p->score comes back from diffcore_rename_extended() with
* the similarity of the renamed file. The similarity is
@@ -3449,6 +3455,11 @@ static int detect_and_process_renames(struct merge_options *opt)
if (!possible_renames(renames))
goto cleanup;
+ if (!opt->detect_renames) {
+ renames->redo_after_renames = 0;
+ renames->cached_pairs_valid_side = 0;
+ goto cleanup;
+ }
trace2_region_enter("merge", "regular renames", opt->repo);
detection_run |= detect_regular_renames(opt, MERGE_SIDE1);
@@ -4879,9 +4890,9 @@ static inline void set_commit_tree(struct commit *c, struct tree *t)
c->maybe_tree = t;
}
-static struct commit *make_virtual_commit(struct repository *repo,
- struct tree *tree,
- const char *comment)
+struct commit *make_virtual_commit(struct repository *repo,
+ struct tree *tree,
+ const char *comment)
{
struct commit *commit = alloc_commit_node(repo);
@@ -5021,7 +5032,8 @@ static void merge_start(struct merge_options *opt, struct merge_result *result)
trace2_region_leave("merge", "allocate/init", opt->repo);
}
-static void merge_check_renames_reusable(struct merge_result *result,
+static void merge_check_renames_reusable(struct merge_options *opt,
+ struct merge_result *result,
struct tree *merge_base,
struct tree *side1,
struct tree *side2)
@@ -5047,6 +5059,26 @@ static void merge_check_renames_reusable(struct merge_result *result,
}
/*
+ * Avoid using cached renames when directory rename detection is
+ * turned off. Cached renames are far less important in that case,
+ * and they lead to testcases with an interesting intersection of
+ * effects from relevant renames optimization, trivial directory
+ * resolution optimization, and cached renames all converging when
+ * the target of a cached rename is in a directory that
+ * collect_merge_info() does not recurse into. To avoid such
+ * problems, simply disable cached renames for this case (similar
+ * to the rename/rename(1to1) case; see the "disabling the
+ * optimization" comment near that case).
+ *
+ * This could be revisited in the future; see the commit message
+ * where this comment was added for some possible pointers.
+ */
+ if (opt->detect_directory_renames == MERGE_DIRECTORY_RENAMES_NONE) {
+ renames->cached_pairs_valid_side = 0; /* neither side valid */
+ return;
+ }
+
+ /*
* Handle other cases; note that merge_trees[0..2] will only
* be NULL if opti is, or if all three were manually set to
* NULL by e.g. rename/rename(1to1) handling.
@@ -5187,6 +5219,8 @@ static void merge_ort_internal(struct merge_options *opt,
ancestor_name = "empty tree";
} else if (merge_bases) {
ancestor_name = "merged common ancestors";
+ } else if (opt->ancestor) {
+ ancestor_name = opt->ancestor;
} else {
strbuf_add_unique_abbrev(&merge_base_abbrev,
&merged_merge_bases->object.oid,
@@ -5252,7 +5286,7 @@ void merge_incore_nonrecursive(struct merge_options *opt,
trace2_region_enter("merge", "merge_start", opt->repo);
assert(opt->ancestor != NULL);
- merge_check_renames_reusable(result, merge_base, side1, side2);
+ merge_check_renames_reusable(opt, result, merge_base, side1, side2);
merge_start(opt, result);
/*
* Record the trees used in this merge, so if there's a next merge in
@@ -5276,8 +5310,13 @@ void merge_incore_recursive(struct merge_options *opt,
{
trace2_region_enter("merge", "incore_recursive", opt->repo);
- /* We set the ancestor label based on the merge_bases */
- assert(opt->ancestor == NULL);
+ /*
+ * We set the ancestor label based on the merge_bases...but we
+ * allow one exception through so that builtin/am can override
+ * with its constructed fake ancestor.
+ */
+ assert(opt->ancestor == NULL ||
+ (merge_bases && !merge_bases->next));
trace2_region_enter("merge", "merge_start", opt->repo);
merge_start(opt, result);