Skip to content

Commit 6d35474

Browse files
Perf: Don't perform merge operations for trivial merges.
When one side of a merge is treesame to the ancestor, we can take the other side and skip all the expensive merge operations. This optimization can only be performed when the generation of REUC extension data is skipped.
1 parent a7df4a9 commit 6d35474

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

src/merge.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2018,6 +2018,26 @@ int git_merge_trees(
20182018
git_iterator_options iter_opts = GIT_ITERATOR_OPTIONS_INIT;
20192019
int error;
20202020

2021+
assert(out && repo);
2022+
2023+
/* if one side is treesame to the ancestor, take the other side */
2024+
if (ancestor_tree && merge_opts && (merge_opts->flags & GIT_MERGE_SKIP_REUC)) {
2025+
const git_tree *result = NULL;
2026+
const git_oid *ancestor_tree_id = git_tree_id(ancestor_tree);
2027+
2028+
if (our_tree && !git_oid_cmp(ancestor_tree_id, git_tree_id(our_tree)))
2029+
result = their_tree;
2030+
else if (their_tree && !git_oid_cmp(ancestor_tree_id, git_tree_id(their_tree)))
2031+
result = our_tree;
2032+
2033+
if (result) {
2034+
if ((error = git_index_new(out)) == 0)
2035+
error = git_index_read_tree(*out, result);
2036+
2037+
return error;
2038+
}
2039+
}
2040+
20212041
iter_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
20222042

20232043
if ((error = git_iterator_for_tree(

0 commit comments

Comments
 (0)