Skip to content

Practice: Commit hygiene

Answer each in your own words first, then open the answer to check.

Q1. A commit message reads: fix. Three weeks later, the change associated with this commit causes a regression. What two specific problems does the bad message cause for the person debugging?

Show answer

Two problems: (1) the future debugger cannot tell what was fixed without reading the diff line-by-line, which converts a 5-minute scan into an hour of code-archaeology; (2) they cannot tell whether the fix was for the regression in question or for an unrelated bug from the same era, so they cannot rule the commit in or out as the cause without understanding it fully.

Q2. Explain the atomic commit principle in one sentence, then explain why it makes git revert safer.

Show answer

Atomic commit principle: each commit represents exactly one logical change. This makes git revert safer because reverting an atomic commit reverses exactly one logical thing; reverting a kitchen-sink commit reverses three unrelated things at once, often re-introducing bugs or undoing useful work that was bundled in.

Q3. A teammate is about to commit changes to four files that include: a bugfix in file A, a refactor in file B, a new feature in file C, and an unrelated typo fix in file D. They are about to commit it all as End of day work. Using the staging area, walk them through the correct approach (what commands, in what order, with what intent).

Show answer
Terminal window
git status # see all 4 changes
git add fileA.js
git commit -m "Fix crash on empty address"
git add fileB.js
git commit -m "Refactor address-validator for testability"
git add fileC.js
git commit -m "Add CSV export to reports page"
git add fileD.js
git commit -m "Fix typo in error message"
git status # confirm clean
git log --oneline # see 4 atomic commits

Four atomic commits instead of one End of day work. Each can be reverted, reviewed, and understood independently.

Q4. Write a Conventional Commits subject line for each of these:

  • Fixing a crash on the login page when password is empty
  • Adding a new dark-mode theme to the settings UI
  • Updating the README with installation instructions
  • Refactoring the payment module to use the new error-handling helper
  • Bumping React from version 18 to version 19
Show answer
  • fix(auth): handle empty password on login
  • feat(settings): add dark-mode theme option
  • docs(readme): add installation instructions
  • refactor(payment): use new error-handling helper
  • chore(deps): bump React from 18 to 19

Q5. A commit message reads: Refactor user-service. The diff touches 200 lines across 8 files. As a reviewer, what is missing from the message that would help you evaluate the change?

Show answer

The body. A 200-line refactor across 8 files needs an explanation of: WHY the refactor was undertaken (what was wrong with the previous code?), WHAT the new structure is (what is the design intent?), what alternatives were considered, what callers need to know about behavior changes. Without the body, the reviewer has to reverse-engineer all of this from the diff, which takes hours.

Take each of these bad commit messages and rewrite them as professional commit messages with subject line + body. You can make up reasonable context for the change (the goal is to practice the structure, not to recover the original intent).

  1. fix
  2. update
  3. Various changes
  4. WIP
  5. Added login form, fixed nav bug, updated docs
  6. Refactor
  7. final version

For each rewrite, your subject line should:

  • Be under 72 chars
  • Use imperative mood
  • Be capitalized, no trailing period
  • Specify WHAT changed

Your body (where the change is non-trivial) should:

  • Explain WHY
  • Reference issues/tickets if relevant
  • Capture any rejected alternatives if interesting

Set up: in a sandbox project (or create one with git init), have three independent changes ready in your working directory:

  • Change 1: add a new function greet(name) to utils.js
  • Change 2: fix a typo in README.md
  • Change 3: update .gitignore to ignore a new build artifact

Now commit each as a separate atomic commit:

  1. git status to see all three changes
  2. git add utils.js
  3. git commit -m "Add greet() helper to utils"
  4. git status to confirm utils is committed, others still unstaged
  5. git add README.md
  6. git commit -m "Fix typo in installation section"
  7. git status to confirm
  8. git add .gitignore
  9. git commit -m "Ignore build/ directory artifacts"
  10. git status to confirm clean tree
  11. git log --oneline to see the three atomic commits

You have just done in 11 commands what could have been one sloppy git add . && git commit -m "stuff". The history now tells three stories instead of one tangled one.

Scenario A. A developer joins your team and submits a pull request with five commits, all with messages like wip, more wip, actually wip, wip again, and final. Reviewers cannot easily evaluate the change because each commit is incomplete. What is the systemic fix (not the per-PR fix), and why is it worth investing team time in?

Show answer

The systemic fix is squashing WIP commits before opening the PR (or before merging). Most teams either (a) require contributors to squash their own commits via rebase before opening the PR, or (b) use “Squash and merge” as the default merge strategy on the platform (GitHub, GitLab). The investment is worth it because PRs become reviewable units (one logical change per PR) instead of being five-commit archaeology projects.

Scenario B. Your team uses Conventional Commits. A developer submits a PR with a subject line Updated the user model. The CI bot rejects the PR because the subject does not match the conventional format. The developer pushes back: “the message is clear enough, why does the format matter?” How do you answer them in two sentences without being condescending?

Show answer

“The format matters because our release tooling parses commit messages to automatically decide the next version number (fix commits bump the patch number, feat commits bump the minor, breaking changes bump the major). Without the convention, the tooling falls back to manual version decisions, which is exactly the busywork the convention removes.” (One sentence on tooling, one sentence on the cost of inconsistency.)

Scenario C. A solo open-source maintainer has been writing commits with messages like fix, update, cleanup for two years. They now want to add automated semantic release tooling that parses Conventional Commits. What is the cost of having two years of non-conventional history, and what should they do going forward?

Show answer

Cost of the existing history: semantic-release tooling cannot generate a meaningful changelog from non-conventional commits, so historical releases will have empty or incorrect changelogs. Going forward: adopt Conventional Commits starting from a specific date or version, document it in CONTRIBUTING.md, and configure the tooling to start from a specific commit. The two-year backlog cannot be retroactively fixed without rewriting history (which breaks anyone who has cloned the repo); accepting the backlog as legacy and starting fresh is the realistic path.

Q. What are the five rules for a good commit subject line?
A.

(1) Under 50-72 chars, (2) Imperative mood, (3) Capitalized, (4) No trailing period, (5) Subject answers WHAT; body answers WHY.

Q. What is an atomic commit?
A.

A commit that represents exactly one logical change, so it can be reverted, reviewed, and read independently.

Q. How does the staging area enable atomic commits when working-directory changes are mixed?
A.

git add <specific files> stages only the files belonging to one logical change. Commit that, then stage and commit the next logical change separately.

Q. What does Conventional Commits format look like?
A.

<type>(<scope>): <description> where type is feat/fix/docs/refactor/test/chore/style/perf and scope is optional. Example: fix(auth): handle empty password on login.

Q. When is Conventional Commits worth adopting?
A.

When working on a team or open-source project that has adopted it, or when you want automated release tooling. Optional for solo projects; using it inconsistently is worse than not using it.

Q. What is the 'could this be two commits?' test?
A.

When deciding whether to commit, ask whether the change is one logical thing. If you would describe it with “and” or “also” in the subject, split it into separate commits.

Q. Name five commit anti-patterns.
A.

Vague verbs (fix, update), kitchen-sink commits (many unrelated changes), end-of-day mega-commits, fix-the-previous-commit cascades, body-less commits on complex changes.

Q. Why does commit hygiene matter at the team-scaling threshold?
A.

Solo developers can survive bad commits. Teams of 5+ cannot, nobody can answer “why was this change made?” by reading the commit alone. The commit history is institutional memory; bad commits make it black-box.

Q. What does git add -p do and when is it useful?
A.

Stages parts of a file (patch mode). Walks through each chunk asking y/n/s. Useful when a single file contains changes for two different commits.

Q. What goes in a commit body that the diff does not already show?
A.

The WHY: what problem the change solves, what alternatives were considered and rejected, what the reviewer needs to evaluate, what related issues or tickets exist.