Skip to content

commit-reach: terminate merge-base walk when one paint side is exhausted#2149

Draft
spkrka wants to merge 3 commits into
gitgitgadget:masterfrom
spkrka:side-exhaust-pr
Draft

commit-reach: terminate merge-base walk when one paint side is exhausted#2149
spkrka wants to merge 3 commits into
gitgitgadget:masterfrom
spkrka:side-exhaust-pr

Conversation

@spkrka

@spkrka spkrka commented Jun 13, 2026

Copy link
Copy Markdown

TBD

spkrka added 3 commits June 13, 2026 17:17
Remove the nonstale_queue struct and move max_nonstale tracking into
local variables in paint_down_to_common() and ahead_behind(). The
queue helpers now take struct prio_queue directly, with max_nonstale
passed as an explicit pointer parameter.

This separates the ENQUEUED-flag dedup logic from the nonstale
tracking, preparing for per-side termination where paint_down_to_common
will track max_parent1 and max_parent2 independently instead of a
single max_nonstale.

No functional change.

Signed-off-by: Kristofer Karlsson <krka@spotify.com>
Track the deepest non-stale PARENT1 and PARENT2 commits independently
in paint_down_to_common().  Once the walk enters the finite-generation
region (topological order guaranteed by commit-graph), terminate early
when one side is exhausted from the queue -- no new merge-base can
form without both paint sides meeting.

The key correctness concern is in-place flag mutation: a commit
already in the queue can gain a new paint flag via
p->object.flags |= flags without being re-inserted (ENQUEUED dedup).
This could create a non-stale {P1,P2} commit that the per-side max
tracking does not know about.  Handle this by updating the per-side
max trackers at flag-mutation time: if a parent that is already
ENQUEUED gains both paint flags (without STALE), bump the max
pointers so the side-exhaustion check does not fire prematurely.

On large monorepos with commit-graph, this yields 300-1000x speedups
for merge-base queries where one side (e.g. a PR branch) is much
smaller than the other.

Signed-off-by: Kristofer Karlsson <krka@spotify.com>
Add tests for the case where multiple merge-base candidates
exist and one is an ancestor of another.  This exercises the
side-exhaustion optimization in paint_down_to_common together
with the remove_redundant safety net in get_merge_bases_many_0.

Test with and without commit-graph to verify the optimization
is a no-op when generation numbers are unavailable.

Signed-off-by: Kristofer Karlsson <krka@spotify.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant