Skip to content

Commit 5e1ca57

Browse files
newrengitster
authored andcommitted
merge-ort: defer recursing into directories when merge base is matched
When one side of history matches the merge base (including when the merge base has no entry for the given directory), have collect_merge_info_callback() defer recursing into the directory. To ensure those entries are eventually handled, add a call to handled_deferred_entries() in collect_merge_info() after traverse_trees() returns. Note that the condition in collect_merge_info_callback() may look more complicated than necessary at first glance; renames->trivial_merges_okay[side] is always true until handle_deferred_entries() is called, and possible_trivial_merges[side] is always empty right now (and in the future won't be filled until handle_deferred_entries() is called). However, when handle_deferred_entries() calls traverse_trees() for the relevant deferred directories, those traverse_trees() calls will once again end up in collect_merge_info_callback() for all the entries under those subdirectories. The extra conditions are there for such deferred cases and will be used more as we do more with those variables. Signed-off-by: Elijah Newren <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e0ef578 commit 5e1ca57

File tree

1 file changed

+31
-2
lines changed

1 file changed

+31
-2
lines changed

merge-ort.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,8 +1147,36 @@ static int collect_merge_info_callback(int n,
11471147
struct tree_desc t[3];
11481148
void *buf[3] = {NULL, NULL, NULL};
11491149
const char *original_dir_name;
1150-
int i, ret;
1150+
int i, ret, side;
11511151

1152+
/*
1153+
* Check for whether we can avoid recursing due to one side
1154+
* matching the merge base. The side that does NOT match is
1155+
* the one that might have a rename destination we need.
1156+
*/
1157+
assert(!side1_matches_mbase || !side2_matches_mbase);
1158+
side = side1_matches_mbase ? MERGE_SIDE2 :
1159+
side2_matches_mbase ? MERGE_SIDE1 : MERGE_BASE;
1160+
if (filemask == 0 && (dirmask == 2 || dirmask == 4)) {
1161+
/*
1162+
* Also defer recursing into new directories; set up a
1163+
* few variables to let us do so.
1164+
*/
1165+
ci->match_mask = (7 - dirmask);
1166+
side = dirmask / 2;
1167+
}
1168+
if (renames->dir_rename_mask != 0x07 &&
1169+
side != MERGE_BASE &&
1170+
renames->deferred[side].trivial_merges_okay &&
1171+
!strset_contains(&renames->deferred[side].target_dirs,
1172+
pi.string)) {
1173+
strintmap_set(&renames->deferred[side].possible_trivial_merges,
1174+
pi.string, renames->dir_rename_mask);
1175+
renames->dir_rename_mask = prev_dir_rename_mask;
1176+
return mask;
1177+
}
1178+
1179+
/* We need to recurse */
11521180
ci->match_mask &= filemask;
11531181
newinfo = *info;
11541182
newinfo.prev = info;
@@ -1202,7 +1230,6 @@ static int collect_merge_info_callback(int n,
12021230
return mask;
12031231
}
12041232

1205-
MAYBE_UNUSED
12061233
static int handle_deferred_entries(struct merge_options *opt,
12071234
struct traverse_info *info)
12081235
{
@@ -1291,6 +1318,8 @@ static int collect_merge_info(struct merge_options *opt,
12911318

12921319
trace2_region_enter("merge", "traverse_trees", opt->repo);
12931320
ret = traverse_trees(NULL, 3, t, &info);
1321+
if (ret == 0)
1322+
ret = handle_deferred_entries(opt, &info);
12941323
trace2_region_leave("merge", "traverse_trees", opt->repo);
12951324

12961325
return ret;

0 commit comments

Comments
 (0)