Engineering Culture: Keeping a Clean Commit History

Have you ever come across or been the perpetrator of a PR with a commit history that looks like this?

This was commonly how I addressed fixes for my PRs years before working at Distru. I thought this might have been my own naivete, but to my surprise, many engineers far more capable than myself have joined Distru since then, and they too addressed review comments in such a manner.

Over time we’ve come to avoid these types of “fix-up” commits at Distru for a couple of reasons:

  • To keep a clean commit history of your code. Code is communication for both other engineers and your future self. The cleaner it is, the more sane the readers will be.

At Distru, whenever we address an issue in a PR, we resolve them in the original commit that introduced the change, to begin with. We accomplish this by using interactive rebasing.

Interactive Rebasing to Edit Commits

Interactive rebasing is a powerful tool in git that allows you to locally traverse back in history to previous commits, make changes, and essentially rewrite history.

A word of warning: Your main git branch should act as a historical ledger (and thus not change) once work has been merged in. Interactive rebasing should only be done on open WIP branches that have yet to be merged into the main branch.

Let’s take an example. We have an open PR consisting of the following commits:

  • Commit A

Creative naming right? Now let’s assume that we’ve received commentary on Commit B that something needs to be changed. Let’s use interactive rebasing to make this change without additional “fix-up” commits.

Find the hash of the commit you’d like to change by running git log:

Then you’ll want to make sure that all current changes (if any) are stashed via git stash before then trying to rebase back to this commit.

To make changes to Commit B, we’ll need to issue the following command:

git rebase -i 400d63a771fc0eefd7409da4bfa6a1f37bfff17b^

You’ll need to add a ^ at the end of the commit hash to include that particular commit as a part of your interactive rebase.

After you run this command, you should be at the interactive rebase screen, here you can change pick to edit for Commit B”:

Now you should be able to save the interactive rebase file ( :wq on vim), and git will rewind you back in history to being in the midst of Commit B:

Save & quit this file (:wq on vim), and the changes you made will now be included as a part of Commit B.

When you’re done with all the changes you’d like to amend, run git rebase --- continue, and it’ll fast-forward you to the latest branch head.

Now, if you run git log, you can see that your commit history is still as clean as ever while having made amendments to previous commits!

Did you notice how the commit hash for Commit B and any children (in this case, Commit C) change? It changed because you’ve overwritten those commits by altering history. So to push this up to remote origin, you’ll need to do a force push via git push -f.

That’s it! You’ve just fixed up a previous commit without having to compromise the integrity of your commit history.

Exploring Other Options

Interactive rebasing is a powerful tool. Editing old commits in place is just one of the many things you can do with it; you can also:

All in all, interactive rebasing is a must-have tool to keep your commit history clean; your teammates and your future self will thank you for producing such easily traversable work!

I hope this looks into how we keep our commit history clean at Distru has been helpful enough for you to start practicing on your own! If you have more to add to this topic, please reach out to me via johnny@distru.com. We’re always trying to learn and improve as a company, and any thought exchange in that effort is greatly appreciated!

Lastly, Distru is currently hiring product-minded engineers, product designers, product managers, and engineering managers that want to build software powering the future of the Cannabis supply chain. If you’re interested in learning more, please check out our Glassdoor and reach out via our careers page and I’d be happy to jump on a call with you!

The Distru Team (May 2021)

Building the future Cannabis supply chain software! We’re a technical team looking for product-driven engineers. Our stack is React, TS, GraphQL, & Elixir :D