3 min read
You just finished writing the new checkout flow for your shopping app, and now you need to add a promo codes feature. Promo codes are built on top of the checkout flow, but you realize you can’t build on top of the checkout flow because your first pull request hasn’t landed yet — it’s stuck in code review. In other words, you’re blocked.
What are you to do? You could:
- Work on something else: This isn’t awesome, you have the entire codebase for comments in your head right now, and moving to something else is just going to slow you down
- Bother your reviewer: Also not awesome, you’re just going to slow them down
- Fold it into the first PR: There’s nothing a developer likes to receive more than multi-thousand line code review
Or, you could stack.
What is stacking?
Stacking is the best kept secret of high-performing developers. The principle is simple: once you’ve finished writing a feature, you commit it to your feature branch, move it up the branch for review, and create a branch off of that feature branch.
Hold on, you’re saying — we always branch off of
main. Why would I branch off of a feature branch?
The answer is fairly straightforward. Branching off of a feature branch allows you pick up your work where you left off. No need to wait for that feature to land, just branch and go.
Over at Graphite, we recently wrote about how to build Wordle using stacking. Below is a PR building all of Wordle all at once: ‣
And here is a stack of eight that does the same thing:
- Pull Request #1: Use Create React App
- Pull Request #2: Add keyboard input
- Pull Request #3: Keep track of past guesses
- Pull Request #4: SCSS support
- Pull Request #5: Show which letters are correct
- Pull Request #6: Add a win condition and a reset button
- Pull Request #7: Add a real dictionary with words
- Pull Request #8: Deploy scripts
As a reviewer, which of those two was easier to read? Which one are you likely to review faster? Which one do you think will get merged first? Let us know what you think in the comments section.
How to incorporate stacking to a team environment
Now, I’m sure you’re asking, will this confuse my teammates?
Good question! And no, this will not confuse your teammates. GitHub thankfully has basic inbuilt support for stacks.
Let’s say you have a stack going:
main → checkout → promo_codes. To create that stack, you can create two pull requests on GitHub:
- One merging branch
- One merging branch
One branch merges into the branch below it in the stack, and as a result, GitHub will only show the diff between those two changes, allowing your reviewer to understand the stack in bite-sized pieces.
When you merge
main, you’ll automatically re-target the second pull request to now merge into
Two things we’ve seen others do to help their teammates understand their stack:
- Many people title their pull requests with the position in the stack, i.e., “[1/8] PR title”, “[2/8] Another PR title”)
- Some especially helpful teammates leave links to the rest of their stack in their descriptions to help reviewers navigate the stack as they’re reviewing it
If this last bit sounds like a burden, this is where automated tooling can help, which we’ll discuss in a separate section.
Why don’t more people use this?
While GitHub’s code review tooling has basic support for stacking, it still isn’t as easy out of the box as it is with Phabricator or Gerrit, where stacking is common. Most people don’t stack because the local tooling for it isn’t great — in GitHub, if you need to edit the pull request at the base of a stack, rebasing the upstack ones can be a lot of work.
Graphite was a tool purpose-built to bring this workflow to GitHub. It syncs your stacks, adds comments to GitHub to help orient your reviewers, and you can start using it today, even if your coworkers on GitHub aren’t ready to change their workflows.
How do I stack in an existing project?
The usual workflow has you fold your code into the first PR. With stacking, you can break up your changes into multiple PRs, which allows you to:
- Land each change separately
- Run CI against it
- Keep your reviewer’s workload light, leading to faster and more thorough reviews
Furthermore, you can get more and more granular about feature releases once you start breaking apart your changes. Our example checkout flow sounds like a complex feature — at the least, it could be split into multiple pull requests, one for the server changes and one for the client changes.
Regardless of what you use, if you want to be a faster developer, just start stacking.