The stacking workflow

Stacked PRs. Stacked diffs. Stacked changes.

A better workflow to manage pull requests.

Code review takes a long time

Code review can take a long time, for both the pull request author and reviewers.

As the author, you can be stuck waiting for hours, days or even years before you can merge. This is especially challenging on distributed teams across different timezones. You're trying to ship a feature, but you're stuck waiting on review from someone who's fast asleep on the other side of the world.

Finally your teammate wakes up, leaves a few comments, requests changes, and now you have to iterate, starting the whole cycle again.

Code review is also time-consuming for the reviewers. Leaving a meaningful review can take a considerable amount of time, particularly if the pull request is large. A thorough code review involves sifting through the code changes, building context, leaving comments and suggestions, and then waiting on the author to respond.

Code review slows you down

Waiting for your teammates to review your pull requests slows you down and blocks you from shipping anything that depends on the code you're waiting on a review for.

Things you could be doing with your time instead of waiting on code review:

  • Shipping impactful new features
  • Tackling that tech debt chore you've been putting off
  • Going to the beach

Stacking allows you to skip the wait

Stacking parallelizes your development and code review workstreams, so you don't need to wait for your previous changes to be merged before building on top of them.

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. In a traditional workflow, next you'd have to get that PR reviewed, merge it into main, and once that's done, branch off of main again, before finally you can start work on 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.

Stacking manually is hard

Because stacked pull requests are dependent on each other, anytime there's an upstream change, every PR in the rest of the stack needs to be recursively rebased on top of one another to stay in sync.

It's possible to do this manually, but the Git CLI wasn't designed for this workflow. You have to rebase each branch individually, which is incredibly time consuming. Plus then you have to deal with cascading merge conflicts, and the whole thing gets even messier.

Tools for stacking

Luckily however, there are tools that automate a lot of this complexity and streamline the process:.

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.
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.
A new source control system from Meta. Has built-in support for stacking.
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.