🧭 How toSoftwareIntermediate✨ AI-assisted

How to Create Stacked Pull Requests With the gh stack CLI

WittyTech Daily··4 min read
#github#gh-stack#stacked-prs#code-review

Nobody reviews a 40-file pull request. They scroll, sigh and click Approve. The gh stack CLI fixes that by splitting one big change into a chain of small pull requests, each targeting the branch below it, so a reviewer only ever sees one layer.

By the end you will have installed the extension, built and submitted a three-layer stack, fixed a lower layer, and merged the whole thing. Stacked pull requests went generally available on github.com on 6 October 2026 (GitHub changelog). The CLI is a separate gh extension, documented in the command reference.

Install the gh stack CLI

You need GitHub CLI 2.0 or later and Git 2.36 or later. The extension reuses your gh login.

gh auth login
gh extension install github/gh-stack
gh extension list

Skip gh auth login if you are already signed in. gh extension list confirms the install.

Start a stack with gh stack init

# first layer, branched off the repository's default branch
gh stack init feature-auth

# or stack on a different trunk
gh stack init --base develop feature-auth

init creates the branch (or adopts an existing one) and checks it out. It also turns on git rerere, so Git remembers how you resolved a conflict and repeated rebases don't ask twice.

Add layers with gh stack add

# layer 1: commit on feature-auth
git add .
git commit -m "Add login endpoint"

# layer 2: a new branch on top of feature-auth
gh stack add feature-api
git add .
git commit -m "Add session API"

# layer 3
gh stack add feature-ui
git add .
git commit -m "Add login form"

Each add creates a branch on top of the current one. To skip the manual commit, -m commits with your message first, -A stages everything including untracked files, and -u stages tracked files only, as in the reference's gh stack add -Am "Add tests" test-layer.

Check the stack with gh stack view

gh stack view
gh stack view --short
gh stack view --json

--short prints one line per branch and --json is for scripts. To move around, use gh stack up, gh stack down, gh stack top, gh stack bottom or gh stack checkout <branch>.

Submit the stack with gh stack submit

gh stack submit --auto

This pushes every branch and opens linked pull requests. --auto skips the full-screen editor and uses generated titles, and new pull requests are drafts unless you add --open. Leave --auto off in an interactive terminal when you want to edit titles first.

The important part is the base branch. The bottom pull request targets the trunk and every other one targets the branch below it:

main
  feature-auth   base: main
  feature-api    base: feature-auth
  feature-ui     base: feature-api

So the reviewer on feature-api sees only the session API, not the login endpoint underneath it.

Fix a lower layer and rebase the stack

gh stack checkout feature-auth
git add .
git commit -m "Address review feedback"
gh stack rebase --upstack
gh stack push
gh stack top

--upstack rebases every branch from the current one to the top. gh stack push pushes the rebased branches with --force-with-lease. On a conflict the rebase stops and lists the files: resolve them, run git add, then gh stack rebase --continue, or use gh stack rebase --abort to restore every branch to its pre-rebase state.

Merge the stack and use the GitHub merge queue

# merge the whole current stack without prompting, squashing commits
gh stack merge --yes --squash

# merge everything up to and including pull request 102
gh stack merge 102

The merge is all-or-nothing, and branch protection and repository rules still apply.

If the base branch uses a merge queue, gh stack merge ignores the method flags with a warning. Per the merging docs, the stack enters the queue in order, and if one pull request is ejected, every pull request above it is removed too. If the stack stops being linear, for example because trunk moved, the merge box shows a Rebase stack button that does the cascading rebase on the server.

Sync and prune after merging

gh stack sync --prune

sync fetches, fast-forwards trunk, rebases the remaining branches onto it, pushes them and refreshes pull request status. --prune also deletes local branches whose pull requests have merged.

Gotchas

  • All branches must live in one repository. Cross-fork stacks are not supported, and GitHub Desktop does not support stacks.
  • Merge requirements come from the bottom pull request's base branch, and branch protection such as CODEOWNERS approval applies to every pull request in the stack.
  • Stacks merge bottom-up. Merging a mid-stack pull request lands everything below it, and the ones above are retargeted.
  • The changelog says auto-merge for stacks is rolling out over several weeks, while the merging page still says it is unsupported. Check your repository before relying on it.
  • GitHub Enterprise Server does not have stacks yet. The changelog says an upcoming release will.
  • Exit code 9 means stacked pull requests are not enabled for the repository, which is worth catching in scripts.

Small linked pull requests are how a human keeps up with the large diffs coding agents produce, which makes stacks a practical review tool for any team shipping AI-assisted code to production.

← More in Software