In all my years of web development and using a fully functional version control system (i.e., Git—I don’t count either SVN or Mercurial as functional), I’ve preached to the choir that commits must be atomic. But what exactly does that mean?
Fagner Brack has the best definition:
An atomic commit should be able to be reverted or applied without side effects.
This is somewhat surprising, because almost everyone I’ve asked thought that atomic referred to the size of the commit—i.e., that it simply meant a small commit.
But what does no side effects actually mean in practice? We discussed this recently in a pull request. For instance, if you want to change a dependency, a commit that adds the new dependency (e.g., in package.json) and removes the old one is not a good commit. Yes, it may be small, but it introduces a lot of side effects. If you check out just that one commit, you likely won’t be able to build the project, because the code doesn’t reflect the new dependency. The old one is still imported everywhere but no longer usable.
This is often overlooked, because almost nobody builds the project at that particular commit. Until, that is, you’re chasing down a bug using git bisect to identify good and bad commits—only to find that you have to manually edit the code just to make it run.
On the other hand, including all code changes needed to implement the new dependency in a single commit can result in a commit that’s too large—making it harder to review and debug later.
In such a case, I’d prefer the following approach:
-
A first commit that introduces the new dependency.
-
A series of commits that incrementally switch the code (and, certainly, tests) to use the new library.
-
A final commit that removes the now-superfluous old dependency.
This way, commits follow another key aspect of atomicity: doing one thing per commit. The more code a commit touches, the more potential issues arise—making it harder for a reviewer to fully grasp the changes, which increases the risk of missed bugs. And we want to be kind to our reviewers…
I’ll close by citing Fagner Brack again:
This is a principle, not a law. Be thoughtful and make the best decision given the circumstances.