Commit Hygiene That Saves Future You
Part 4 of the “Git & Version Control Mastery” series. “fix”, “fix2”, “asdf”, “final fix” — your git log is a diary of pain nobody can read.
Commit Hygiene That Saves Future You
Part 4 of the “Git & Version Control Mastery” series. “fix”, “fix2”, “asdf”, “final fix” — your git log is a diary of pain nobody can read.
Open the history of almost any project and you’ll find it: a wall of commits named fix, wip, 更新, asdf, final, final for real, and the ever-popular .. Each one represents a real change, but the history is useless — nobody can tell what happened, why, or which commit to look at when something breaks. The code works, but the story of the code is gibberish.
Commit hygiene feels like a nicety until the day you’re staring at a six-month-old bug, running git blame, and the only context you get is fix2. Good commits are a gift to your future self and your teammates. Here's how to write them without slowing down.
A commit isn’t a save button. It’s a unit of meaning — a small, complete change with an explanation of why. Treat it that way and your history becomes documentation that’s always up to date.
What a Good Commit Looks Like
Two properties make a commit valuable: it’s atomic (one logical change) and it’s explained (a message that says why).
❌ A bad commit: 600 lines across 14 files, message "updates"
(Did this add a feature? Fix a bug? Refactor? Who knows.)
✅ Good commits: the same work, split into meaning
- "Add email validation to signup form"
- "Fix timezone bug in order timestamps"
- "Refactor PriceCalculator for readability"
Each good commit is a thing you could describe in one sentence and revert on its own without dragging unrelated changes with it. That’s the whole standard.
Fix #1: One Logical Change Per Commit
The core discipline: don’t mix a bug fix, a feature, and a refactor into one commit. Separate them, because they have different reasons, different risk, and different reasons to be reverted.
- A reviewer can understand a single-purpose commit at a glance.
git bisect(Part 3) can pinpoint a small commit's exact effect; a mixed commit hides the cause.git revertcan cleanly undo one change without collateral damage.
When you realize you’ve made several changes before committing, stage them separately:
git add -p # interactively stage just the chunks for ONE change
git commit -m "Fix timezone bug in order timestamps"
git add -p # now stage the next logical change
git commit -m "Add CSV export to orders page"
git add -p (patch mode) is the underrated tool here — it lets you commit part of your working changes, so messy "I did three things" work becomes clean, separated commits.
Fix #2: Write Messages That Explain Why
The diff already shows what changed. Your message’s job is the why the diff can’t show. A useful format:
Short summary in imperative mood, ~50 chars
Optional body explaining WHY this change was needed, what
problem it solves, and any context or trade-offs. Wrap at ~72
chars. Reference issues: Fixes #423.
A few rules that make messages instantly better:
- Imperative mood: “Add caching” not “Added caching” (it reads as “this commit will add caching”, matching Git’s own messages).
- Summarize the why, not the how: “Fix race condition in payment retry” beats “Change the if statement.”
- Link context: issue numbers, incident references — the breadcrumbs future-you will follow.
git blame on a line should lead to a commit that explains itself, not one that says fix.
Fix #3: Clean Up Before You Share
Your local work-in-progress can be as messy as you like — wip, wip2, "trying something." The discipline is to tidy it before it becomes public. Interactive rebase lets you reshape local history into clean commits:
git rebase -i HEAD~5 # squash, reorder, reword your last 5 local commits
Squash the five wip commits into one meaningful "Add user notifications" commit, reword unclear messages, drop dead-end experiments. The reviewer sees a clean, logical series — not your stream of consciousness. (Remember Part 1: only rebase local commits you haven't shared.)
Putting It Together
- Atomic commits — one logical change each; use
git add -pto separate. - Explain why — imperative summary, a body for context, link the issue.
- Tidy before sharing — interactive rebase to squash and reword local mess.
- Aim for a readable
git log— history as documentation, not a diary of panic.
The Takeaway
Commit hygiene is invisible until the moment you desperately need your history to make sense — debugging a regression, reviewing a PR, or running git blame on a line nobody remembers writing. Atomic, well-explained commits turn your Git history into living documentation: every line traceable to a clear reason, every change revertable on its own, every bug huntable with bisect. It costs almost nothing in the moment — separate your changes, write a real message, tidy before you push — and it pays back every single time someone (usually future you) has to understand why the code is the way it is.
This is Part 4 of the Git & Version Control Mastery series. Next up: a branching strategy that doesn’t hurt — choosing how your team uses branches without drowning in process.
What’s the worst commit message you’ve ever written (or inherited)? 👇
메타데이터
- post_id
- fe7302cfdb2a
- slug
- commit-hygiene-that-saves-future-you-fe7302cfdb2a
- url
- https://medium.com/@najmul.hasan284/commit-hygiene-that-saves-future-you-fe7302cfdb2a
- canonical_url
- https://medium.com/@najmul.hasan284/commit-hygiene-that-saves-future-you-fe7302cfdb2a
- author_url
- https://medium.com/@najmul.hasan284
- status
- ok
- fetched_at
- 2026-06-23 03:48:11