Skip to main content
โšก Calmops

Git Commit Message Style Guide

Write commits that explain intent, not just code changes

Why Commit Messages Matter

A good commit message is not decoration. It is a maintenance tool.

When teams debug regressions, audit incidents, prepare release notes, or review history during refactors, they rely on commit messages to understand intent quickly. If commit history is full of messages like fix, update, or changes, the repository becomes harder to operate.

Good commit messages reduce onboarding time, improve code review quality, and make rollback decisions safer.

Core Structure

Use three sections:

type(scope): subject

body

footer

Only the first line is required. Body and footer are optional but recommended for non-trivial changes.

Subject Line Rules

Recommended constraints:

  1. Keep subject around 50 characters.
  2. Use imperative mood (add, fix, remove, not added, fixed).
  3. Do not end with a period.
  4. Communicate outcome, not activity.

Good:

fix(auth): reject expired refresh tokens

Bad:

fixed some auth stuff.

A practical set of types:

  1. feat: new user-facing capability.
  2. fix: bug fix.
  3. docs: docs-only change.
  4. style: formatting only, no logic change.
  5. refactor: code restructuring without behavior change.
  6. test: tests only.
  7. chore: tooling/build/dependency maintenance.
  8. perf: performance improvement.
  9. ci: CI/CD pipeline changes.
  10. revert: rollback of prior commit.

Use what your team can enforce consistently.

What to Put in the Body

Body explains what changed and why.

Do not repeat code diff details line by line. Git already stores the diff. The body should provide decision context.

Good body content:

  1. Problem context.
  2. Decision rationale.
  3. Constraints or trade-offs.
  4. Side effects and migration notes.

Wrap body lines near 72 characters for terminal readability.

Use footer for machine-readable metadata.

Examples:

Closes: #824
Refs: OPS-1172
Breaking-Change: auth cookie name changed to __Host-session

If your release tooling parses conventional commits, keep footer format strict.

Conventional Commits Example Set

Feature

feat(payments): add idempotency key validation

Prevent duplicate charge creation during client retry storms.
Validation now rejects reused keys outside the configured TTL.

Closes: #413

Bug fix

fix(cache): avoid stale profile reads after password reset

Invalidate profile cache on credential update path.
Previously users saw stale security metadata for up to 10 minutes.

Refactor

refactor(api): split account handlers into bounded modules

No behavior change. Improves ownership boundaries and test setup.

Breaking change

feat(config): rename APP_PORT to HTTP_PORT

Standardize naming across services and deployment templates.

Breaking-Change: APP_PORT is no longer read at startup

Commit Granularity Guidelines

A commit should represent one logical change.

Too large:

  1. Multiple unrelated features.
  2. Refactor + behavior change + formatting in one commit.

Too small:

  1. “fix typo” repeated 20 times in same file flow.

Practical rule: if commit message requires and three times, split it.

Anti-Patterns to Avoid

  1. update
  2. fix bug
  3. wip
  4. final
  5. asdf

These messages hide intent and make history operationally useless.

Team Policy You Can Adopt

Minimal policy:

  1. Require type: subject structure.
  2. Require imperative subject.
  3. Require body for feat, fix, and perf.
  4. Require issue reference for production-impacting changes.
  5. Block ambiguous commit subjects in CI with lint tooling.

Commit Message and Release Automation

If you use semantic release tooling:

  1. feat triggers minor bump.
  2. fix triggers patch bump.
  3. breaking change footer triggers major bump.

Disciplined commit formatting enables changelog generation and safer automated releases.

Rewriting History Safely

Before pushing:

git commit --amend
git rebase -i HEAD~5

After shared branch push, avoid rewriting unless team process explicitly permits it.

Practical Checklist Before Committing

  1. Does subject state outcome clearly?
  2. Is this one logical change?
  3. Does body explain why?
  4. Are side effects documented?
  5. Is issue/work item linked if needed?

Conclusion

Commit messages are part of your engineering interface. Clear commit history turns a codebase from “just files” into an auditable, maintainable system.

If your team improves only one workflow habit this quarter, improve commit quality. The payoff compounds.

Resources

Comments