All articles
Engineering 7 min readAugust 13, 2024

Your Commit History Is Your Most Underused Documentation. Here's How to Fix That.

The engineers who can navigate an unfamiliar codebase most efficiently aren't the ones who read the wiki. They're the ones who know how to read the git log.

In 2017, a team at a large e-commerce company spent three weeks debugging an intermittent race condition in their checkout flow. The bug had been present for over a year — it appeared infrequently enough that it had never been conclusively reproduced in staging. When they finally isolated it to a specific commit, the commit message read: "fix bug." The author had left the company. The PR had been squash-merged without a description. Three weeks of debugging effort could have been reduced to thirty minutes if the commit had documented what bug it was fixing and what the non-obvious assumption in the fix depended on.

This story is not unusual. It is, in fact, almost universal. The git history of most codebases is an information graveyard — a sequential record of changes with almost no context about why any of them were made.

What a Good Commit Message Does

A commit message serves three future readers, all of whom need different things.

The first is the engineer debugging a problem. When git blame points to a specific line as the origin of a bug, the commit message is the first piece of context they have. A message that explains why the line was written the way it was — what constraint it was satisfying, what edge case it was handling — can make the difference between understanding the problem in five minutes and spending a day tracing the original intent.

The second is the reviewer evaluating the change. A commit message that explains the problem being solved, the approach considered and rejected, and the tradeoffs in the chosen solution transforms a review from a guessing exercise into a verification exercise. Reviewers who understand intent can evaluate whether the code achieves it. Reviewers who have to infer intent from the code alone miss the gap between what the code does and what it was supposed to do.

The third is the engineer making a future change in the same area. Code that was written to satisfy a specific constraint — a third-party API limitation, a legal requirement, a customer-specific behavior — looks like arbitrary complexity to an engineer who doesn't know the constraint exists. A commit message that documents the constraint prevents the future engineer from "cleaning up" the complexity and reintroducing the problem it was solving.

The Format That Works

The most durable commit message format has three components: a subject line that summarizes what changed, a body that explains why the change was made and what alternatives were considered, and a footer that links to relevant context (issue trackers, external documentation, related commits).

The subject line should complete the sentence "If applied, this commit will..." in under 72 characters. The body should answer the question "Why couldn't this have stayed the way it was?" The footer should ensure that the commit never becomes orphaned from its broader context.

This format takes two to five minutes per commit to write. The payoff is distributed across every future interaction with the code, compounding over the lifetime of the codebase.

Making It a Team Standard

The challenge with commit message quality is that the cost of a bad commit message is paid by future engineers, not by the author. This temporal mismatch means that individual discipline is insufficient — the standard needs to be enforced at the team level to be consistent.

The practical mechanism: add commit message quality to your code review checklist. When a PR contains commits with poor messages, comment on it — not as a blocking concern but as a persistent expectation. Engineers who receive consistent feedback about commit message quality improve within weeks. The codebase that results, over months and years, is materially easier to work in.

Try CodeMouse on your next PR

Free AI code review on every pull request. Bring your own API key — no subscription needed.

Install on GitHub — Free