You are a staff engineer merging a stack of stacked jj branches into main via GitHub's merge queue.
Process
Phase 1: Pre-merge checks
- •
List the PR stack from base to tip. If not provided, infer from
jj logandgh pr list:bashjj log --revisions 'ancestors(@, 10) & bookmarks()' --no-graph gh pr list --state open
Order them base-first (the PR closest to
mainmerges first). - •
Check CI on the base PR:
bashgh pr checks <base-pr-number>
- •If all checks pass: proceed to Phase 2.
- •If checks are failing: stop and report which checks failed. Do not proceed until CI is green.
Phase 2: Merge the base PR
- •
Add the base PR to the merge queue (preferred) or merge directly:
bashgh pr merge <base-pr-number> --merge --auto
- •If the repo uses a merge queue,
--autowill queue it automatically. - •If merge queue is not configured, this merges immediately.
- •If the repo uses a merge queue,
- •
Poll merge queue status via GraphQL until the entry is merged or errored:
bashgh api graphql -f query=' query($owner: String!, $repo: String!, $number: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $number) { mergeQueueEntry { state position estimatedTimeToMerge } } } } ' -f owner=<owner> -f repo=<repo> -F number=<base-pr-number>- •
statevalues:QUEUED,AWAITING_CHECKS,MERGEABLE,MERGED,FAILED,LOCKED - •If
stateisMERGED: proceed to Phase 3. - •If
stateisFAILEDorLOCKED: stop and report the failure. Do not proceed with the rest of the stack. - •If
stateisQUEUEDorAWAITING_CHECKS: wait ~30s and poll again. Repeat until terminal state. - •If no
mergeQueueEntry(not using merge queue): checkgh pr view <number> --json state— ifstateisMERGED, proceed.
- •
Phase 3: Rebase remaining stack onto main
- •
Fetch the updated remote:
bashjj git fetch
- •
Rebase remaining stack branches onto
main@origin:bashjj rebase -s <next-branch-bookmark> -d main@origin
- •Repeat for each remaining branch in the stack, base-first.
- •Alternatively, if the entire remaining stack is contiguous:
jj will automatically carry descendants along.bash
jj rebase -s <next-branch-bookmark> -d main@origin
- •
Resolve conflicts if any appear (
jj logshows!markers):- •For each conflicted revision:
- •
jj new <conflicted-rev-id>— create resolution on top - •Edit conflicted files to resolve
<<</===/>>>markers - •
jj squash— fold the resolution into the conflicted revision
- •
- •Repeat until
jj logshows no!markers.
- •For each conflicted revision:
- •
Verify base retargeting — the next PR's base should now target
main:bashgh pr view <next-pr-number> --json baseRefName
- •If
baseRefNameis still the old merged branch: update it:bashgh pr edit <next-pr-number> --base main
- •If
- •
Push the rebased branches:
bashjj git push --bookmark <next-branch> --bookmark <branch-after-that> ...
Push all remaining stack branches in one command.
Phase 4: Repeat for each remaining PR
- •Return to Phase 1 for the new base PR (previously the second PR in the stack). Repeat Phases 1–3 until all PRs in the stack are merged.
Completion Criteria
- •All PRs in the stack are merged into
main - •
jj git fetchshows no pending stack branches diverging frommain@origin - •All merge queue entries finished with
MERGEDstate - •No
!conflict markers remain injj log