Skip to content

Lesson 2 of 9 · 20m

Atomic Commits and Messages That Age Well

Stage hunks with add -p, write messages that record why, and keep secrets out of history.

The commit that ships on Friday at 6 p.m. is never "fix stuff." It's three logical changes glued together: a typo fix, a dependency bump, and half of a feature — and next quarter someone has to bisect through it or revert it without taking the good parts down too. Atomic commits are how you make history useful instead of a crime scene.

Stage hunks, not files

git add -p walks your unstaged changes hunk by hunk and asks y/n/s/e. s splits a hunk, e opens it in your editor for surgical staging. This is the tool that lets you commit "the rate-limit change" separately from "the log cleanup" even though both live in the same file.

Before committing, run git commit -v (or git diff --staged) so the full staged diff sits under your message buffer. You will catch the debug console.log and the accidental config.local.yaml this way at least once a month.

Messages that age well

The convention that has survived every style guide: a subject line of ~50 characters in the imperative mood ("Add", not "Added" or "Adds"), blank line, then a body that explains why, wrapped at 72 columns. The diff shows what changed; the message is the only place the why gets recorded.

Throttle login attempts to 5/min per IP

Credential-stuffing attempts were saturating the auth worker
pool. A fixed-window limiter per source IP blocks the burst
without penalizing NAT'd office users more than briefly.

Ref: SEC-412

Five commits that each do one thing with a real message can be rebased, reverted, cherry-picked, and reviewed. One "updates" commit can only be apologized for.

Security angle: what goes in stays in

Anything committed — API keys, .env files, customer data — is in history on every clone, even if you delete it in the next commit. Prevent it: keep secrets in .gitignore, run a scanner such as gitleaks or trufflehog as a pre-commit check, and if a secret does land, rotate it. git rm is not remediation.

Also: git commit --amend rewrites the commit and changes its SHA. Safe before you push, history-destroying after — the golden rule from the rebase lesson applies here too.

Pitfalls

  • add -p staging is per-hunk, not per-line — unless you use e to edit the hunk manually. Learn e; it's the difference between "close enough" and exact.
  • Amend doesn't just rewrite the message. git commit --amend also folds staged changes into the previous commit — check git status first or you'll absorb unrelated work.
  • Committing the merge conflict markers <<<<<<< happens embarrassingly often after a rushed resolve; git diff --check flags them and leftover whitespace before you commit.

Try this

Make two unrelated edits in one file, then use git add -p to commit them as two separate commits with distinct messages. Check your work with git log -p -2.