dev-resources.site
for different kinds of informations.
Atomic commits will help you git legit.
Iâve given a talk (Git Legit) a few times that basically makes a case for atomic commits. Iâve created a cheatsheet to go with it, but then I realized thereâs no point to the cheatsheet if you donât use atomic commits. Then I realized you wonât start using atomic commits until you know the benefits. So, hereâs basically a short recap of my talk if you havenât seen it.
When I started using Git, I used it as a save point. Similarly to when youâre playing a video game, made a bunch of progress, and think âI should probably find a save point or Iâll lose all my progressâ. This makes a lot of sense; weâre used to this linear, âcheckpointâ mindset. But I shifted from the âcheckpoint commitâ mindset to atomic commits and havenât looked back once.
Firstly, what are atomic commits?
Atomic commits, in short, are what they sound like: atomic. So small that they can't be broken up any further. I feel like thereâs basically three features a commit needs to have to be atomic:
In short, all your tests need to be green on every commit and your application shouldnât break. Every commit has a clear commit message and a description detailing what the purpose of these changes was. Lastly, the commit should only have changes pertaining to one fix or feature (or whatever you were working on). Donât have commits where you âfixed that bug and also implemented the feature and then also refactored some classâ.
Why, you ask? Well,
Atomic commits have big benefits
For me, one of the biggest advantages of atomic commits is spending a LOT less time solving merge conflicts. Because all your commits are concentrated to a certain part of the code, merging and rebasing become so, so much less painful. Youâll have a lot more context to the conflict and your conflicts will become smaller and much more rare. Any time you need to rebase your branch will go much more smoothly. Also, dropping and cherry-picking commits become very handy options.
Atomic commits also make code review much more pleasant. Youâll be able to review commit by commit, which will give your brain less information overload and offer a clear context of what youâre reviewing. After all, the commit is about one fix or feature only, and the message and description are clear and concise. Having this context and diminished confusion will not only make reviewing more pleasant; it will make you better at reviewing. This commit by commit review isnât possible if youâre using git like a save point, creating checkpoint commits. Thatâs because theyâre based on time, not on a portion of the code. Consequently, you might request changes or comment on one commit, when that particular change was already undone in a next commit. You just hadnât gotten to that commit yet. Very inconvenient.
Lastly, your history becomes much more relevant. Without atomic commits, it becomes difficult to be descriptive in your commit messages, since youâre touching different areas of the code and not focusing on one central theme per commit. So, at a glance, people wonât be able to tell what happened in your history. Take this scenario:
You fix a bug. Commit. You realize you broke something else in the process. Another commit. You address comments on your PR. Commit. And so on, and so on. You end up with this:
Anyone looking through your history wonât know what commit actually fixed the bug. Without the context of your PR, the upper commit messages have no meaning. Every commit captures your application in a broken state, so you canât revert comfortably. All you really wanted was to fix the bug. So amend your initial commit until youâve actually fixed the bug.
How, you ask? Well, hereâs
How to keep your commits atomic
While on your task/feature/whatever branch, group all the changes to their relevant commits. This means youâll need to change your commits if you make any changes to them afterwards. This is possible through interactive rebase and amending.
Please note: any time you change a commit, it changes the commit hash. This means that if you try to push it to your origin, it will be rejected (your origin thinks the commit doesnât belong there), unless you
git push -f
. You should probably protect master and any other important branches.
My cheatsheet lays out some handy commands Git offers to help you keep your commits atomic. It takes some learning and getting used to, but youâll breathe a lot easier once you do.
Featured ones: