summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--merge-ort.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/merge-ort.c b/merge-ort.c
index 6f81795846..7e624fcd36 100644
--- a/merge-ort.c
+++ b/merge-ort.c
@@ -1147,8 +1147,36 @@ static int collect_merge_info_callback(int n,
struct tree_desc t[3];
void *buf[3] = {NULL, NULL, NULL};
const char *original_dir_name;
- int i, ret;
+ int i, ret, side;
+ /*
+ * Check for whether we can avoid recursing due to one side
+ * matching the merge base. The side that does NOT match is
+ * the one that might have a rename destination we need.
+ */
+ assert(!side1_matches_mbase || !side2_matches_mbase);
+ side = side1_matches_mbase ? MERGE_SIDE2 :
+ side2_matches_mbase ? MERGE_SIDE1 : MERGE_BASE;
+ if (filemask == 0 && (dirmask == 2 || dirmask == 4)) {
+ /*
+ * Also defer recursing into new directories; set up a
+ * few variables to let us do so.
+ */
+ ci->match_mask = (7 - dirmask);
+ side = dirmask / 2;
+ }
+ if (renames->dir_rename_mask != 0x07 &&
+ side != MERGE_BASE &&
+ renames->deferred[side].trivial_merges_okay &&
+ !strset_contains(&renames->deferred[side].target_dirs,
+ pi.string)) {
+ strintmap_set(&renames->deferred[side].possible_trivial_merges,
+ pi.string, renames->dir_rename_mask);
+ renames->dir_rename_mask = prev_dir_rename_mask;
+ return mask;
+ }
+
+ /* We need to recurse */
ci->match_mask &= filemask;
newinfo = *info;
newinfo.prev = info;
@@ -1202,7 +1230,6 @@ static int collect_merge_info_callback(int n,
return mask;
}
-MAYBE_UNUSED
static int handle_deferred_entries(struct merge_options *opt,
struct traverse_info *info)
{
@@ -1291,6 +1318,8 @@ static int collect_merge_info(struct merge_options *opt,
trace2_region_enter("merge", "traverse_trees", opt->repo);
ret = traverse_trees(NULL, 3, t, &info);
+ if (ret == 0)
+ ret = handle_deferred_entries(opt, &info);
trace2_region_leave("merge", "traverse_trees", opt->repo);
return ret;