commit-reach: guard !FIND_ALL early exit with generation ordering check

When paint_down_to_common() falls back to commit-date ordering (for
v1 commit graphs without corrected commit dates), the !FIND_ALL early
exit incorrectly fires.  The exit assumes the queue is generation-
ordered, so the first RESULT commit found must be the shallowest.
With date ordering this is not guaranteed: a closer merge base with
a lower committer date (clock skew) may still be in the queue behind
deeper commits.

Add a gen_ordered flag that is cleared when the date fallback fires,
and require it for the early exit.

Update the test from the previous commit to test_expect_success.

Signed-off-by: Kristofer Karlsson <krka@spotify.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
jch
Kristofer Karlsson 2026-06-29 13:19:21 +00:00 committed by Junio C Hamano
parent 18cf52c8a5
commit ae68032a8d
2 changed files with 8 additions and 4 deletions

View File

@ -59,11 +59,14 @@ static int paint_down_to_common(struct repository *r,
{
struct prio_queue queue = { compare_commits_by_gen_then_commit_date };
int i;
int gen_ordered = 1;
timestamp_t last_gen = GENERATION_NUMBER_INFINITY;
struct commit_list **tail = result;

if (!min_generation && !corrected_commit_dates_enabled(r))
if (!min_generation && !corrected_commit_dates_enabled(r)) {
queue.compare = compare_commits_by_commit_date;
gen_ordered = 0;
}

one->object.flags |= PARENT1;
if (!n) {
@ -98,11 +101,12 @@ static int paint_down_to_common(struct repository *r,
commit->object.flags |= RESULT;
tail = commit_list_append(commit, tail);
/*
* The queue is generation-ordered; no
* remaining common ancestor can be a
* When the queue is generation-ordered,
* no remaining common ancestor can be a
* descendant of this one.
*/
if (!(mb_flags & MERGE_BASE_FIND_ALL) &&
gen_ordered &&
generation < GENERATION_NUMBER_INFINITY)
break;
}

View File

@ -958,7 +958,7 @@ test_expect_success 'merge-base without --all is one of --all results' '
grep -F -f single all
'

test_expect_failure 'merge-base without --all, clock skew, v1 commit-graph' '
test_expect_success 'merge-base without --all, clock skew, v1 commit-graph' '
git rev-parse skew-M2 >expect &&
merge_base_all_modes skew-P1 skew-P2
'