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>
Kristofer Karlsson committed
Jun 29, 2026 at 13:19 UTC
ae68032a8d0427bf90bbc316f662320d15933fdc
2 files changed
+8
-4
commit-reach.c
+7
-3
@@ -59,11 +59,14 @@ static int paint_down_to_common(struct repository *r,
59
{
60
struct prio_queue queue = { compare_commits_by_gen_then_commit_date };
61
int i;
62
+ int gen_ordered = 1;
63
timestamp_t last_gen = GENERATION_NUMBER_INFINITY;
64
struct commit_list **tail = result;
65
65
- if (!min_generation && !corrected_commit_dates_enabled(r))
66
+ if (!min_generation && !corrected_commit_dates_enabled(r)) {
67
queue.compare = compare_commits_by_commit_date;
68
+ gen_ordered = 0;
69
+ }
70
71
one->object.flags |= PARENT1;
72
if (!n) {
@@ -98,11 +101,12 @@ static int paint_down_to_common(struct repository *r,
101
commit->object.flags |= RESULT;
102
tail = commit_list_append(commit, tail);
103
/*
101
- * The queue is generation-ordered; no
102
- * remaining common ancestor can be a
104
+ * When the queue is generation-ordered,
105
+ * no remaining common ancestor can be a
106
* descendant of this one.
107
*/
108
if (!(mb_flags & MERGE_BASE_FIND_ALL) &&
109
+ gen_ordered &&
110
generation < GENERATION_NUMBER_INFINITY)
111
break;
112
}
t/t6600-test-reach.sh
+1
-1
@@ -958,7 +958,7 @@ test_expect_success 'merge-base without --all is one of --all results' '
958
grep -F -f single all
959
'
960
961
-test_expect_failure 'merge-base without --all, clock skew, v1 commit-graph' '
961
+test_expect_success 'merge-base without --all, clock skew, v1 commit-graph' '
962
git rev-parse skew-M2 >expect &&
963
merge_base_all_modes skew-P1 skew-P2
964
'