Manage GitHub PR stacks
Use gh stack for a linear chain in which each branch builds on the branch
below it and each PR targets that lower branch.
(trunk) <- models <- api <- ui
bottom top
up moves toward the top; down moves toward trunk. A stack is linear, so
parallel children require separate stacks.
Inspect before changing
- Confirm the repository, worktree status, current branch, remotes, and
gh auth status. - Preserve staged and unstaged user changes. Do not clean, unstage, or rewrite them unless explicitly requested.
- Run
gh stack view --jsonwhen local stack state exists. Treat it as the canonical machine-readable view. - Resolve the actual trunk and push remote rather than assuming
mainandorigin. - Before any push or submit, inspect applicable branch rules and the exact branches and PRs that will change.
Install the extension only when missing:
gh extension install github/gh-stack
When multiple remotes exist, pass --remote <name> where supported or set the
repository's intended push remote:
git config remote.pushDefault <name>
Keep automation non-interactive
| Operation | Automation-safe form |
|---|---|
| Inspect | gh stack view --json (preferred) or --short |
| Initialize | gh stack init --base <trunk> <bottom> ... <top> |
| Add | gh stack add <branch> |
| Submit | gh stack submit --auto [--open] [--remote <name>] |
| Checkout | gh stack checkout <stack-or-pr-or-branch> |
| Merge | gh stack merge <target> --yes --<method> |
Bare view, argumentless init, add, or checkout, and submit without
--auto may prompt. modify is a TUI-only workflow and has no non-interactive
mode. Never launch an interactive command and leave it waiting for input.
Route the task
| Task | Read first |
|---|---|
| Plan a new stack or split existing work | stack-design.md |
| Execute or verify a command | commands.md |
| Resolve conflicts, divergence, or interrupted state | troubleshooting.md |
Read only the references needed for the task. For restructuring, read both stack design and troubleshooting before changing ancestry or metadata.
Build and edit deliberately
For new work, create the intended layer before writing it when practical:
gh stack init --base <trunk> <bottom-branch>
# edit, stage exact paths, test, commit
gh stack add <next-branch>
# edit, stage exact paths, test, commit
Put shared types, schemas, APIs, and utilities below their consumers. Keep one cohesive story per stack and put unrelated work in another stack.
When a higher layer needs a lower-layer correction:
- Determine the owning layer. If unclear, inspect
git log --all -- <path>. - Navigate to it with
down,bottom, orcheckout <branch>. - Edit, stage exact paths, test, and commit there.
- Run
gh stack rebase --upstackto replay dependent layers. - Return to the previous layer, verify the stack, then push or submit.
Do not hide a foundational change in an upper PR merely to avoid a rebase.
Control generated PR bodies
gh stack submit can add a GitHub Stacks CLI attribution footer when it creates
a PR without a non-empty repository PR template, and the inspected CLI has no
opt-out flag. If the footer is unacceptable or the user wants full control of
every PR body:
- Push the stack with
gh stack push --remote <name>. - Create each missing PR explicitly with
gh pr create, using the parent branch as--baseand the layer branch as--head. - Run
gh stack submit --auto --remote <name>to link and update those existing PRs.
A non-empty default PR template also prevents the generated footer path, but it replaces the generated commit-derived body. Pre-creating PRs is the explicit, predictable option. See commands.md for details.
Synchronize and recover safely
Use gh stack sync --remote <name> for routine fetch, rebase, push, and PR-state
reconciliation. Add --prune only when local deletion of merged branches is
explicitly intended.
Exit code 3 needs different handling by command:
- Failed
rebase: resolve, stage, thengh stack rebase --continue, or abort. - Failed
sync: sync already restores all branches. Rungh stack rebaseto recreate the conflict, then resolve and continue.
If local and GitHub stack compositions diverge, non-interactive sync can print
Sync aborted while exiting 0. Inspect output as well as the exit code.
Respect mutation boundaries
push,submit,sync,link, andmergecan mutate remote state; run only the operation the user authorized and verify the resulting state.submitis not status-only: it may push branches, create PRs, correct bases, and update stack metadata. Preflight it accordingly.- A request to commit, push, submit, publish, or fix checks does not authorize a
merge, merge queue, or auto-merge. Run
gh stack mergeonly when governing instructions permit it and the user explicitly requests that exact action. - Never bypass branch protection or required workflows. Treat a reported bypass as failure and stop further remote mutation.
- Never delete branches or PRs merely to repair stack metadata unless deletion is explicitly requested.
- Push and submit are not transactionally all-or-nothing. After failure, inspect local branches, remote refs, PR bases, and stack state before retrying.
After any remote mutation, verify independently with gh stack view --json and
targeted gh pr view or gh pr list queries.