// Guide

Git Commit Message Guide

Bad commit messages make release notes painful. Good ones make them automatic. Here's how to write commits that generate great changelogs — and what to do if your history is already a mess.

Try Free — No Account Needed →

Why commit messages matter for release notes

Your git log is the raw material for your release notes, changelog, and deployment documentation. A history full of "fix", "wip", "update stuff", and "asdf" forces you to manually reconstruct what changed every release — which is why release notes get skipped or written badly.

A well-written commit message is a gift to your future self, your teammates, and your users.

The anatomy of a good commit message

structure
type(scope): short description Optional longer body explaining WHY this change was made, not WHAT — the diff shows what. Closes #123

The first line (the subject) is what appears in git log --oneline and in your release notes. It should be:

Conventional Commits — the standard

Conventional Commits is the most widely adopted commit message convention. It prefixes every commit with a type that signals what kind of change it is:

PrefixMeaningAppears in changelog as
feat:New featureAdded
fix:Bug fixFixed
perf:Performance improvementPerformance
refactor:Code change, no behaviour changeUsually omitted
docs:Documentation onlyUsually omitted
chore:Build, CI, deps — no user impactUsually omitted
test:Tests onlyUsually omitted
feat!: or BREAKING CHANGE:Breaking changeBreaking Changes (prominent)

Good vs bad commit messages

❌ bad commits — hard to generate release notes from
fix bug wip update asdf misc cleanup fix the thing from yesterday stuff oops
✓ good commits — generate great release notes automatically
feat: add dark mode toggle in user settings fix: crash when uploading files larger than 50MB perf: reduce dashboard load time by 40% via query optimisation feat!: remove deprecated /api/v1 endpoints — migrate to /api/v2 fix: password reset emails not sending for accounts created before 2024 feat(auth): add TOTP two-factor authentication

What to do when your commit history is a mess

If your team's commit history is full of "fix" and "wip", you have two options:

Team tip: Add a .gitmessage template to your repo with the Conventional Commits format. Set it as the default with git config commit.template .gitmessage — every developer gets the format as a reminder on every commit.

Scopes: optional but useful

The (scope) in feat(auth): ... is optional but useful for larger codebases. It identifies which part of the system was changed. Common scopes: auth, api, ui, db, payments, notifications. Scopes make changelogs easier to filter and understand for large teams.

The commit body: why, not what

The diff shows what changed. The commit body should explain why. This is the most underused part of a commit message and the most valuable for future developers (including yourself in six months):

✓ good commit with body
fix: retry webhook delivery on 5xx responses Without retries, any transient server error on the webhook endpoint would permanently drop the event. This caused data loss for customers running their webhook receivers on unreliable infrastructure. Retries use exponential backoff with jitter: 1s, 2s, 4s, max 3 attempts. Closes #847

Frequently Asked Questions

What are Conventional Commits?

Conventional Commits is a specification for commit message format. Prefixes like feat:, fix:, perf:, and chore: make commit history machine-readable and generate changelogs automatically. See conventionalcommits.org for the full spec.

Does ChangelogAI require Conventional Commits format?

No. ChangelogAI works with any commit format — even messy ones like 'fix stuff' or 'wip'. Conventional Commits makes the output better, but it's not required.

Should the commit message be present or past tense?

Imperative mood (present tense) is the convention: 'add dark mode', not 'added dark mode'. Git's own commit messages use imperative mood, and it reads more naturally in changelogs.

How long should a commit message subject line be?

Under 72 characters. Most tools truncate at 72 characters in log displays. Under 50 is even better — it forces clarity.

What if my team won't follow a commit convention?

Start with linting. Tools like commitlint enforce Conventional Commits on CI, blocking merges for non-compliant messages. Even without linting, ChangelogAI can work with inconsistent commit messages — it just produces cleaner output with good commits.

Related Tools & Guides

Stop writing release notes by hand

Paste your commits. Get polished, publish-ready release notes in seconds. Completely free, no account needed.

Try ChangelogAI Free →