Thine Holy Four Commit Properties

An even more deliberate git.

Izaak Schroeder
Bootstart
Published in
4 min readApr 5, 2019

--

You may have encountered Stephan Ball’s seminal “Deliberate Git”; if you haven’t then you should stop reading this and go through that first. Once you have, you’ll realize what a commit should represent, (a story), which helps significantly with structuring the content of your commit messages and helps prevent the repository from descending into a commit clown fiesta.

However, this does not necessarily elucidate what a commit should be and it misses out on some things that make working with commits easier. Ergo, this is a guide to helping you fine-tune how to partition your code, such that the commits not only tell a story, but also work well with the existing tooling in your development ecosystem.

The Holy Four are four properties that a given git commit sha1 should be:

  1. Pickable: Does git cherry-pick sha1 make sense?
  2. Revertible: Does git revert sha1 make sense?
  3. Testable: Does CI pass for the given sha1?
  4. Tractable: Does sha1 represent a single, logical, cohesive change?

Each of these properties helps to ensure that working with an individual commit does not become a source of enormous pain and developer mud flinging.

Pickability

Can I cherry pick the commit(s) without creating merge conflicts?

Being able to cherry pick usually means whatever you’ve done will stand on its own. If the primary feature gets rejected or you need to hotfix a production branch with bits of code from your feature branch, well designed commits can often make moving chunks of code around easy. If your decide your functionality belongs in a separate PR you can also easily create a new branch and cherry pick onto that branch.

Bad:

Good:

Commit [2] can be cherry picked into a different branch or different version, outside of the other work that’s being done on the refactor.

Revertibility

Does reverting the commit make sense? Is it possible without breaking code?

There is often a tug between the natural interdependencies in the code itself and the desire to split the commits into one chunk per piece of functionality (physical cohesiveness vs. logical cohesiveness). If you have three commits and reverting the last two results in dead code or broken code in the first commit, then odds are they should be a single commit instead of three. Physical cohesiveness wins over logical cohesiveness in commits.

Bad:

Good:

Commit [1] is dead code if [2] gets reverted or changed. There is no point in having [1] without [2] so they should not be separate commits. Even worse, if critical changes happened in [2] means reverting [2] wouldn’t make sense; having[1] on its own would simply result in errors.

Testability

Does every commit pass the test suite?

If some subset of your commits were to suddenly disappear (or reappear on top of another branch) well designed commits give a high probability everything will still hold together. It’s typically also a reasonable indication that the functionality of the commit is actually tested in the commit itself, and not two commits down the line; this saves you from entering a nightmarish git revert scenario.

Bad:

Good:

Tractability

Does every commit represent a single, logical, cohesive change?

No one has the time or cognitive capacity to review 1,000+ line diffs all the time and ensuring your changes are small and specific can mean more effective feedback. Big changes often get a “LGTM” stamp in lieu of proper review because no one wants to be seen as the complainer saying you wrote too much code. This also helps later when someone wants to understand why something happened; git blame becomes more useful when the result talks about the code and doesn’t include 10 other barely related changes.

Bad:

Good:

Having so much content in [1] makes it unwieldy to manage and any discussion happening would be about a lot of things at once. Having focused commits means they can be worked on iteratively and as independently as the code allows for.

To Wit

Good commits develop slowly, bad commits have wings. Take some time to ask questions about your commits before enshrining them into your codebase forever and future wayward souls that have to work in the same repository will be happier and more effective contributors.

Use the Holy Four commit properties on your next project. 🙏

--

--