The stacking workflow

Stacked PRs. Stacked diffs. Stacked changes.

A better workflow to manage pull requests.

Small PRs are better

According to Google engineering, small PRs are:

  • More correct: the smaller the PR, the easier it is to design, and the less likely the author is to introduce bugs.
  • Easier to review: not only are small PRs reviewed more quickly, but they're also reviewed more thoroughly.
  • Faster to merge: small PRs are less likely to have rebase conflicts, spend less time sitting in the review process, and are merged faster than larger PRs.
  • Better if things go wrong: in the unfortunate event that a PR is rejected, there is less wasted work; if the PR ends up being reverted it's a much simpler process with less cascading side-effects.

Small PRs are hard

Despite all of the above benefits, right now you probably still have some PRs that are more than 200 lines.

And that's completely understandable.

Let's say you're working on a feature that involves front-end and server changes, small refactoring, and an update to CI. Your first instinct is probably going to be to combine all of those changes into a single PR, because managing dozens of small PRs manually is a mess, and waiting for review on each of them would slow you down.

So instead, you do the slightly worse thing: you fold all those related changes into one PR and convince yourself that it's really one change... even though you know there are parts you could pull out and land separately if you really had to.

Note: On the off chance all your PRs are all under 200 lines, that's great! Stacking has nothing to offer you; please feel free to close this webpage.

Stacking makes small PRs easy

Stacking lets you make many small PRs (1) easily and (2) without having to wait for review.

Imagine you're creating a feature that requires both a new server endpoint, and front-end changes. You've just written the PR that creates the endpoint on a new feature branch, because on GitHub every PR must be its own Git branch. In a traditional workflow, next you'd have to get that PR reviewed, then merge it into main, and once that's done, branch off of main again, before finally you can begin authoring the front-end change that relies on the server code you just wrote. It's a hassle.

A diagram showing a branching model without stacking.

With stacking, you don't have to do that. Instead, you put your server changes up for review, create a new dependent branch, and continue working.

A diagram showing a branching model with stacking.

Once both PRs are approved, you can either land them together or separately. The stack is structured in such a way, that one change can land ahead of the other change; for example, in this case, the new server endpoint is safe to land ahead of any PRs that introduce code invoking it.

This separation of concerns isn't done automagically by stacking, but is instead a side effect of forcing developers to break up their large change into a sequence of smaller, dependent changes.

Note: Many developers find a lot of the same benefits by breaking their change into a sequence of commits (instead of pull requests). By making the unit of change a pull request, however, your change can be tested, reviewed, landed, and reverted more easily. If you're more used to commits, many developers start stacking by limiting themselves to one-commit-per-pr (or having a tool automatically create a pull request per commit).

Tools for stacking

Manually stacking in Git can be tedious, and that's why many developers don't do it; however, there are plenty of tools that can streamline the process.

Graphite
An out-of-the-box solution for stacking on GitHub: includes a CLI, VS Code extension, and web UI for managing stacks. It fully syncs with GitHub, so it works even if you're the first person on your team to try stacking.
ghstack
An open-source CLI for stacking on GitHub. Simplifies the process of creating, updating, and pushing stacked commits to GitHub (abstracting away branches).
git town
A high-level CLI for git. Includes support for opening and syncing branches to GitHub.
Sapling
A new source control system from Meta. Has built-in support for stacking.
spr
Another open-source CLI for stacking on GitHub. Fundamentally very similar to ghstack. A no-frills way to create and update PRs on GitHub. (Requires single commit per PR.)
If using a tool doesn't speak to you, git is adding more support for stacking every day. The new --update-refs option lets you update a stack with fewer rebases; however, parts of the stacking process are still tedious (i.e. opening PRs on GitHub or any other provider).

Once you stack, you'll never go back

Tools aside, you should stack more.

Beyond a change in branch structure, stacking forces you to structure your thinking and makes your changes easier to understand for you, your reviewers, and any developers down the line (whether they're looking to learn, understand, or revert). Stacking results in demonstrably better code, and makes everyone's life easier.

You can start stacking today in pretty much any repository. Stacking is independent of: language, whether you're backend or frontend, whether you rebase or merge, whether you commit or amend, and whether you use a polyrepo or a monorepo.

People that start stacking find themselves regularly creating stacks of 5-10 PRs, because almost every large change can be better structured as a sequence of small changes. If you find that number daunting, tooling can make it more approachable; however, whether you use a tool or not, the most important thing is to start stacking.