commit-reach: move min_generation check into paint_queue_get()

Consolidate the min_generation termination condition into paint_queue_get(), alongside the existing stale-entry and side-exhaustion checks. Move last_gen into struct paint_state so that commit_graph_generation() is called exactly once per dequeued commit and the result is shared across all termination checks and the monotonicity BUG assertion. Signed-off-by: Kristofer Karlsson <krka@spotify.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Kristofer Karlsson committed Jul 11, 2026 at 13:27 UTC 3adb597b2aceceb3d1ad97b56e2d62b30fc9bb64
1 file changed +18 -13
commit-reach.c
+18 -13
@@ -90,6 +90,8 @@ struct paint_state {
90 size_t parent2_count;
91 size_t mb_candidate_count;
92 int gen_ordered;
93 + timestamp_t min_generation;
94 + timestamp_t last_gen;
95 };
96
97 static void paint_count_update(struct paint_state *state,
@@ -139,11 +141,23 @@ static void paint_queue_put(struct paint_state *state,
141 static struct commit *paint_queue_get(struct paint_state *state)
142 {
143 struct commit *commit = prio_queue_get(&state->queue);
144 + timestamp_t generation;
145
146 if (!commit)
147 return NULL;
148
149 commit->object.flags &= ~ENQUEUED;
150 + generation = commit_graph_generation(commit);
151 +
152 + if (state->min_generation && generation > state->last_gen)
153 + BUG("bad generation skip %"PRItime" > %"PRItime" at %s",
154 + generation, state->last_gen,
155 + oid_to_hex(&commit->object.oid));
156 + state->last_gen = generation;
157 +
158 + /* generation cutoff */
159 + if (generation < state->min_generation)
160 + return NULL;
161
162 if (!state->mb_candidate_count) {
163 /* only stale entries remain */
@@ -153,7 +167,7 @@ static struct commit *paint_queue_get(struct paint_state *state)
167 /* one side is exhausted */
168 if ((!state->parent1_count || !state->parent2_count) &&
169 state->gen_ordered &&
156 - commit_graph_generation(commit) < GENERATION_NUMBER_INFINITY)
170 + generation < GENERATION_NUMBER_INFINITY)
171 return NULL;
172 }
173
@@ -180,9 +194,10 @@ static int paint_down_to_common(struct repository *r,
194 struct commit *commit;
195 int i;
196 int steps = 0;
183 - timestamp_t last_gen = GENERATION_NUMBER_INFINITY;
197 struct commit_list **tail = result;
198
199 + state.min_generation = min_generation;
200 + state.last_gen = GENERATION_NUMBER_INFINITY;
201 if (!min_generation && !corrected_commit_dates_enabled(r)) {
202 state.queue.compare = compare_commits_by_commit_date;
203 state.gen_ordered = 0;
@@ -201,18 +216,8 @@ static int paint_down_to_common(struct repository *r,
216 while ((commit = paint_queue_get(&state))) {
217 struct commit_list *parents;
218 int flags;
204 - timestamp_t generation = commit_graph_generation(commit);
219 steps++;
220
207 - if (min_generation && generation > last_gen)
208 - BUG("bad generation skip %"PRItime" > %"PRItime" at %s",
209 - generation, last_gen,
210 - oid_to_hex(&commit->object.oid));
211 - last_gen = generation;
212 -
213 - if (generation < min_generation)
214 - break;
215 -
221 flags = commit->object.flags & (PARENT1 | PARENT2 | STALE);
222 if (flags == (PARENT1 | PARENT2)) {
223 if (!(commit->object.flags & RESULT)) {
@@ -225,7 +230,7 @@ static int paint_down_to_common(struct repository *r,
230 */
231 if (!(mb_flags & MERGE_BASE_FIND_ALL) &&
232 state.gen_ordered &&
228 - generation < GENERATION_NUMBER_INFINITY)
233 + state.last_gen < GENERATION_NUMBER_INFINITY)
234 break;
235 }
236 /* Mark parents of a found merge stale */