Skip to content

perf(adopt): scope to local branches, walk chains on demand (v0.2.25)#24

Merged
rohoswagger merged 2 commits into
mainfrom
perf/adopt-local-only
May 20, 2026
Merged

perf(adopt): scope to local branches, walk chains on demand (v0.2.25)#24
rohoswagger merged 2 commits into
mainfrom
perf/adopt-local-only

Conversation

@rohoswagger
Copy link
Copy Markdown
Owner

Summary

ez adopt no longer scans every PR in the repo. On onyx (~10k PRs) adopting 12 local PRs went from ~120s to ~1.4s.

The old get_all_pr_statuses paginated through every PR ever opened just to find the few that matter. Now each mode does targeted fetches:

Default — ez adopt

One GraphQL call: PR statuses for local branches only. No ancestor expansion. If a local PR's base isn't local-with-PR or trunk, we warn and skip with a hint to use --pr <N> for explicit chain walking.

ez adopt feat/a feat/b

Fetch the named branches' PRs, then expand_ancestor_chains walks bases iteratively, one GraphQL batch per stack level. Bounded by stack depth.

ez adopt --pr <N>

New github::get_pr_by_number — one GraphQL call to look up the PR by number, returning head branch + PrInfo. Then expand chain like --branches.

Smoke test (onyx, ~10k PRs, 12 local branches with PRs)

ez adopt
Found 12 branch(es) to adopt
  #10429 fix-minio-default-start → … (base: `main`)
  #9083  nikg/metrics-1a-memory-delta → … (base: `main`)
  #9087  nikg/metrics-1b-redis-pool   → … (base: `nikg/metrics-1a-memory-delta`)
  #9089  nikg/metrics-1c-event-loop-lag → … (base: `nikg/metrics-1b-redis-pool`)
  ... (8 more)
✓ Adopted 12 branch(es), 0 already tracked
[ok | 1.4s]

Note the correctly-chained 3-deep stack (metrics-1a1b1c): default mode picks up multi-level stacks for free, because each level's PR base is another local branch in the fetch set.

Tests

5 new unit tests, 219 total pass:

  • expand_ancestor_chains fetches missing parents until trunk (verified with a stubbed fetcher).
  • Terminates when a base has no upstream PR (no infinite loop on tried set).
  • No fetches when all bases are already trunk.
  • orphan_local_prs flags branches with non-local non-trunk bases.
  • Orphan warning order is sorted (deterministic).

Internal refactor

  • expand_ancestor_chains_with(prs, trunk, fetch) takes the fetcher as a closure so tests can stub the network without setting up a fake gh.
  • orphan_local_prs(prs, trunk) -> Vec<&String> extracts the "what would build_adopt_graph drop?" logic from run.
  • Removed dead filter_prs_for_requested_branches and chain_to_trunk that the old global-scan flow needed.
  • get_all_pr_statuses is no longer called anywhere; left in place with its existing tests for now.

Test plan

  • cargo test — 219 pass
  • cargo fmt --all -- --check clean
  • cargo clippy -- -D warnings clean on lib code
  • ez adopt smoke test on onyx — 1.4s adopts 12 local PRs including a 3-deep stack

ez adopt now uses targeted GraphQL lookups instead of paginating every
PR in the repo. On onyx (~10k PRs) this drops the time to adopt 12
local PRs from ~120s to ~1.4s.

Default mode (no args):
  - Fetch PRs only for local branches via get_pr_statuses_for.
  - No ancestor expansion. Local PRs whose base isn't local-with-PR or
    trunk are warned about with a hint to use ez adopt --pr <N> to walk
    the remote chain explicitly.

--branches <names>:
  - Fetch named branches, then expand_ancestor_chains walks bases
    iteratively, fetching one batch per stack level via GraphQL.
  - Bounded by stack depth, not repo PR count.

--pr <N>:
  - Adds github::get_pr_by_number — single GraphQL call for one PR by
    number, returning head branch + info.
  - Same chain expansion as --branches.

Internal:
  - Extract expand_ancestor_chains_with that takes the fetcher as a
    closure so tests can stub the network.
  - Extract orphan_local_prs helper for sorted, deterministic warnings.
  - Remove obsolete filter_prs_for_requested_branches and chain_to_trunk
    that the global-scan flow needed.

5 new unit tests:
  - expand_ancestor_chains fetches missing parents until trunk.
  - terminates when base has no upstream PR (no infinite loop on tried).
  - no fetches when all bases are already trunk.
  - orphan_local_prs flags branches with non-local non-trunk bases.
  - orphan output is sorted (deterministic warning order).

Bumps version to 0.2.25.
Cleanup of comments that just restated function names or obvious code.
Kept the two WHYs that matter: tried set prevents infinite loop on
broken chains, default mode deliberately skips expansion to avoid
re-introducing per-PR network cost.
@rohoswagger rohoswagger merged commit b4d3ac1 into main May 20, 2026
4 checks passed
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