Back to blog
Development

GitHub Stacked PRs: Split a Giant PR Without Chaos

GitHub Stacked PRs: split a giant PR into a reviewable chain, avoid the squash merge that breaks it, and know when it's not worth it.

Blurtek
7 min read969 palabras

A stacked PR splits one large change into several small pull requests that depend on each other: PR 2 branches off PR 1, PR 3 branches off PR 2, and so on. GitHub has no native 'stack' concept — you simulate it by pointing each PR at the right base branch and keeping the branches synced through chained rebases, something Git 2.38 lets you automate with a single command.

01

What a stacked PR is (and isn't in GitHub)

A stacked PR isn't a GitHub feature: it's a workflow pattern built on branches and git rebase. Instead of opening one feature/checkout-v2 branch with 40 changed files and waiting for someone to find a free afternoon to review it whole, you split it into logical pieces — 'data model', 'API endpoint', 'frontend logic', 'e2e tests' — each in its own branch and its own PR. Every PR points, as its base, to the previous PR's branch, not to main. A reviewer can approve and merge piece 1 while piece 4 is still being written, and each PR reads in minutes instead of hours. GitHub renders this correctly in the diff view once you set the base branch properly, but it offers no aggregated 'stack' view and won't reorder anything for you — that's on you, by hand or with an external tool.

The failure nobody explains: squash merge breaks the stack

Here's the failure almost no tutorial mentions, and it explains why most teams that try stacked PRs abandon them after one attempt. If your repository defaults to 'Squash and merge' — the most common option because it keeps main's history clean — merging PR 1 rewrites all its commits into one with a new hash. PR 2's branch, still pointing at PR 1's original commits, now has a history that diverges from main: the 'already merged' changes reappear as pending in the diff. The visual result is alarming — a 3-file PR that suddenly shows 40 changed files — and it's the number one reason a team's stack 'explodes' and they swear off the pattern. The fix isn't avoiding stacked PRs: it's not using squash merge on branches with pending children, or rebasing the child branch onto main right after each merge, before anyone touches anything else.

02

The mechanism that makes this viable without paying for a tool

The reason stacked PRs used to be a nightmare and are now manageable has a name: git rebase --update-refs, added in Git 2.38 (September 2022). Before that, rebasing the stack's base branch — say, after addressing review feedback on PR 1 — meant manually rebasing each child branch one by one, resolving the same conflicts repeatedly when they touched shared files. With --update-refs, Git detects which other local branches point at commits within the range being rebased and moves their refs along with yours in the same operation. It's exactly the mechanism paid tools like Graphite or extensions like git-spice run under the hood: no new magic, just this same command wrapped in a friendlier interface. In practice the pattern boils down to three commands: git checkout -b feature/step-2 feature/step-1 to branch each child off the previous one (never off main), gh pr create --base feature/step-1 to set the correct link when opening the PR, and git rebase main --update-refs followed by git push --force-with-lease on every affected branch when the base moves.

03

A practical step-by-step guide with the gh CLI

Setting up and opening the stack

  • Split the change into pieces that can be reviewed and merged independently (ideally each builds and passes tests on its own)
  • Create the first branch off main and open PR 1 normally with gh pr create
  • Create the second branch off the first one (not off main) and open it with gh pr create --base <branch-1>
  • Repeat the pattern for each following piece, always pointing at the immediately preceding branch
  • Label each PR title with its position ('1/4', '2/4'...) so reviewers understand the order without a tool
  • Turn off 'Squash and merge' as the only option, or agree with the team to use 'Rebase and merge' for intermediate branches

When the base changes: the moment most teams give up

The real friction isn't creating the stack, it's keeping it alive as review feedback comes in. If a reviewer requests a change on PR 1 while PR 2 and PR 3 already exist on top of it, that change has to propagate downward before anyone reviews anything else, or PR 3 and 4 will be reviewing code that no longer exists. The correct flow is: apply the change on PR 1's branch, commit it, and run git rebase feature/step-1 --update-refs from any branch in the stack so Git reorders the whole chain in one pass. Then push --force-with-lease on every branch that moved — GitHub updates the affected PRs automatically since it follows the branch pointer, not a fixed PR. This only works if the team has the discipline to rebase the stack the same day feedback arrives: letting a 4-PR stack sit for a week is the fastest way to resolve the same conflict three times.

200-400 lines/hour

review pace with peak defect-detection effectiveness, per Cisco's code review study (Cohen, 'Best Kept Secrets of Peer Code Review', SmartBear, 2006) — beyond that volume, defect-finding effectiveness drops sharply

Antes
  • One 1,200-line, 35-file PR: review postponed for days, superficial comments, a single reviewer willing to 'swallow it whole'
Después
  • 4 stacked PRs of 150-300 lines each: reviewed same-day, comments specific to each piece, already-approved pieces can merge without waiting on the rest
04

Do you need Graphite, git-spice, or plain git will do?

Let's be honest here: for a 2-4 developer team that opens stacked PRs occasionally, paying for Graphite or another dedicated tool usually means spending money to solve a problem that git rebase --update-refs and a few shell aliases already solve for free. These tools deliver real value in stack visualization, one-command reordering, and automatic syncing after each merge — something that matters when an organization has dozens of developers opening stacks in parallel every day — but for the workload of a Spanish tech SME, that operational cost and the extra CLI's learning curve rarely pay off. At Blurtek we've more than once chosen plain git plus a clear branch-naming convention over adding another dependency to a small team's workflow; the external tool starts to earn its keep once the team grows or stacked PRs go from occasional to the default pattern every sprint.

05

When a PR stack isn't worth building

Stacked PRs aren't the answer to everything, and recommending them unconditionally would mean selling you a solution you don't need. If your team is one or two people, if the change is genuinely small and can't be split into pieces that stand on their own, or if you're in a prototype phase where the code will change radically within days, the cost of keeping chained branches in sync far outweighs the benefit of incremental review. The real signal it's worth it is different: when a PR sits unreviewed for more than two days because 'it's too big to look at right now,' or when the same config file gets touched by three competing features on the same base branch. Outside those cases, a normal PR and a quick review are cheaper than learning to manage a stack.

Is your team dragging days-old unreviewed PRs, or branch stacks that break on every rebase? At Blurtek we help small development teams define a Git and code-review workflow that fits their actual size, without forcing tools you won't get your money's worth from.

Solicitar diagnóstico