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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
struct commit_list *j;
for (j = remoteheads; j; j = j->next) {
- struct commit_list *common_one = NULL;
- struct commit *common_item;
-
- /*
- * Here we *have* to calculate the individual
- * merge_bases again, otherwise "git merge HEAD^
- * HEAD^^" would be missed.
- */
- if (repo_get_merge_bases(the_repository, head_commit,
- j->item, &common_one) < 0)
+ int ret = repo_in_merge_bases(the_repository,
+ j->item, head_commit);
+ if (ret < 0)
exit(128);
-
- common_item = common_one->item;
- commit_list_free(common_one);
- if (!oideq(&common_item->object.oid, &j->item->object.oid)) {
+ if (!ret) {
up_to_date = 0;
break;
}
test "$expect" = "$current"
'
+test_expect_success 'merge octopus already up to date' '
+
+ git reset --hard c2 &&
+ test_tick &&
+ git merge c0 c1 &&
+ expect=$(git rev-parse c2) &&
+ current=$(git rev-parse HEAD) &&
+ test "$expect" = "$current"
+'
+
test_done