Atomic commits are a common practice among people who value a clean commit history in Git. But there doesn’t seem to be a consensus on what atomic really means.
Taking the term literally, one interpretation would be that you should create small commits. Or, in other words, commits with the smallest possible set of changes.
A more nuanced interpretation would be that you should create cohesive commits. That is, commits that are indivisible — their changes belong so strongly together that it would be unnatural to keep them apart.
A real-world example
Consider the following commit history (most recent commits first):
At first glance, there’s nothing wrong with these commits: they’re small and have clear commit messages. Some people like this style because it shows exactly what happened.
But why would having a chronological view of the changes be important? Ultimately, commits are consumed by humans to figure out what changes were made and why. So recording intermediate snapshots of your changes adds unnecessary noise.
From small to cohesive
If you were writing a book, you probably wouldn’t write all chapters and paragraphs in the order they appear in the final draft. This is because our brains work in a non-linear way when we’re producing content. On the other hand, we tend to consume content in a very linear way. For this reason, authors spend a lot of time going back and forth during the writing process, reviewing and editing, in order to provide a pleasant experience for readers.
Producing a branch in Git isn’t too different from writing a few paragraphs in a book — you might not get everything right on your first try. As such, you should allocate some time to clean up your commit history1.
Cleaning up the commit history implies rewriting it. In our earlier example, the four small commits could be squashed into a single cohesive commit:
The hidden benefits
Being diligent with rewriting history to produce cohesive commits has a surprising side-effect. The more you do it, the better you get at breaking down work into small iterations. Eventually, you'll be able to “see” the commits before you start crafting them. As a consequence, you won't have to rewrite history as much, and rewrites will be smaller and simpler2.
When you choose to clean up your commit history is up to you. Some people like to do it as they go, others prefer to do it at the end.
I find it fascinating how deliberate practice can make you so good at something, that you end up needing to do it less often.
It’s a really nice point of view to look at commits as a history you want to tell. I’m new in the development world and I confess I look to git more like a way to “don’t lose you work”, but you gave me a new perspective. Also I didn’t know about the possibility to rewrite commits, I’m going to take a look on that