Stacked pull requests: the diff size is a decision nobody reviews
GitHub now ships stacked pull requests as a first-class workflow. What changes is not version control: it is the size of every review, the moment CI actually runs, and whether a dependency is written down or remembered.
Manifold Studio · automotive search & data

Audio briefing
Listen to this insight
Extraction-ready summary
- A stack is a dependency chain made explicit: the bottom pull request targets the trunk, each layer above targets the branch below it, and anything a layer depends on must live in that layer or lower.
- Branch protection and CI in a stack are evaluated against the bottom pull request base branch but enforced on every layer, closing the gap where mid-stack work merged on a check that never ran against it.
- Merging happens bottom-up, so choosing where to stop merging is a release decision rather than an engineering detail.
- Stacks only work inside a single repository, with no cross-fork support and no GitHub Desktop support, and the rebasing that used to make them expensive is now handled server-side or by the gh stack extension.
Two weeks of work, one branch, one pull request. The diff holds four hundred files, the reviewer opens it on a phone, scrolls twice, and approves it on trust.
Nothing in that sentence is a discipline problem. It is what the tool rewarded. A pull request is the unit of review, and for most of its life its size has been set by whenever someone happened to stop working, not by what a person could actually read.
GitHub has now made stacked pull requests a documented, first-class workflow rather than a convention a few engineering teams defended in blog posts. The mechanics are worth understanding even if nobody on your team types git all day, because what a stack changes is not version control. It changes when CI runs, what a reviewer is asked to hold in their head, and whether a dependency between two pieces of work is written down or merely remembered.
What a stack actually is
Two or more pull requests in the same repository, arranged as a chain. The bottom pull request targets the trunk, usually main. Each pull request above it targets the branch of the one below.
- PR #1
feat/auth-layer→ basemain - PR #2
feat/api-endpoints→ basefeat/auth-layer - PR #3
feat/frontend→ basefeat/api-endpoints
Each layer shows only the diff between its branch and the branch beneath it, so a reviewer reading layer three sees three files, not four hundred.
The governing rule is one sentence, and it is the whole design: if code in one layer depends on code in another, the dependency must live in the same branch or a lower one. Shared types and schema go at the bottom. API routes sit above them. The interface sits above that. You start a new branch when you change material, when the work moves from backend to frontend, from logic to tests, or when the current branch has grown past what one person can review in one sitting.
The diff size is a business decision nobody signs off on
On the marketing side of a dealership, the change that reaches production is rarely one thing. The inventory feed schema changes, the vehicle detail page has to read the new field, the parts filter needs a new facet, and the confirmation email has to stop showing the old attribute. Four concerns, three reviewers, four different owners of the outcome.
Without a stack, that becomes one branch because splitting it means rebasing four branches against each other every morning for a week. And splitting it means the branch protection rules and the CI checks fire on the bottom pull request only, so the middle layers merge on a green check that never ran against them. So the work lands as one pull request, and the reviewer approves the part they understand and trusts the rest.
A stack makes the same work arrive as four reviewable decisions with the dependencies stated rather than implied. That is the real product. Not speed, not elegance: the removal of a category of approval that was never an approval.
CI that only ever ran at the bottom
This is the part that matters to anyone who has to sign off on a release.
In a stack, the merge requirements for every pull request are determined by the bottom pull request's base branch, normally main. Branch protection rules, including CODEOWNER approvals, are enforced on every pull request in the stack, including the mid-stack ones that never touch the default branch. CI checks that a pull request against the default branch would trigger run for all layers, not just the bottom one.
Read that in operational terms. The bar you set for production now applies to every layer of the work, which means a stack cannot be used to sneak a half-reviewed layer in behind a well-reviewed one. The bottom layer sets the standard and the whole chain inherits it.
The rebase was the reason most teams never did this
Stacked branches have been a known technique for a decade. Almost nobody ran them, for one reason: rebasing. Merge the bottom pull request and every branch above it is now based on a branch that no longer exists, so somebody spends a morning replanting three branches by hand and fixing the same conflict three times.
GitHub removed that step. Cascading rebases run server-side from the pull request, or locally through the gh stack extension in GitHub CLI, and when the bottom pull request merges the remaining branches are rebased automatically and the next pull request re-targets the default base branch. The manual labour that made stacks a hobby is gone, and the only thing left to argue about is whether your team wants to work this way.
Merging is bottom-up, and that makes it a release decision
A stack merges from the bottom. You can merge the entire stack by merging the top pull request, and everything below it comes along. You can merge one pull request, or a portion of the stack. Whatever you merge, the layers above stay open and re-target the stack's base branch automatically.
The whole stack does not have to land at once, and the resulting history is the same as merging each pull request individually, bottom first. Merge commits, squash and rebase are all supported, and stacks are merge-queue aware.
Which means the merge point is a business decision wearing an engineering costume. Merging the middle of a stack ships everything below it. If the release calendar, the OEM review window or a seasonal parts promotion cares what goes live on Thursday, then someone has to name the layer at which the stack stops.
The volume argument, and the risk inside it
The docs are direct about why this exists now: when you generate a lot of code at once, often with AI agents, a stack gives each change somewhere to go. An agent finishes one task, starts the next task that builds on it, and each task becomes one pull request based on the one below. The dependency is recorded explicitly instead of being collapsed into a single branch with unrelated changes in it.
Hold both halves of that. Yes, a stack gives generated work a place to go and a reviewable shape. It also makes inheritance visible: a wrong decision in layer two is now sitting underneath five layers that were reviewed on their own terms, and the stack map shows you exactly how much depends on it. That is better than the alternative, which is the same mistake hidden inside one enormous branch. But it is not a safety net. Someone still has to read layer two.
Where it stops working
Stacks require every branch to live in the same repository, so cross-fork stacks are not supported, and GitHub Desktop does not support stacked pull requests at all. If your model is an agency working from a fork, or a vendor whose work arrives as a fork, the workflow constrains how you split the work before it constrains anything else.
The practical failure mode is boundary choice. Split layers by file and you get four pull requests that all need to merge together to mean anything. Split by concern and each layer is a decision with its own reviewer: schema, then endpoints, then interface, then tests. The second kind merges in pieces. The first kind is a large pull request with extra bookkeeping.
The other failure is time. A stack that lives for three weeks is a stack that gets rebased into a different argument than the one it started.
What to change on Monday
- Draw the layers by concern, not by directory. Schema and types at the bottom, then the data layer, then the interface, then tests.
- Start a new branch where the material changes, and where the current branch stops being readable in one sitting.
- Keep stacks short. A stack is a review structure, not a naming convention for long-running work.
- Protect the trunk and let the chain inherit the bar, rather than writing separate rules for layers.
- Decide the merge point before you open the top pull request, and say out loud what shipping means.
- For agent-generated work, one task, one layer, one pull request, with the dependency made explicit.
None of this is a version control argument. It is the same argument this desk keeps making about handoffs in a dealership: the cost of a decision nobody could see is paid later, by someone whose name is not on it, in the form of rework. A pull request nobody read is a decision nobody made. A stack at least asks you to name the layers.
Creative compliance gate
No creative reaches a flight before the manufacturer signs it off.
Every piece of creative named in this insight, including anything produced with AI assistance, clears the brand’s review before media spend, organic scheduling or event capture goes live. The four rules below are the ones that keep a campaign on its date.
- 01
Submit the asset pack, not the idea
Stills, cut-downs, captions, alt text and end cards travel together, with the intended flight dates attached. Reviews stall on packages that arrive in pieces.
- 02
Build the review into the flight date
Two to three weeks covers most OEM programs. Any clip carrying a product claim, an incentive or a co-op match needs longer, and a launch week is the wrong time to find that out.
- 03
Nothing flies unapproved
That includes the "test" post, the organic support cut and the paid boost of an organic clip. If it is public, it was published, and compliance will treat it that way.
- 04
Store the approval with the asset
Keep the sign-off reference and its expiry alongside the creative. Reusing an approved cut saves the next review; reusing an expired one restarts it.
Answer engine fuel
Questions buyers actually ask
Are stacked pull requests a new Git feature?
No. A stack is ordinary branches and ordinary pull request bases: the bottom pull request targets the trunk and each one above targets the branch below it. What is new is the tooling around it, including cascading rebases from the pull request or through the gh stack extension, a stack map in the merge box, webhook and API support, and a gh-stack skill for agents.
Do I have to merge the whole stack at once?
No. You can merge the entire stack by merging the top pull request, merge a single pull request, or merge a portion of the stack. Pull requests must merge from the bottom up, so merging a mid-stack layer lands everything below it while the layers above stay open and automatically re-target the base branch. Merge commits, squash and rebase are all supported and stacks are merge-queue aware.
What breaks a stack workflow first?
Layer boundaries chosen by file rather than by concern, and stacks that stay open too long. The mechanical limits are that every branch must be in the same repository, cross-fork stacks are not supported, and GitHub Desktop does not support stacked pull requests.
Do branch protection rules and CI checks apply to mid-stack pull requests?
Yes. Merge requirements for every pull request in the stack are determined by the bottom pull request base branch, normally main. Branch protection rules such as CODEOWNER approvals are enforced on every pull request including mid-stack ones, and CI checks triggered by pull requests on the default branch run for all layers, not just the bottom one.
Primary sources
Filed under Infrastructure
More from this desk →Read next
The duplicate stack: an audit that finds what you are paying for twice
Forty-one tools, nineteen actual jobs, eleven jobs with more than one owner. The consolidation audit is a register, four tests and an order of removal, and its real output is not savings. It is a stack small enough that one person can be accountable for it.
InfrastructureGood is the minority: dealer site speed, Core Web Vitals, and the script tax
Across a sample of more than 3,300 dealer domains, most pages fail the field thresholds on mobile. The cause is rarely the platform. It is the number of things we asked the page to load.