GitHub Stacked Pull Requests: What Changed in Preview
In this piece
GitHub announced stacked pull requests in public preview on July 30. The workflow is older than the announcement. Developers have built dependent branches, opened one pull request per branch, and rebased the chain by hand for years. Dedicated tools made that less painful. GitHub itself saw unrelated pull requests with unusual base branches.
GitHub now recognizes the chain as one stack. It shows how the pull requests relate, applies rules and checks to each layer, rebases remaining branches after a partial merge, and can land several layers in one operation. The official gh stack extension manages the local branches.
You still choose where one reviewable change ends and the next begins. Native support removes the bookkeeping while leaving dependency design to you.
A stack is an ordered review structure
GitHub defines a stack as two or more pull requests in the same repository. The bottom pull request targets a trunk branch, usually main, though it can target a release branch or another base. Every pull request above it targets the branch immediately below.
That base relationship narrows each diff. If PR 2 targets the branch for PR 1, its review page shows what PR 2 adds rather than the two changes combined. The top branch still contains everything beneath it in Git history, while reviewers see only what that layer adds.
The ordering encodes dependencies. Code in a layer may depend on its own branch or a lower one. It must not depend on a higher layer. The branch bases turn that dependency graph into a review workflow.
Independent changes should remain separate pull requests against the same trunk. A stack makes a stronger claim: its pieces are separate review units with a required order.
The preview does not choose the boundaries
The feature removes coordination work after a team has already made a design decision. It cannot decide whether a type, its consumer, and a follow-up logging change are three useful reviews or one implementation split across three URLs.
Use a small request-ID change to see the distinction. A RequestID type can be reviewed and merged before HTTP middleware consumes it. Middleware can be reviewed before logging decides which fields belong in every request record. That is a dependency chain with three possible approval points.
The same three commits could also be one pull request. If the type only exists to support a middleware function, and no reviewer could reasonably approve it in isolation, a stack adds bases, notifications, and checks without creating a smaller decision. The ordering is real in Git history, but it is not yet a review structure.
GitHub keeps that judgment with the author and reviewers. Its CLI can initialize a stack, add branches, submit pull requests, rebase dependent branches, synchronize remote state, and merge a contiguous lower portion. The platform still needs a coherent bottom layer, a reviewer who understands the order, and checks that reflect what each layer can prove.
That division is healthy. A tool can preserve an existing dependency order. It cannot make an arbitrary order useful.
The distinction also keeps merge order honest. A lower pull request may be safe to land while an upper layer remains a local experiment. A branch-first workflow often creates every branch before that answer exists. Native stacks make the later maintenance easier, but they do not make an unfinished layer review-ready.
What GitHub now automates
The public preview makes GitHub understand and act on that order.
GitHub can rebase the chain
Rebasing is the main cost of stacked work. Merge the bottom pull request and the next branch needs a new base, then the same conflict reappears two layers up. The promise of smaller reviews starts to look expensive.
GitHub now documents server-side cascading rebases, while gh stack can cascade the rebase locally. When a lower pull request merges, GitHub rebases the branches above it so the next open pull request targets the stack’s base branch.
GitHub moves the branches; reviewers still judge whether the rewritten code is correct.
Protections apply to every layer
A mid-stack pull request may target another feature branch rather than main. Before native support, that could put it outside rules designed for the default branch.
In a GitHub stack, merge requirements come from the bottom pull request’s base branch. GitHub enforces branch protections, including CODEOWNER approvals, on every pull request in the stack. GitHub Actions workflows triggered for pull requests to the default branch also run for every layer.
Reviewers can trust a layer when GitHub applies the required checks and approvals to it, even when the layer’s base is another feature branch.
The same protections on every layer multiply CI work. Three layers can mean three check runs.
The merge operation understands portions of a stack
GitHub supports full-stack, partial-stack, and single-pull-request merges, always in dependency order.
Merge the top pull request and GitHub lands every unmerged layer beneath it. Merge a pull request in the middle and GitHub lands that layer plus the lower ones. Higher pull requests stay open, then rebase and retarget to the stack’s base. Merge methods can be merge commit, squash, or rebase.
A team can land the foundation without pretending that the dependent feature is ready. GitHub rebases and retargets the remaining branches after that decision.
Reviewers can see the whole chain
On github.com, a stack map appears in the merge box. It shows the pull requests, their order, and their status. A layer indicator at the top of the page makes the current position explicit.
This replaces conventions such as handwritten “depends on #123” notes as the only map. Those notes can still explain intent, while the platform supplies navigation and state.
Automation can inspect and change stacks
GitHub has added stack support for APIs and webhooks. Pull request webhooks include stack data. REST endpoints can list, create, extend, and dissolve stacks. GraphQL exposes read-only stack fields, so automation can inspect a stack through GraphQL but must use REST to change it.
Existing bots that merge stacks must use GitHub’s new asynchronous merge endpoint.
Stacks work across GitHub interfaces
The documented interfaces are github.com, GitHub CLI, GitHub Mobile, webhooks, REST, GraphQL, and an agent skill. GitHub Desktop does not support stacks, and every branch must live in the same repository. GitHub does not support cross-fork stacks either.
A maintainer cannot turn a contributor’s fork-based pull request and a maintainer-owned follow-up into one native stack.
What GitHub still needs from you
Before any automation helps, you decide where to cut the stack.
GitHub’s rule: if code in one layer depends on code in another, the dependency must be in the same branch or a lower branch. GitHub can verify the branch order; you choose the conceptual order.
You still decide:
- whether the work contains dependent review units at all;
- which foundation belongs at the bottom;
- whether each layer is coherent enough to review and test;
- how many layers are useful before navigation and CI become overhead;
- which reviewers need which context;
- whether to merge the foundation now or wait for the full stack;
- whether squash, rebase, or merge commits preserve the history you want.
You decide which threshold each layer must meet. Reviewable, testable, mergeable, and deployable describe different thresholds. A request-ID type can be easy to review and safe to merge before any endpoint uses it. Middleware may compile only after the type exists. Logging propagation may be useful only after every lower layer lands. GitHub tracks the order and readiness checks.
If reviewers must open the higher layer to understand a given one, the layer is not reviewable on its own. Moving a helper between files does not create a useful review unit.
Good commits and stacked PRs solve different problems
Commits structure repository history. They affect git log, bisecting, reverting, and how a change survives after merge. Pull requests structure review work. They hold discussions, approvals, checks, ownership rules, and merge decisions.
One branch can contain three beautiful commits and still produce one pull request with one combined review queue. A reviewer can inspect it commit by commit, but GitHub still treats the whole pull request as the approval and merge unit.
A stack makes the dependency boundaries explicit at the pull-request level. Consider the shared Go example for this series:
- COMMIT A · PR 1Request-ID type
- commit follows; PR 2 bases on PR 1
- COMMIT B · PR 2HTTP middleware
- commit follows; PR 3 bases on PR 2
- COMMIT C · PR 3Logging propagation
Git records one ordered commit history. GitHub turns each layer into a separate pull request, with the same dependency order and a narrower review surface.
The code dependency is identical in both views. Reviewers get three review units in the stacked view: each carries its own discussion, checks, approvals, and readiness decision. They can review the second layer while work continues on the third, and the first can merge while the third remains unfinished.
The official CLI handles the local half
GitHub’s server can understand a stack created on the website, but branches still live in a local repository. The official github/gh-stack extension handles that side of the workflow.
Install it with:
gh extension install github/gh-stackThe extension can initialize a stack, add layers, publish branches, submit pull requests, display the graph, rebase, check out a remote stack, and merge. It stores ordering metadata in .git/gh-stack, keeps interrupted-rebase state in .git/gh-stack-rebase-state, and enables Git’s recorded-resolution reuse, rerere, when initializing a stack.
GitHub also publishes an agent integration through gh skill install github/gh-stack. The skill supplies the commands, but the agent still needs tasks arranged in a sound dependency order.
For a complete three-layer Go walkthrough, continue with Your First GitHub Stack. To shape the same dependency chain before publishing branches, see Stacked Changes with Jujutsu.
The preview’s current limits
GitHub marks the feature as a public preview subject to change. The announcement describes a staged rollout, including merge queue support.
The hard limits are one repository, no cross-fork stacks, and no GitHub Desktop support. The launch sources do not confirm GitHub Enterprise Server support.
Before relying on stacks, create a disposable two-layer example in the target repository. Confirm that a middle pull request shows the expected diff, required workflows and CODEOWNERS apply, and your merge queue or merge bot accepts the stack. That test checks the repository’s actual controls without putting a release-critical migration at risk.
When a normal pull request is better
Most changes still belong in one normal pull request.
Use a normal pull request when the change is already one coherent review unit. A small bug fix, a dependency bump, a revert, or a focused security patch gains nothing from an extra branch and another check run.
Use separate normal pull requests for independent changes. If two branches can both target main without depending on each other, ordering them creates a false dependency. That makes rebases, reviews, and merges more constrained for no technical reason.
Fork-based contributions need normal pull requests because the preview requires same-repository branches. Teams standardized on GitHub Desktop also lack a supported stack workflow today. Repositories that require a merge queue should verify rollout before making a stack the only route to main.
A larger change does not always deserve a stack. Splitting by file count or line count hides one concept behind several approvals. A useful layer exists for a reason: a dependency boundary, a distinct risk, a different owner, or a merge decision that can stand on its own.
What changed
GitHub now records stack relationships and automates base tracking, cascading rebases, per-layer protections and CI, navigation, and partial or full landing. The official CLI handles local branch operations.
You still decide how to split and order the work. GitHub preserves that order.
Filed under
Explore this subject