Mastering Atomic Commits, The Secret to Efficient Git Workflows
Have you ever heard of atomic commits? Discover how using them can transform your coding practices, making your Git history cleaner, more comprehensible, and easier to manage.
Before we delve into the clear benefits of atomic commits, let's first understand what an atomic commit is. An atomic commit is the smallest code change that cannot be broken down any further. It encapsulates a set of changes that serve a single, discrete purpose and is (almost) independent of other commits. To better illustrate this, I will borrow the definition from a blog post that inspired me to start using atomic commits. In the world of physics, an atom is made up of protons, neutrons, and electrons. Each of these subatomic particles serves as the building blocks that form an atom. And for those who love nitpicking, yes, there are particles even smaller—just like my chances of winning a science quiz! 😄

Similarly, an atomic commit is made up of different parts that represent a meaningful change. In the front-end world, this might be a component that consists of CSS, HTML, and JavaScript changes. For the back-end, it could be a database migration script and a change to an entity model.

Should You Care?
There are multiple reasons why atomic commits are incredibly useful. I've personally come across their value when needing to revert a change quickly. Imagine you deploy something, and after a while, you find a bug in production. To resolve the issue, you might end up reverting a whole chunk of code changes, even those that could have stayed deployed. You have two options: either ditching the entire change or manually fixing specific lines of code. If you had atomic commits, you could easily cherry-pick your commit and just revert that part.
Another benefit is the ease of merging. You've likely found yourself in a situation where you had to deal with merge conflicts. When you break your changes into small, self-contained pieces of code, you decrease the likelihood of merge conflicts. Additionally, because the changes are small, it is only necessary to resolve small parts rather than a mixture of unrelated changes.
But those are only two examples. In the past year, I have changed the way I make commits due to the benefits these atomic changes provide. Let me share with you the advantages I see, in addition to the two I used in my concrete examples:
Easily Revert a Change
When changes are small, it is very easy to pick a certain commit and revert it using git revert a1b2c3d4e5f67890abcdef1234567890abcdef12
. This will take the Git commit a1b2c3d4e5f67890abcdef1234567890abcdef12
and revert it on top of the current codebase. As a consequence, all other changes are not affected, which is ideal for these situations. To give a bit more context, each commit consists of file changes that are being applied, and it will only revert these changes.
Simplify Merging
Since the changes are broken down into smaller chunks, resolving conflicts entails smaller and easier-to-manage conflicts—20 lines of code versus 3 to 5 lines of code that cause conflicts. I believe it is obvious which one is easier to resolve.
Enhanced Readability
Atomic commits, on their own, do not improve readability, but they go hand in hand with meaningful commit messages. More on this in my previous blog post. Since the code contains smaller chunks with meaningful messages, the history becomes more readable and easier to navigate. The same applies to pull requests, making them easier to review due to improved readability.
Facilitates Bisecting
A bug can easily creep into the application at a certain point, and you might not be aware of when it happened. The bug wasn't there a month ago, but you have made hundreds of commits since then. You need to find which specific commit introduced the bug. You can use the handy git bisect
command to single out the commit that introduced the issue. Since the commits are small and represent one single logical change, you will end up finding the issue sooner.
Promotes Modular Thinking
Encouraging the breakdown of code into smaller, logical units fosters a modular approach, improving the overall structure and maintainability. Of course, you need the mentioned meaningful messages alongside atomic commits.
How to Make Atomic Commits?
It is easy to fall into the trap of starting to code without a plan to resolve a problem. I have been there myself, and even now, I sometimes find myself trying to do too much at once. Using atomic commits requires discipline and planning. I have come up with a checklist that helps me incorporate atomic commits into my daily work. Here is what you need to do:
Divide the problem into smaller tasks: This helps you focus on one thing at a time and limits the scope of your code changes.
Commit early and often: Once you reach a meaningful point in your code, make a commit. You can always squash commits if needed.
Review your commits before pushing changes to the remote repository: Use
git status
,git diff
, andgit log
to inspect the code changes before committing and pushing. Another way is to usegit add -p
when you have a lot of changes. These changes can be grouped into multiple commits in an interactive mode. With that, you can split chunks and move logical changes into commits.Enforce meaningful messages: Ensure that your commit messages are clear and concise, summarizing the single change the commit makes. This helps to avoid commits that include multiple unrelated changes.
Practical Examples of Atomic Commits
I will present three scenarios that illustrate what an atomic commit should look like. This should help you understand how to incorporate atomic commits into your workflow.
Scenario 1: Feature Implementation
Imagine you are working on a web calculator that supports several operators like addition, subtraction, division, and multiplication. Let's look at how an atomic commit should and should not look.
Atomic Commit Example:
git add src/utils.js
git commit -m "Add addition function to utility module"
Explanation: This commit is atomic because it focuses on a single, specific change — adding the addition
function to the utils.js
file.
Non-Atomic Commit Example:
git add src/utils.js
git add src/components/button.html
git add src/components/button.scss
git commit -m "Add utility functions and update button component"
Explanation: This commit is non-atomic because it combines two unrelated changes — adding utility functions and updating a UI component.
Scenario 2: Bug Fix
Atomic Commit Example:
git add tests/mathUtils.test.js
git add src/mathUtils.js
git commit -m "Fix divide by zero error in 'divide' function"
Explanation: This commit is atomic because it addresses a single bug — the divide by zero error in the divide
function, and includes the test case to validate the fix.
Non-Atomic Commit Example:
git add tests/mathUtils.test.js
git add src/mathUtils.js
git add docs/changelog.md
git commit -m "Fix divide by zero error and update changelog"
Explanation: This commit is non-atomic because it mixes a bug fix with an unrelated change — updating the changelog.
Scenario 3: Refactoring
Atomic Commit Example:
git add src/services/apiService.js
git commit -m "Refactor API service to use async/await"
Explanation: This commit is atomic because it focuses on a single refactoring task — converting the apiService
to use async/await
.
Non-Atomic Commit Example:
git add src/services/apiService.js
git add src/components/Login.js
git commit -m "Refactor API service and update login component styling"
Explanation: This commit is non-atomic because it combines a refactoring task with an unrelated change — updating the styling of the Login
component.
Start Now
In the realm of version control, embracing atomic commits is vital for maintaining a clean, comprehensible, and efficient Git history. Atomic commits ensure that each change is isolated, well-documented, and manageable. This approach streamlines development, enhances collaboration, simplifies code reviews, and eases debugging.
Incorporating atomic commits into your workflow may take practice, but it becomes easier over time. Don't wait to adopt this best practice—start using atomic commits today, and watch your skills improve.
Published by...