Each commit should contain exactly one logical change. Commits that mix refactoring, bug fixes, and features together make git bisect useless, code review painful, and reverting a single change impossible without losing everything else in the commit.
Why This Matters
Non-atomic commits make reverting a single change impossible — you must revert the entire commit and manually re-apply the parts you wanted to keep. They make git bisect unreliable because a "good" commit may contain an unrelated bug. They make code review slower because reviewers must mentally separate unrelated changes in one diff.
An atomic commit contains exactly one logical change: one bug fix, one feature, or one refactor. When commits mix multiple concerns, three critical git operations break:
git revert becomes dangerous. If a commit contains a bug fix AND a refactor, reverting the bug fix also reverts the refactor. You must manually re-apply the refactor, which is error-prone and time-consuming.
git bisect becomes unreliable. If a commit contains a feature AND an unrelated bug, bisect will flag the commit for the feature when you are looking for the bug. You cannot isolate which change in the commit caused the regression.
Code review becomes painful. Reviewers must mentally separate "this part is the feature" from "this part is a drive-by refactor" within the same diff. Mixed concerns increase review time and reduce review quality.
The rule
Each commit should contain one logical change. If you are fixing a bug and notice something to refactor, make two separate commits. If a feature requires a refactor first, commit the refactor separately, then commit the feature.
Bad example
commit abc123Author: dev@example.comDate: Mon Mar 10 14:30:00 2026 update user profile and fix navbar and refactor utils - Added bio field to user profile page - Fixed navbar z-index issue on mobile - Refactored date formatting utilities - Updated tests
Good example
commit abc123 — refactor: extract date formatting to shared utilitycommit def456 — fix: correct navbar z-index stacking on mobilecommit ghi789 — feat: add bio field to user profile page
Each commit is independently revertable, reviewable, and bisectable.
How to detect
During code review, check if a single commit touches unrelated files or concerns:
git show --stat HEAD
If a commit modifies files in unrelated directories (e.g., components/navbar AND lib/utils AND app/profile), it likely contains multiple logical changes.
Remediation
Before committing, review your staged changes with git diff --staged
If you see unrelated changes, use git add -p to stage only the related hunks
Commit each logical change separately with a descriptive message
If you already made a mixed commit, use git reset HEAD~1 to unstage and re-commit in separate pieces
Establish team conventions: one concern per commit, refactors in separate commits from features