Git Commit Linter: Write Commit Messages Your Team Can Actually Use
A messy commit history makes git log, code review, and automated changelogs harder for everyone. This linter checks your commit message against the widely-used Conventional Commits specification plus classic Git formatting conventions — subject length, imperative mood, and body line wrapping — and tells you exactly what to fix.
Followed by a blank line, then an optional body wrapped at 72 characters.
Why Conventional Commits Format Matters
Prefixing a commit with a type like feat, fix, or chore lets tools like semantic-release automatically determine whether a change is a major, minor, or patch version bump, and lets changelog generators group commits by category without any manual bookkeeping.
The 50/72 Rule
This convention (popularized by Tim Pope's classic 'A Note About Git Commit Messages') says: keep the subject line to 50 characters or less, leave a blank line, then wrap the body at 72 characters. It's not arbitrary — it matches how terminal tools like git log display commit messages by default.
Imperative Mood, Explained
Git's own auto-generated commit messages ('Merge branch', 'Revert...') use imperative mood, so human-written messages should match that style for consistency. A quick test: your subject line should complete the sentence 'If applied, this commit will ___.'
Practical Examples
A Passing Commit Message
Follows Conventional Commits and the 50/72 rule.
- 1.feat(auth): add password reset flow
- 2.
- 3.Sends a reset link via email and expires it after 15 minutes.
- 4.All checks pass
A Commit Message With Issues
Common mistakes this linter catches.
- 1.Subject: 'Fixed the bug in login page that caused errors.'
- 2.Issue: past tense ('Fixed' instead of 'fix')
- 3.Issue: ends with a period
- 4.Issue: 55 characters, over the 50-char guideline
Common Conventional Commit Types
- feat: A new feature
- fix: A bug fix
- docs: Documentation only changes
- refactor: Code change that neither fixes a bug nor adds a feature
- chore: Maintenance tasks, tooling, dependencies
What This Linter Checks
- Subject line length (≤ 50 recommended, ≤ 72 hard limit)
- No trailing period on the subject
- Conventional Commits type(scope): format
- Imperative mood in the description
- Blank line before the body, body wrapped at 72 chars
Frequently Asked Questions
What is Conventional Commits format?
A specification (type(scope): description) for structuring commit messages so tools can automatically generate changelogs and determine semantic version bumps. Common types are feat, fix, docs, style, refactor, perf, test, build, ci, and chore.
Why is imperative mood recommended?
Git itself uses imperative mood for its own generated messages (like 'Merge branch...'), and the convention is that a commit message should complete the sentence 'If applied, this commit will ___' — so 'add feature' reads correctly, but 'added feature' doesn't.
Why does the subject line length matter?
git log --oneline and GitHub's commit list both truncate long subject lines. Keeping it under 50 characters (and never over 72) ensures the summary stays fully readable in every tool that displays it.
Why should the body be wrapped at 72 characters?
It's a long-standing Git convention so that commit messages display cleanly in terminal-based tools like git log, which typically indent output, without needing the terminal to soft-wrap awkwardly.
Does this tool check the diff or just the message?
Just the message. It has no access to your actual code changes — it only lints the text you paste for formatting and structure.
What happens if I don't use a scope?
Scope is optional in Conventional Commits — 'fix: correct off-by-one error' is valid without parentheses. The linter accepts both scoped and unscoped formats.
Is my commit message sent anywhere?
No, all linting runs locally in your browser with plain JavaScript regex checks.