Skip to content

Commit 885f006

Browse files
newrengitster
authored andcommitted
merge-ort: avoid repeating fill_tree_descriptor() on the same tree
Three-way merges, by their nature, are going to often have two or more trees match at a given subdirectory. We can avoid calling fill_tree_descriptor() on the same tree by checking when these trees match. Noting when various oids match will also be useful in other calculations and optimizations as well. Signed-off-by: Elijah Newren <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d2bc199 commit 885f006

File tree

1 file changed

+22
-4
lines changed

1 file changed

+22
-4
lines changed

merge-ort.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,15 @@ static int collect_merge_info_callback(int n,
223223
unsigned mbase_null = !(mask & 1);
224224
unsigned side1_null = !(mask & 2);
225225
unsigned side2_null = !(mask & 4);
226+
unsigned side1_matches_mbase = (!side1_null && !mbase_null &&
227+
names[0].mode == names[1].mode &&
228+
oideq(&names[0].oid, &names[1].oid));
229+
unsigned side2_matches_mbase = (!side2_null && !mbase_null &&
230+
names[0].mode == names[2].mode &&
231+
oideq(&names[0].oid, &names[2].oid));
232+
unsigned sides_match = (!side1_null && !side2_null &&
233+
names[1].mode == names[2].mode &&
234+
oideq(&names[1].oid, &names[2].oid));
226235

227236
/* n = 3 is a fundamental assumption. */
228237
if (n != 3)
@@ -275,10 +284,19 @@ static int collect_merge_info_callback(int n,
275284
newinfo.pathlen = st_add3(newinfo.pathlen, p->pathlen, 1);
276285

277286
for (i = MERGE_BASE; i <= MERGE_SIDE2; i++) {
278-
const struct object_id *oid = NULL;
279-
if (dirmask & 1)
280-
oid = &names[i].oid;
281-
buf[i] = fill_tree_descriptor(opt->repo, t + i, oid);
287+
if (i == 1 && side1_matches_mbase)
288+
t[1] = t[0];
289+
else if (i == 2 && side2_matches_mbase)
290+
t[2] = t[0];
291+
else if (i == 2 && sides_match)
292+
t[2] = t[1];
293+
else {
294+
const struct object_id *oid = NULL;
295+
if (dirmask & 1)
296+
oid = &names[i].oid;
297+
buf[i] = fill_tree_descriptor(opt->repo,
298+
t + i, oid);
299+
}
282300
dirmask >>= 1;
283301
}
284302

0 commit comments

Comments
 (0)