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>
seen
Kristofer Karlsson 2026-07-11 13:27:44 +00:00 committed by Junio C Hamano
parent 8df944d32a
commit 3adb597b2a
1 changed files with 18 additions and 13 deletions

View File

@ -90,6 +90,8 @@ struct paint_state {
size_t parent2_count;
size_t mb_candidate_count;
int gen_ordered;
timestamp_t min_generation;
timestamp_t last_gen;
};

static void paint_count_update(struct paint_state *state,
@ -139,11 +141,23 @@ static void paint_queue_put(struct paint_state *state,
static struct commit *paint_queue_get(struct paint_state *state)
{
struct commit *commit = prio_queue_get(&state->queue);
timestamp_t generation;

if (!commit)
return NULL;

commit->object.flags &= ~ENQUEUED;
generation = commit_graph_generation(commit);

if (state->min_generation && generation > state->last_gen)
BUG("bad generation skip %"PRItime" > %"PRItime" at %s",
generation, state->last_gen,
oid_to_hex(&commit->object.oid));
state->last_gen = generation;

/* generation cutoff */
if (generation < state->min_generation)
return NULL;

if (!state->mb_candidate_count) {
/* only stale entries remain */
@ -153,7 +167,7 @@ static struct commit *paint_queue_get(struct paint_state *state)
/* one side is exhausted */
if ((!state->parent1_count || !state->parent2_count) &&
state->gen_ordered &&
commit_graph_generation(commit) < GENERATION_NUMBER_INFINITY)
generation < GENERATION_NUMBER_INFINITY)
return NULL;
}

@ -180,9 +194,10 @@ static int paint_down_to_common(struct repository *r,
struct commit *commit;
int i;
int steps = 0;
timestamp_t last_gen = GENERATION_NUMBER_INFINITY;
struct commit_list **tail = result;

state.min_generation = min_generation;
state.last_gen = GENERATION_NUMBER_INFINITY;
if (!min_generation && !corrected_commit_dates_enabled(r)) {
state.queue.compare = compare_commits_by_commit_date;
state.gen_ordered = 0;
@ -201,18 +216,8 @@ static int paint_down_to_common(struct repository *r,
while ((commit = paint_queue_get(&state))) {
struct commit_list *parents;
int flags;
timestamp_t generation = commit_graph_generation(commit);
steps++;

if (min_generation && generation > last_gen)
BUG("bad generation skip %"PRItime" > %"PRItime" at %s",
generation, last_gen,
oid_to_hex(&commit->object.oid));
last_gen = generation;

if (generation < min_generation)
break;

flags = commit->object.flags & (PARENT1 | PARENT2 | STALE);
if (flags == (PARENT1 | PARENT2)) {
if (!(commit->object.flags & RESULT)) {
@ -225,7 +230,7 @@ static int paint_down_to_common(struct repository *r,
*/
if (!(mb_flags & MERGE_BASE_FIND_ALL) &&
state.gen_ordered &&
generation < GENERATION_NUMBER_INFINITY)
state.last_gen < GENERATION_NUMBER_INFINITY)
break;
}
/* Mark parents of a found merge stale */