Main Branch

Articles

Give each pull request in a stack one review decision

I tried GitHub's native stacked pull requests on a messy repo with 10 stale drafts and a broken test suite. Here's what stacks fix, what they cost, and how to decide when a change earns the extra branches.

Andrea Griffiths 6 min read 🌐 Read in Spanish 🌐 阅读中文版
Pull Requests Code Review GitHub Stacked PRs Developer Workflow
Listen to article

Leer en español → · 阅读中文版 →

Updated August 8, 2026 after a kind friend gave me feedback.

I wanted to try stacked pull requests somewhere messy enough to tell me whether they were useful.

The repo had 10 old draft PRs. Two were separate attempts at dark mode. Two overlapped on flight-delay emails. And npm test failed because a Playwright test lived inside the Jest test directory.

That was the development history in this repo. Work pauses. Context moves. You come back to a queue that needs a shape before it needs more code.

I closed the drafts without deleting their branches, then rebuilt one real fix as three pull requests: test runners first, locale behavior second, browser coverage and CI third.

  • Separate Jest and Playwright so CI can give us a useful signal.
  • Set the document language from the active locale.
  • Add browser coverage and run it in CI.

GitHub rendered the work as a 3/3 stack. Each layer ran CI and CodeQL. The useful result was a review order I could explain: fix the signal, change the behavior, prove the behavior.

The GitHub merge panel showing a 3/3 stacked pull request ready to land

Each layer gives a reviewer one question: test infrastructure, locale behavior, then browser CI. GitHub shows the three PRs as a 3/3 stack. The stack map made the dependency explicit instead of making reviewers infer it from branch names and commit history.

That experience changed how I think about the oversized PR.

The reviewer has too many jobs

A pull request can be correct, tested, and painful to review.

You start with one reasonable change. Then you need a schema update. Then shared types. Then an API endpoint. Then a UI component. Then tests. Then a refactor because the existing code makes the new behavior awkward.

A few days later, you have an 800-line PR with six kinds of work inside it.

The reviewer has to build the whole feature in their head before they can say anything useful. They need to understand the model, trace the backend behavior, inspect the UI, verify the tests, and decide whether the refactor belongs in the same change.

SmartBear’s code review guidance recommends reviewing 200-400 lines of code at a time. Beyond 400 lines, its guidance says defect detection drops.

The 400-line number isn’t as important, but when a reviewer must hold too many unrelated decisions at once, that is a challenge.

The branch gets older while that happens. Main keeps moving. Feedback arrives late, often in a pile. Then the author has to separate review changes from branch drift. Large pull requests create a review problem before they create a Git problem.

A stack earns its branches

A useful stack has a dependency order you can explain.

One large diff versus a three-layer stack, where each layer holds one review decision

One large diff asks a reviewer to make six decisions. A stack gives each layer one question.

The model gives the API something real to build on. The API gives the UI a contract. A reviewer can make one decision at a time and still see where the work is going.

A 600-line rename can still be one coherent pull request. A 120-line change across auth, persistence, and UI can hold three separate decisions. Line count helps you notice trouble. The decision tells you where to cut.

I use four questions before I create a stack:

  • Can the lower layer land safely on its own, or behind an appropriate flag?
  • Will feedback on the lower layer reshape the work above it?
  • Can a reviewer assess this layer without reconstructing the entire feature?
  • Does the branch order match the real implementation dependency?

If the answers are yes, the extra branches earn their keep.

Three layers was the right number for this change. If you land at four or five, look at the work again. Either it holds that many separate decisions, or the branching became the point.

Anything you change in the lowest layer cascades into rebase and conflict work in every branch above it, so a foundation that stalls in review holds the whole stack. Open the bottom layer first and early, before the work above it hardens.

Some work needs to stay together. If a reviewer needs the UI and API in the same diff to judge the behavior, keep them together. The goal is a useful review, not a tidy branch diagram.

Agents make oversized diffs faster

Coding agents make feature-sized diffs cheap. Your agent is fast. Your reviewer is a person with a coffee.

I’ve seen the 2,000-line agent pull request. It may contain good work. It also asks someone to trust a model, an API, a UI, test coverage, and a pile of generated glue all at once.

Give the agent a review shape before it starts. Ask it to identify the dependency order, build the foundation first, and keep each layer centered on one question a reviewer can answer.

That changes the output from one enormous branch into work the team can actually discuss.

What native stacks keep, and what they multiply

Dependent branches are old Git. The work around them has always been the painful part.

GitHub’s native stacks keep the policy connected to the whole chain. Each PR is evaluated against the stack’s final base, usually main, so required reviews, CODEOWNERS, and checks keep applying as the work moves upward.

Merge the highest PR to land the whole stack. If you merge only part of it, GitHub rebases the layers that remain.

Three layers meant three full CI runs. I hadn’t planned for that. Every PR is evaluated against the stack’s base, so checks multiply with stack size. On a demo repo that’s a rounding error. On a real repo with a slow suite, a five-layer stack can consume five times the CI minutes.

GitHub exposes github.event.pull_request.stack.position and .size in workflow expressions, so you can run the fast checks on every layer and reserve the full suite for the top PR or the lowest unmerged one. GitHub handles the stack wiring; the workflow choice is yours.

Start where the decisions split

Start with two layers. Pick a feature where the foundation and the behavior already feel like separate review conversations. Open the foundation early. Let feedback arrive before the work above it hardens.

The short workflow is:

gh extension install github/gh-stack
gh stack init
gh stack add <branch>
gh stack submit

The official GitHub walkthrough covers the commands and agent setup at gh.io/stacks. Read that when you’re ready to build.

On your next feature, find the first independently reviewable decision and open that PR early.

About the Author: Andrea Griffiths is a Senior Developer Advocate at GitHub, where she helps engineering teams adopt and scale developer technologies. She's passionate about making technical concepts accessible—to both humans and AI agents. Connect with her on LinkedIn, GitHub, or Twitter/X. · Read in Spanish · 阅读中文版