Skip to content

Commit bc97680

Browse files
committed
merge: use repo_in_merge_bases for octopus up-to-date check
The octopus merge path checks whether each remote head is already an ancestor of HEAD by computing all merge-bases via repo_get_merge_bases() and comparing the first result's OID to the remote head. This is more expensive than necessary: repo_get_merge_bases() calls paint_down_to_common() with min_generation=0, performs the full STALE drain, and may run remove_redundant(), when all we need is a yes/no reachability answer. Replace this with repo_in_merge_bases(), which answers the is-ancestor question directly. When generation numbers are available, repo_in_merge_bases() uses can_all_from_reach() -- a DFS bounded by generation number that stops as soon as the target is found or ruled out, without entering paint_down_to_common() at all. Without generation numbers, it still benefits from a tighter min_generation floor. Signed-off-by: Kristofer Karlsson <krka@spotify.com>
1 parent 94f0577 commit bc97680

2 files changed

Lines changed: 14 additions & 14 deletions

File tree

builtin/merge.c

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,21 +1735,11 @@ int cmd_merge(int argc,
17351735
struct commit_list *j;
17361736

17371737
for (j = remoteheads; j; j = j->next) {
1738-
struct commit_list *common_one = NULL;
1739-
struct commit *common_item;
1740-
1741-
/*
1742-
* Here we *have* to calculate the individual
1743-
* merge_bases again, otherwise "git merge HEAD^
1744-
* HEAD^^" would be missed.
1745-
*/
1746-
if (repo_get_merge_bases(the_repository, head_commit,
1747-
j->item, &common_one) < 0)
1738+
int ret = repo_in_merge_bases(the_repository,
1739+
j->item, head_commit);
1740+
if (ret < 0)
17481741
exit(128);
1749-
1750-
common_item = common_one->item;
1751-
commit_list_free(common_one);
1752-
if (!oideq(&common_item->object.oid, &j->item->object.oid)) {
1742+
if (!ret) {
17531743
up_to_date = 0;
17541744
break;
17551745
}

t/t6408-merge-up-to-date.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,14 @@ test_expect_success 'merge fast-forward octopus' '
8989
test "$expect" = "$current"
9090
'
9191

92+
test_expect_success 'merge octopus already up to date' '
93+
94+
git reset --hard c2 &&
95+
test_tick &&
96+
git merge c0 c1 &&
97+
expect=$(git rev-parse c2) &&
98+
current=$(git rev-parse HEAD) &&
99+
test "$expect" = "$current"
100+
'
101+
92102
test_done

0 commit comments

Comments
 (0)