Stacked Diffs: Keeping Phabricator Diffs Small

  1. Break up a large change into a series of individual commits
  2. Stack the commits on top of one another.
  3. Create Phabricator Diffs for each commit.

1: Create the First Commit

Time to make the first bit of our change. Starting on master, we’ll checkout a branch for the new feature, add a new class to our project, make our first commit, and sent it out for review:

2: Commits 2 Through N

We continue coding, making an additional logical change. For the sake of this example, let’s say the class uses functionality in the file we added in the first commit:

3: Address Feedback

Now let’s say a reviewer caught a mistake in your Part 1 diff and we need to go back and fix it.

4: Land the Diff

Alright, Part 1 has been approved and is ready to land:

5: Rinse and Repeat

If we’d had more than just two diffs in our stack we would just keep repeating the same processes in steps 3 and 4. Once all but the last diff in a stack has been landed, we can just run arc land my_feature to land the last commit.

Provisos, Pro-tips, and Parting Notes

  • You’ll see I always have to type arc diff HEAD^(I never use the standard arc diff ). Because of this, I’ve actually created a bash alias for doing my diffs so I never forget the HEAD^ part: alias ad="arc diff HEAD^"
  • I was pretty explicit and verbose with a lot of the commands above for the purposes of explaining exactly what was going on. As you get more comfortable with the work flow, I highly recommend setting up scripts and git aliases to help you do all of this. For example, since this work flow involves often doing an interactive rebase starting from master, I’ve aliased git rebase -i master to simply git rim.
  • If you’re using Harbormaster and Jenkins for CI, you’ll want to setup a staging area, other wise your stacked diffs will fail your integration tests (see appendix for how to do this).
  • If you’re ever unsure about what code is going to be sent up to Differential when you run arc diff HEAD^, just run arc diff HEAD^ -preview.
  • If you ever screw up a rebase, git reflog is your salvation.
  • Sometimes you’ll amend during a rebase and that will cause a conflict further up in the stack when you continue the rebase. When resolving these conflicts be sure to only use git rebase --continue. Don’t do an amend when resolving these conflicts. I’ve made that mistake before. It’s no fun.
  • When doing an interactive rebase, only edit one commit at a time. Doing more than one is an invitation for forget where you are in the stack and screw something up. I’ve made this mistake before. It’s no fun.
  • Always finish a rebase. If you walk away from your computer in the middle of a rebase, you may come back to it later, forget you’re in a rebase, and then try to change branches. This can seriously screw up what your repository looks like and confuse the hell out of you. I’ve made this mistake before. It’s no fun.

Special Note

I want to give a special thanks to all of the mentors at Facebook who taught me this workflow and to all the folks at Uber who have helped me refine it. Special thanks to Grayson Koonce for his massive help with editing this post.


Rebasing before landing

When landing an individual commit in your stack, there’s a chance there might be a conflict when landing. In order to avoid any conflict issues, we update master and rebase our branch to ensure a clean land.

Setting up a staging area

  1. find your repository in diffusion, e.g.
  2. click “edit repository”
  3. copy the “remote uri” value
  4. edit the “staging area”, and paste in the remote uri value
  5. save!



Software Engineer, Long Distance Runner, Diversity Advocate, YIMBY,

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Kurtis Nusbaum

Kurtis Nusbaum

Software Engineer, Long Distance Runner, Diversity Advocate, YIMBY,