Developer Tools

GitHub Finally Built Stacked PRs. The Engineering Argument Is Not What You Think.

GitHub Finally Built Stacked PRs. The Engineering Argument Is Not What You Think.

GitHub Finally Built Stacked PRs. The Engineering Argument Is Not What You Think.

On July 30, 2026, GitHub shipped stacked pull requests into public preview. Within hours the HN thread hit 700+ points, which is a reliable signal that a feature has been wanted for a long time by a lot of engineers. Tim Neutkens from Vercel is quoted saying it helped Next.js ship larger features. John Resig called it “incredible.” The GitHub blog post has testimonials from TED’s CTO and a connectivity engineer at WHOOP.

All of that is real. And none of it is the interesting part.

The interesting part is what the feature’s design choices reveal about GitHub’s theory of software development—and where that theory conflicts with what developers at Google, Meta, and large open-source projects have known for fifteen years. Because GitHub did not build the thing that the Phabricator and Gerrit crowd wanted. They built something adjacent to it, and the difference matters enormously for how this plays out.

I have spent time both in environments with native stacked-diff tooling and in pure GitHub shops. The gap between those two experiences is not subtle. But neither is the gap between what GitHub shipped and what a genuinely diff-centric review system looks like. Understanding the distinction requires going back to first principles on what makes large-change review hard.

Why Stacked Changes Exist: The Actual Problem

The reason stacked PRs matter is not that individual PRs are too big. It is that the unit of reviewable work—the diff—does not correspond to the unit of logical change. When you are building a feature that requires a database migration, an API layer, a service integration, and a frontend component, those pieces are logically coupled but technically separable. A reviewer looking at all four together faces a cognitive load problem: they cannot hold the whole system in their head while also evaluating whether each piece is correct.

The classical solution, from Phabricator at Facebook and Gerrit at Google, was to make the review unit the commit (or a small patch set), not the branch. Each logical step in a sequence gets its own review object. Crucially, those review objects know about each other. They form a chain. When you review the API layer, you see only the API layer diff—not the database migration underneath it. The tooling handles the stacking, rebasing, and sequencing. You think in terms of logical changes; the tool handles the mechanical dependency graph.

GitHub’s model is different. The fundamental unit is still the branch, and therefore still the pull request. What stacked PRs add is the ability to chain branches: branch B targets branch A, which targets main. When A merges, B automatically retargets to main and rebases. The PR review experience for B still shows you all the commits on branch B—it does not show you just the diff between A and B in a way that is decoupled from the commit history on that branch.

This is a meaningful distinction. It is not fatal—many teams will find the GitHub approach workable—but pretending the two are equivalent would be wrong.

What GitHub Actually Shipped

Let me be precise about what public preview includes, because the HN thread conflates several things.

The core mechanic is branch-targeting: you create a stack of branches, each targeting the one below it. The gh extension install github/gh-stack CLI manages this. You can create stacks from the terminal or from github.com. Each PR in the stack shows a “stack map” at the top of the page, so reviewers can see where in the chain they are looking.

Merging works in two modes. You can merge individual layers, which triggers automatic rebasing of the layers above. Or you can merge the entire stack in one click—the latest ready PR lands and pulls everything below it with it. Branch protections and required checks still apply at each layer.

The CLI also integrates with GitHub Copilot as an agent skill, which is notable and worth coming back to.

What is missing or broken in public preview:

  • Squash-and-merge for entire stacks is broken in documented ways. The GitHub team acknowledged this in the HN thread and said fixes are rolling out.
  • Cross-fork stacks are not supported—which means open-source maintainers receiving stacked PRs from external contributors cannot use this workflow. GitHub cited security concerns around automated rebase across fork boundaries.
  • Merge queue support for stacked PRs is rolling out progressively, not immediately available.
  • There is no interdiff support: you cannot diff two arbitrary versions of a PR’s history the way Gerrit allows. Force-push shows a link to the previous state, but comment threading across versions is limited.
Capability GitHub Stacked PRs (preview) Phabricator / Gerrit Graphite (third-party)
Stack visualization Stack map in PR header Dependency graph in UI Full stack dashboard
Unit of review Branch (PR) Commit / patch set Branch (PR)
Automated rebase on merge Yes Yes Yes
Squash-merge entire stack Broken (in progress) N/A (commit-based) Yes
Cross-fork stacks No N/A No
Interdiff / version history Limited (force-push link) Full patch set history Partial
API for external merge queues Yes (async API) N/A Trunk.io integration
Agent/LLM integration Copilot gh-stack skill None None

The Phabricator Argument Is Correct but Incomplete

Several engineers in the HN thread made the point clearly: GitHub built this without engaging seriously with prior art. Phabricator has had stacked diffs since roughly 2013. Gerrit has had them since before that. Meta engineers, Google engineers, and anyone who has worked with large monorepos has been using some form of this for over a decade.

The specific complaint is that GitHub chose branches as the fundamental unit rather than commits or patch sets. One commenter put it this way: “You don’t have to expose change IDs in the UI other than as a secondary thing.” Another asked the GitHub team directly why they chose to require a new branch for each change rather than making commits reviewable in isolation.

The GitHub team’s response in the thread was not satisfying. They acknowledged the design choice but did not articulate why it is correct. The honest answer is probably two things that they could not say publicly: first, changing the fundamental PR model from branch-based to commit-based would require rewriting a huge amount of infrastructure that has accumulated over fifteen years; second, the branch-based model is what the majority of GitHub’s user base understands, and forcing a paradigm shift on 100 million developers to satisfy the 1% who want Gerrit semantics is a bad product decision.

Both of those reasons are legitimate. But they explain a constraint, not a design virtue. The result is a stacked PR system that feels like GitHub with an extra layer rather than a fundamentally better review model.

I have worked in a Phabricator environment. The experience of reviewing a stack where each diff is genuinely isolated—where you open “arc review” for a change and see only and exactly what that change adds relative to its parent—is qualitatively different from reviewing a branch that happens to be targeted at another branch. The cognitive overhead drops significantly. You can hold one piece of the system in your head at a time.

GitHub’s version gets you part of the way there. The stack map helps. The automatic retargeting helps. But the review unit is still the branch, which means the PR for layer 3 shows you all the commits on layer 3, not just the diff between layer 2 and layer 3 in a form that is decoupled from branch history.

Why It Still Matters That GitHub Built It

Despite the design limitations, this is genuinely significant, for three reasons that are not about feature parity with Phabricator.

First, distribution. GitHub has approximately 100 million registered users and is effectively the default code review platform for a generation of developers who have never used Gerrit or Phabricator. Many of those developers work at companies where the code review culture is a single giant PR that sits in queue for two weeks while the author answers comments by force-pushing new commits and everyone loses track of what changed when. Stacked PRs, even in the GitHub branch-based model, are a significant improvement over that baseline. The feature does not have to be as good as Phabricator to be valuable—it has to be better than the alternative that most GitHub users are actually using.

Second, the merge-queue integration. Several companies with large CI budgets are watching the rollout of stacked PR support in merge queues closely. The problem is real: if you have a 30-PR stack and each PR requires 20 minutes of CI to merge, sequential merging takes 10 hours of wall time. If the merge queue can process the whole stack in one operation—running CI once against the combined diff—that is a substantial engineering efficiency gain. Trunk.io already announced integration. The GitHub async merge API enables this at scale in a way that third-party tools like Graphite could not, because Graphite does not own the merge queue.

Third, and most importantly: AI agents.

The AI Agent Angle Is the Real Story

The GitHub blog post mentions the Copilot agent skill for gh-stack almost as an aside. John Resig’s quote touches on it: “the gh cli tools + agent skill help a ton.” But I think this is where the stacked PR feature becomes strategically interesting in a way that has nothing to do with human developer ergonomics.

Consider what AI coding agents do today. A Copilot workspace session, a Devin session, or any autonomous coding agent working on a substantial feature will produce a large batch of changes. The current state of the art is that the agent dumps all of those changes into a single PR, and a human reviewer has to evaluate the entire thing at once. This is the worst possible scenario for code review: a large diff, generated by a system that cannot explain its reasoning conversationally, with no natural decomposition into reviewable units.

Stacked PRs change the architecture of agent-generated code review. An agent that understands the stack API can decompose its own work: “here is the schema change, here is the API layer that depends on it, here is the service integration, here is the frontend.” Each layer becomes independently reviewable. A human reviewer can approve the schema change before the agent proceeds to write the API, catching architectural errors early rather than at the end of a 3000-line PR.

This is not hypothetical. The gh-stack CLI already has a Copilot skill. The GitHub documentation for the stacks REST API is live. The pieces are in place for agents to create and manage stacks natively. The engineering teams building agentic coding systems will integrate with this. It will not take long.

The implication is that stacked PRs solve a slightly different problem than the one being debated in the HN thread. The Phabricator crowd is arguing about the right model for human-to-human code review. That argument is correct on the merits, but it may be less important than the question of how humans review agent-generated code. For that use case, the branch-based GitHub model may actually be better than a commit-based model, because the branch is a more natural unit for an agent to reason about and decompose its work into.

An agent writing a Phabricator-style patch series would need to manage commit history, rebase, and patch set sequencing at a level of Git literacy that current agents handle poorly. A branch-per-layer model maps more directly onto the way agents currently think about work decomposition: generate a complete implementation of one layer, then generate the next layer on top of it.

The Squash-Merge Problem Is Deeper Than a Bug

The broken squash-and-merge for stacks is the most discussed issue in the public preview. But I think the discussion understates how structurally difficult this is.

When you squash-merge a PR, you collapse all the commits on that branch into a single commit on main. This is the dominant merge strategy at many organizations—it keeps the main branch history clean, one commit per feature, easy to bisect. The problem with squash-merging a stack is that the commits on layers 2 and 3 include the commits from layers 1 and 2 respectively, because those layers were branched from each other. Squashing layer 1 into main changes the SHA of what layer 2 is based on, which means layer 2 needs to rebase not just retarget.

GitHub’s CPRMC system (their internal Create Pull Request Merge Commit evaluator) has to evaluate mergeability at each layer, which requires modeling the state of main after each preceding squash. This is a graph problem, not a simple sequential operation. The fact that it is broken in the current preview is not surprising—it is a genuinely hard systems problem—but it is also a problem that teams depending on squash-and-merge (which is most professional teams using protected main branches) will hit immediately.

The GitHub engineer’s response in the thread was measured: they acknowledged it and said fixes are rolling out. I believe them. But the timeline for “rolling out” matters for teams deciding whether to adopt this in production. My guess is that squash-and-merge for full stacks will be stable by Q4 2026, but that is a guess based on the complexity of the problem, not inside information.

The Cross-Fork Problem Is Not Going Away

The cross-fork limitation is more structurally intractable than the squash-merge bug. When someone forks your repository and opens a stacked PR, the automated rebase that happens when you merge a lower layer cannot safely execute in the context of the fork. GitHub cited security concerns—specifically that an automated rebase could execute code in the forked repository’s context with access to secrets and runner credentials from the upstream repository.

This is a real security issue, not an excuse. GitHub Actions runners configured for the upstream repository can be triggered by code changes in pull requests from forks, and that access is carefully scoped precisely because untrusted code runs there. If merging layer 1 of a stack automatically rebases layer 2 in a fork, you have an automated code execution pathway that sidesteps the normal approval gate.

The practical consequence: stacked PRs are a closed-source feature, for now. Open-source projects where external contributors submit patches via fork cannot use this workflow for those contributions. The maintainers can use stacked PRs for their own internal work, but the workflow breaks down for the external contribution model that defines open-source collaboration on GitHub.

This is a meaningful limitation for open-source projects. It also illustrates a general pattern in GitHub’s recent feature development: capabilities that are straightforward to implement for single-organization repositories require significantly more engineering to work safely in the fork-based open-source model. Stacked PRs are not unique in this regard—merge queues had similar fork complications—but it is worth naming explicitly.

What Graphite Built and Why It Is Not Dead

Graphite launched in 2021 with a pitch that was essentially: GitHub will never build native stacked PRs, so we will. The pitch was correct for five years and is now incorrect. That is a difficult position for a company to be in.

But I do not think Graphite is finished. The company built significant functionality beyond the stacking mechanism: a PR dashboard, review assignment workflows, analytics, and a code review experience that is more opinionated than GitHub’s default interface. Those are real product differentiators that do not disappear because GitHub shipped branch-chaining.

More importantly, Graphite has been iterating on this problem for four years. Their squash-and-merge implementation actually works. Their stack visualization is more mature. Their CLI ergonomics are further developed. For teams that adopted Graphite and built workflows around it, the switching cost back to GitHub native is nonzero.

The parallel here is GitHub Pages vs. Netlify, or GitHub Actions vs. CircleCI. GitHub shipping a native version of something does not eliminate the market for better third-party implementations of the same thing. It validates the category and raises the bar. Graphite has to decide whether it can win on quality in a space GitHub now occupies—which is hard—or whether it has adjacent product surface that GitHub is not competing in. My read is that the code review analytics and PR management dashboard are more defensible than the stacking mechanism itself.

What Teams Should Actually Do Right Now

If you are running an engineering organization and trying to decide whether to adopt GitHub’s stacked PR preview, here is my honest assessment broken down by team type.

Small teams (<10 engineers) on squash-and-merge: Wait. The squash-and-merge bug affects you directly and the team is too small to tolerate the friction of working around it. Check back in Q4 2026.

Medium teams (10-100 engineers) on merge commits: Try it. The automated retargeting alone is useful for anyone who has manually managed a 3-4 layer branch chain. The stack map helps reviewers orient. The bugs are less likely to affect you if you are not on squash-and-merge.

Large teams on merge queues: Engage with your merge queue vendor now. Trunk.io has already integrated. If you are running a custom merge queue or using a provider that has not integrated yet, the async API is public and the technical work is straightforward. The CI time savings from stack-aware merge queues are real and measurable.

Open-source maintainers: This is not for your external contributors yet. Use it for your own branch management, not as an expectation you set for community contributions.

Teams with AI coding agents in production: This is worth watching closely. The Copilot skill exists. The REST API is live. If your agent workflow produces large batches of changes, there is a real opportunity to decompose those into stacks and improve review quality. The engineering work to integrate is not trivial but is well-defined.

The Review Culture Problem That Tooling Cannot Fix

One commenter in the HN thread made a point that got fewer upvotes than it deserved: “If you thought git was complex, wait until you get your 5-deep stacked PR from that nice coworker.”

The optimistic reading of stacked PRs is that they enable smaller, more focused changes that are easier to review. The pessimistic reading is that they make it easier to avoid the hard conversation about scope. Instead of telling a contributor that their PR is too large and needs to be decomposed thoughtfully, a manager can say “just stack it” and push the cognitive complexity onto reviewers who now have to evaluate five interconnected PRs instead of one large one.

I have seen both outcomes. The teams where stacked diffs worked well were teams with strong engineering discipline: they used stacking as a tool for logical decomposition, not as a way to avoid scope discussion. The teams where it went badly were teams where “just stack it” became a substitute for architecture review. You ended up with five-deep stacks where layer 3 had a fundamental design flaw that made layers 4 and 5 wrong, but nobody caught it because each layer seemed reasonable in isolation.

The tooling is neutral on this. GitHub’s implementation, Phabricator’s, Graphite’s—none of them prevent bad decomposition. They just make decomposition possible. Whether teams use that capability well depends on review culture, and review culture is not a product feature.

Predictions

Based on what I have seen in the public preview and in the HN discussion, here are specific, falsifiable claims about how this plays out.

By end of Q3 2026: Squash-and-merge for full stacks will be stable. GitHub has the incentive and the engineering capacity to fix this quickly; the preview expansion would have been premature if they were not close to a fix.

By end of 2026: At least one major AI coding agent (Copilot Workspace, Devin, or a comparable system) will announce native stacked PR support as a feature for decomposing agent-generated changes. The infrastructure is in place; the product integration is the remaining work.

By mid-2027: Cross-fork stacks will ship in some limited form—possibly requiring upstream maintainer opt-in and explicit security configuration. The open-source exclusion is a significant enough limitation that GitHub will be pressured to solve it.

By end of 2027: Graphite’s differentiation will have shifted almost entirely away from the stacking mechanism toward the code review analytics, dashboard, and review management features. The stacking feature itself will be table stakes that GitHub provides for free.

The claim I am least confident about: whether the GitHub branch-based model will ever feel as good as Phabricator for teams that have used the commit-based alternative. My gut says no—there is a qualitative difference in how those systems handle interdiffs and patch set history that GitHub’s current design cannot replicate without a fundamental architectural change. But “good enough for most teams” and “as good as Phabricator for heavy users” are different bars, and GitHub only has to clear the first one to win the market.

The Bigger Picture

GitHub shipping stacked PRs is not primarily a story about a new feature. It is a story about the platform finally closing a gap that third parties had been exploiting for years, and doing so in a way that prioritizes compatibility with the existing model over fidelity to the best prior art.

That is the correct call for a platform with 100 million users. You do not redesign the fundamental interaction model for the power users when the power users are 1% of your base. You build something that works for the other 99% and accept that the Phabricator engineers will remain unsatisfied.

What changes is the floor. Before this, a team that wanted stacked PRs had to adopt Graphite, build their own tooling, or suffer through manual branch management. Now the floor is GitHub-native stacking, which is not perfect but is accessible and free. That raises the average quality of code review workflows across the industry, even if it does not satisfy the critics who have Phabricator in their muscle memory.

That is worth something. Possibly a lot, depending on how the AI agent integration develops. The piece I keep coming back to is the agent workflow: if the future of software development involves significantly more agent-generated code, and if review is the primary mechanism by which humans stay in control of what agents produce, then the tooling that structures agent-generated changes into reviewable units becomes critical infrastructure. GitHub is the only platform positioned to make that infrastructure native.

That might turn out to be more important than whether the interdiff viewer matches Gerrit’s.

The CLI Experience and What It Signals About Adoption

The gh-stack CLI extension is worth examining in detail, because CLI design reveals assumptions about the intended user. The install path is gh extension install github/gh-stack, and the basic workflow is: create a branch, make commits, run gh stack pr to create a PR targeting the layer below, repeat for each layer. To merge the full stack, you run gh stack merge from the top layer.

Several things stand out. First, the CLI is an extension, not a first-class gh subcommand. That is a deliberate decision that says: this workflow is not yet assumed to be universal. GitHub is treating stacked PRs as an opt-in power feature rather than the default way to create PRs. Compare this to how merge queues were introduced—initially opt-in, then progressively more encouraged as the default for teams with protected branches.

Second, the CLI extension model means that CI/CD pipelines and automation scripts that interact with PRs have to be updated separately to understand stacks. A script that queries the GitHub API for open PRs and processes them in order may handle stacks incorrectly by treating each layer as an independent PR. This is a migration burden that is invisible in the marketing materials but real for any organization with significant automation built on top of the GitHub API.

Third, the documentation for the stacks REST API is already comprehensive. GitHub built the API before the GUI, which is unusual and suggests they expected programmatic access to be a primary use case. This supports the AI agent hypothesis: the team designing this feature was thinking about systems that create and manipulate PRs programmatically, not just humans clicking through the GitHub web interface.

The combination of a CLI extension and a comprehensive REST API is exactly the right architecture for a feature that is meant to be consumed both by humans and by automated systems. It is a more thoughtful design than it initially appears.

Stack Depth and the Practical Ceiling

One question the documentation does not answer clearly is whether there is a formal limit on stack depth. The examples in the GitHub blog post show three-layer stacks. The HN discussion references five-deep stacks as a theoretical concern. In practice, I would argue the useful ceiling is lower than either of those numbers.

The cognitive overhead of reviewing a stack grows superlinearly with depth. At two layers, a reviewer can hold both pieces in their head simultaneously. At three layers, they need to make conscious choices about ordering—do I review bottom-up or top-down? At four or five layers, the reviewer needs to build a mental model of the entire dependency graph before they can evaluate any individual piece, which partially defeats the purpose.

The teams that use stacked changes most effectively—the ones I have seen at companies with mature monorepo cultures—typically cap their stacks at two to three layers. Beyond that, the decomposition is telling you something: either the feature is too large for a single development cycle, or the boundaries between layers are not clean enough to review independently. Both of those are architectural signals worth heeding.

GitHub’s implementation does not enforce a depth limit, which means teams will have to develop their own norms. This is appropriate—the right depth depends on team size, review culture, and the nature of the changes—but it means that the benefit of the feature is not automatic. Teams that adopt stacked PRs without developing explicit norms about depth and decomposition will likely end up with deep stacks that are harder to review than a single large PR would have been.

Historical Context: Why This Took So Long

GitHub was founded in 2008. Phabricator launched at Facebook around 2011 and was open-sourced in 2012. Gerrit has been in active development since 2008. The stacked-diff pattern has existed as a well-understood, widely-deployed solution to the large-change review problem for roughly fifteen years.

Why did GitHub take this long?

The charitable answer is that GitHub’s model—branch-based PRs, fork-and-pull for open source—is architecturally different from the commit-based models of Gerrit and Phabricator, and retrofitting stacking onto the branch model required solving genuinely hard problems around automated rebase, merge queue integration, and cross-fork security. The engineering work to do this correctly was substantial.

The less charitable answer is that GitHub spent the years from 2018 to 2022 primarily focused on GitHub Actions, Copilot, and enterprise features, and the core code review experience stagnated. Stacked PRs is the kind of feature that the GitHub team has known was wanted for years—the user requests are documented and numerous—but kept getting deprioritized in favor of features with broader revenue impact.

The acquisition by Microsoft in 2018 is relevant context here. Post-acquisition, GitHub’s product strategy became more explicitly enterprise-focused. Features that benefit large teams (Actions, Packages, Copilot, Advanced Security) took priority over features that benefit individual developers and small teams (better code review ergonomics). Stacked PRs primarily benefit individual developers and small teams, which may explain why it landed in 2026 rather than 2020.

What changed? The AI coding agent workflow. Once Copilot Workspace and similar systems started generating large batches of changes, the absence of native stacked PR support became a product gap that affected Copilot’s value proposition, not just an ergonomics complaint from a small subset of power users. That changed the prioritization calculus. The feature that was “nice to have” for human developers became “necessary infrastructure” for the AI-augmented development workflow that GitHub is betting its future on.

That reframing is the most important thing to understand about the timing of this release.

Was this analysis useful?
Michael Sun
Michael Sun

Solo founder and engineer writing opinionated, benchmark-driven analysis of AI, security, and developer tooling.

About ThesisBench →

Discussion

Leave a comment

Comments are moderated and appear after review. Be specific — vague praise and drive-by hot takes are equally likely to be skipped.

Related