DEV Community

Cover image for How atomic Git commits dramatically increased my productivity - and will increase yours too
Samuel-Zacharie FAURE
Samuel-Zacharie FAURE

Posted on • Updated on

How atomic Git commits dramatically increased my productivity - and will increase yours too

Atomic: of or forming a single irreducible unit or component in a larger system.

Also available on my blog.

Knowing VS Actually Knowing

I remember when my first mentor told me about Test-Driven Development. A great methodological approach to software engineering. It took me just a few minutes to understand what it was and how it worked.

Then I spent the next six months actively not practicing it. TDD is hard when you start, so you just... don't.

Half a year later, I was hitting my head against a wall trying to build a new feature. I forced myself for the first time to actually do TDD by the book. The wall that was blocking my progress disappeared instantly.

In a previous article, I explained how many managers and tech leads often know exactly how to make our industry better... yet don't. There is always a good reason to not do things right. And somehow we still end up surprised when we're doing things wrong.

This long introduction is here to illustrate a point: you can know what you should do, but you might not know how important it is to actually do it. So many people out there, just like I did before, know how TDD is great... yet still don't use it.

The simplest concepts can often completely change the way you work... if you would only apply them. Introducing: the atomic git commits.

What's an atomic git commit?

Working with atomic git commits means your commits are of the smallest possible size. Each commit does one, and only one simple thing, that can be summed up in a simple sentence.

The amount of code change doesn't matter. It can be a letter or it can be a hundred thousand lines, but you should be able to describe the change with one simple short sentence.

Ideally, you also want your test suite to be in the green when you commit. Your changes might be "atomic", i.e the smallest possible, but they should also be "complete", which means your test suite always follow through.

As small as possible, but complete: this is an atomic git commit.

Why should you write atomic git commits?

There are a few great advantages to practicing atomic git commits, and we'll briefly detail them. But the last one really is the most important. It might completely change the way you approach your work, increase your productivity by an order of magnitude, and make your job much more enjoyable.

Reason number 1: An atomic change is a reversible change

We all know this simple truth about software: the requirements are always changing. By writing atomic git commits, we allow ourselves to revert any changes by a simple commit revert. This already increases your productivity tremendously.

Reason number 2: A clean git history

When shit hit the fan, a clean git history means the difference between pain and salvation. It's like insuring your house: seems useless, until there's a fire.

Reason number 3: Pull requests are much easier to review

Your team will absolutely love you for this.

Reason number 4: A much, much better workflow

This is by far the most important reason to practice atomic git commits: it completely alters the way you approach problem-solving.

If you're like me, you might have a tendency while developing a feature, to just... do it. Entirely.

Then you realize how you did not think everything through.

You need to change more that you expected. Some edge cases aren't taken into account. You broke some unrelated tests, they need fixing. Soon, you end up in a maze of your own making. You're lost. Your head hurts. You can't make any progress without being entirely focused.

Now, this is the wrong way to do things. And worse, you already know the right way, because it's so obvious.

The well-known method to complete a big, complex task: cut it down into smaller, manageable, tiny steps. Each step -its own simple problem to solve. This is obvious advice that you probably already heard many times... But are you actually practicing it in your daily job?

Well, here's a great way to actually practice it: write atomic git commits.

By forcefully working in atomic commits, you're approaching the work the right way, by simplifying it into smaller steps. After all, simplifying complexity is the very core of our job. So why aren't we always consciously doing it?

Of course this advice might sound obvious. But if my past experience proves anything, it's that the obvious really bears repeating, and even more importantly, it bears practicing.

Make your work simpler, better, more manageable, and most importantly: make it easier. Take small steps. Write small commits. Atomic commits. You will love them.

Latest comments (65)

Collapse
 
tinaheiligers profile image
Christiane (Tina) Heiligers

I find that a combo of committing often with descriptive commit messages really helps during WIP.
Before submitting the work though, I do a clean-up and rebase to give reviewers an easier time.

Collapse
 
samuelfaure profile image
Samuel-Zacharie FAURE

This is the way

Collapse
 
tythos profile image
Brian Kirkpatrick

Benefits for PR/MR reviews alone is worth it.

Collapse
 
jeje profile image
Jérôme Reybert

Excellent article, it highlights with simple words something difficult to share with colleagues.

I tend to stick to this motto since years, with more or less success. I can see two things that helped me recently.

First one is, finding a way to stay focus on what is the primary goal of the task. For development tasks such as adding a new feature, or worse, refactoring, you may go through a lot of code, spotting a lot potential fix/enhancement. It is really hard to not fix them at the moment, usually because you fear to forget it instanly you'll jump to the next function. But what seems easy and contained in a single function at the moment may end with patches all around the project. And you end with two different feature in your stage area, maybe hard to split.

The answer for that is: add an issue, with minimum context to work on it later (you, or another developper). Then, the issue will be addressed in a clean codebase, at the right moment, which is a good start for a new atomic commit.

The second tip is to put less pressure on the atomic commit. If you use merge requests, on your project, setup merge request to use semi linear history (for example in gitlab). Even if each individual commit is not strictly atomic, your git log will naturally be cut into merge requests atomic sections.

Collapse
 
macdanson profile image
Nahabwe Danson

I think I should actively start this approach. I have heard of it over and over but hestant to start

Collapse
 
bretbernhoft profile image
Bret Bernhoft

This is great. I will reconsider my Push frequency, based on the suggestions in this article. Have you run into any resistance with this style of workflow?

Collapse
 
allbertuu profile image
Alberto Albuquerque

Nice post! It would be nicer if you've brought examples to how write these commits. But after all, you made it!

Collapse
 
jatin510 profile image
Jagdish Parihar

hey !!
Can you please show some example as well.
A sample open source project, will be a huge help to understand the concept.
Thanks !!

Collapse
 
samuelfaure profile image
Samuel-Zacharie FAURE

Stay tuned for part 2 :)

Collapse
 
syedashrafulla profile image
Syed Ashrafulla

The harder and, at least for internal repositories, behavior that I push for is atomic small pull requests. I don't know why, but Git users seem to love pull requests with double digit commits rather than using git commit --amend. I'm less interested in the requestor's thought process than I am in a clean linear commit history.

Collapse
 
nabbe profile image
Nick Abbene

Also understated is how easier it is to change the order of things if needed (breaking up a big MR, or reordering stacked MRs)

Collapse
 
janarth10 profile image
janarth10

After all, simplifying complexity is the very core of our job

This line really resonates. I recently read the chapter on Information Hiding in John Ousterhout's "A Philosophy of Software Design" and in a nutshell its all about simplifying complexity by hiding information in "deep" modules.

Collapse
 
ryancurrah profile image
Ryan Currah • Edited

Squashing commits on merge could accomplish this.

Collapse
 
samuelfaure profile image
Samuel-Zacharie FAURE

Squashing commits on merge is the devil, rebasing without any squash on merge is the way to go

Collapse
 
szikra profile image
szikra

I would suggest that "cutting complex tasks down into smaller, manageable, tiny steps" could also be a commit.

Write a TODO comment block (where you detail the steps needed to complete the task). You can (even days or weeks later) go back and check what steps are done or to see if you forgot anything.

(You can use a separate [issue tracker] system to do this, which might be necessary if changes are needed outside of the code. It depends on a lot of things where it should be done, but it should be done somewhere. Doing it in code has the least overhead, the least excuses not to do it, and it is tightly coupled with the code so it is easy to check what was the plan/motivation behind a string of changes... even years later when the issue tracker might have been replaced.)

Collapse
 
samuelfaure profile image
Samuel-Zacharie FAURE

Very interesting take

Collapse
 
jake0011 profile image
JAKE

thanks Sam, this is a very informative piece.

Collapse
 
mfurmaniuk profile image
Michael

Agree with this and how I have always worked with my branches, it provides me a better record of all the changes (in case I go off on a tangent) so there is a comprehensive commit of everything done. Also like the quick revert if you go too far down a path of destruction.

Collapse
 
schultyy profile image
Jan Schulte

Small commits really started to pay off once I had to git bisect to debug some strange behavior.

The main concern against atomic commits I heard often was: "But then you have so many commits in the history".
Honestly, I don't mind it. I'd rather have more commits than a hard to debug git history.