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 <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
d2bc1994f3
commit
885f0063e9
26
merge-ort.c
26
merge-ort.c
@ -223,6 +223,15 @@ static int collect_merge_info_callback(int n,
|
|||||||
unsigned mbase_null = !(mask & 1);
|
unsigned mbase_null = !(mask & 1);
|
||||||
unsigned side1_null = !(mask & 2);
|
unsigned side1_null = !(mask & 2);
|
||||||
unsigned side2_null = !(mask & 4);
|
unsigned side2_null = !(mask & 4);
|
||||||
|
unsigned side1_matches_mbase = (!side1_null && !mbase_null &&
|
||||||
|
names[0].mode == names[1].mode &&
|
||||||
|
oideq(&names[0].oid, &names[1].oid));
|
||||||
|
unsigned side2_matches_mbase = (!side2_null && !mbase_null &&
|
||||||
|
names[0].mode == names[2].mode &&
|
||||||
|
oideq(&names[0].oid, &names[2].oid));
|
||||||
|
unsigned sides_match = (!side1_null && !side2_null &&
|
||||||
|
names[1].mode == names[2].mode &&
|
||||||
|
oideq(&names[1].oid, &names[2].oid));
|
||||||
|
|
||||||
/* n = 3 is a fundamental assumption. */
|
/* n = 3 is a fundamental assumption. */
|
||||||
if (n != 3)
|
if (n != 3)
|
||||||
@ -275,10 +284,19 @@ static int collect_merge_info_callback(int n,
|
|||||||
newinfo.pathlen = st_add3(newinfo.pathlen, p->pathlen, 1);
|
newinfo.pathlen = st_add3(newinfo.pathlen, p->pathlen, 1);
|
||||||
|
|
||||||
for (i = MERGE_BASE; i <= MERGE_SIDE2; i++) {
|
for (i = MERGE_BASE; i <= MERGE_SIDE2; i++) {
|
||||||
const struct object_id *oid = NULL;
|
if (i == 1 && side1_matches_mbase)
|
||||||
if (dirmask & 1)
|
t[1] = t[0];
|
||||||
oid = &names[i].oid;
|
else if (i == 2 && side2_matches_mbase)
|
||||||
buf[i] = fill_tree_descriptor(opt->repo, t + i, oid);
|
t[2] = t[0];
|
||||||
|
else if (i == 2 && sides_match)
|
||||||
|
t[2] = t[1];
|
||||||
|
else {
|
||||||
|
const struct object_id *oid = NULL;
|
||||||
|
if (dirmask & 1)
|
||||||
|
oid = &names[i].oid;
|
||||||
|
buf[i] = fill_tree_descriptor(opt->repo,
|
||||||
|
t + i, oid);
|
||||||
|
}
|
||||||
dirmask >>= 1;
|
dirmask >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user