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
The first line (the subject) is what appears in git log --oneline and in your release notes. It should be:
- Under 72 characters
- Written in imperative mood: "add dark mode" not "added dark mode"
- Specific about what changed
- Prefixed with a type (using Conventional Commits)
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:
| Prefix | Meaning | Appears in changelog as |
|---|---|---|
feat: | New feature | Added |
fix: | Bug fix | Fixed |
perf: | Performance improvement | Performance |
refactor: | Code change, no behaviour change | Usually omitted |
docs: | Documentation only | Usually omitted |
chore: | Build, CI, deps — no user impact | Usually omitted |
test: | Tests only | Usually omitted |
feat!: or BREAKING CHANGE: | Breaking change | Breaking Changes (prominent) |
Good vs bad commit messages
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:
- ChangelogAI handles it anyway. Even vague commits produce usable release notes because the AI infers context from the surrounding commits and codebase conventions. It's not perfect, but it's better than starting from scratch.
- Squash and rewrite before releasing. Use
git rebase -ito squash related commits and rewrite the squash message properly before tagging a release. This gives you a clean history to generate notes from.
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):
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 →