Git Commit Message Generator
Generate conventional commit messages following Angular, Conventional Commits standards. Create semantic git commits. Free commit message builder
A good commit message is a contract with your future self at 2am when production is on fire and git log -p is the only documentation. "fixed stuff" violates that contract; "fix: prevent null user in session middleware after token refresh" honors it. This generator helps you write Conventional Commits — the format used by Angular, semantic-release, every modern monorepo, and most CI changelog tools — with type, scope, summary, body, and breaking-change footers.
The Conventional Commits format
<type>(<optional scope>)<!?>: <description>. Followed by an optional body, then optional footers. The full spec is 1.0.0 (2019), used by Angular, Vue, Nest, electron, and most JavaScript projects. Adoption in other ecosystems (Python, Go, Rust) is partial but growing.
- feat — a new user-facing feature. Triggers a MINOR version bump in semantic-release.
- fix — a bug fix. Triggers a PATCH version bump.
- docs — documentation only.
- style — code formatting, missing semicolons, no logic change.
- refactor — code changes that neither fix bugs nor add features.
- perf — performance improvement.
- test — adding or correcting tests.
- build — changes to build system or dependencies.
- ci — CI configuration changes.
- chore — maintenance tasks (no production code change).
- revert — reverting a previous commit.
- ! suffix on type, or BREAKING CHANGE: footer — indicates breaking change. Triggers a MAJOR version bump.
Working example: a real bug fix
Input
Change: prevent null pointer in session middleware when JWT refresh fails partway through. Affects /api/* endpoints. Was causing 500 errors observed in Sentry issue #4827.
Output
fix(auth): handle null user after partial JWT refresh failure When the refresh-token call to the IdP returned 200 with a malformed payload, the session middleware proceeded with req.user undefined, then exploded at the first call site that read req.user.id. Now: explicitly validate the refreshed token shape before storing, and if validation fails, return 401 and force re-login. Fixes #4827
Subject line (50-72 chars), imperative mood ("handle" not "handled"), no trailing period. Body wrapped at 72 chars, explains WHY not WHAT (the diff shows what), references the issue. Conventional commit type "fix" with scope "auth" generates the right semantic-release category.
The conventions everyone agrees on
- Subject line ≤72 characters. Git GUIs and email lists wrap at 72; longer lines look broken.
- Imperative mood ("add" not "added", "fix" not "fixes"). Treat the commit as completing the sentence "If applied, this commit will…".
- Capitalize the first letter (or the type, in Conventional Commits). No period at the end of the subject.
- Blank line between subject and body. Without it, git interprets the body as a continuation of the subject.
- Body explains the WHY. The diff shows the WHAT. If your message duplicates the diff, you are wasting commit-message space.
- Reference issues in the footer (Fixes #123, Closes #456, Related to JIRA-789). Many CI tools auto-link.
The conventions that depend on your team
- Conventional Commits vs free-form — projects using semantic-release require Conventional. Other teams use it loosely or not at all.
- Scope conventions — module name, package name, file area, or no scope. Pick one and stick to it.
- Squash vs preserve — when merging a feature branch, do you squash to one commit or keep the history? Squash is cleaner for changelogs; preserved history is more useful for git bisect.
- Body required vs optional — small one-line fixes ("fix: typo in README") usually skip the body. Anything substantive should have one.
- Co-authored-by trailers — when pairing or AI-assisted, add Co-authored-by: Name <email> footers for attribution and GitHub contribution counting.
When to reach for this tool
- You are writing a commit at 6pm Friday and want a template that prevents "wip" from being the message.
- You inherited a repo that uses semantic-release and want to make sure your commit triggers the right version bump.
- You are setting up a new repo and want a commit-msg hook example using Commitlint.
- You are reviewing a PR with vague commit messages and want a reference for the format you wish the author had used.
What this tool will not do
- It will not write the message for you from a diff. Without knowing intent, a generator can only produce generic "update X" messages that defeat the purpose.
- It will not run as a git hook. For commit-msg validation, use Commitlint or husky locally — they hook into git directly.
- It will not retroactively fix history. Once a commit is pushed, rewriting messages requires force-push, which is destructive on shared branches. Get it right at commit time.
Frequently asked questions
Why imperative mood?
Git itself uses imperative for its automatic commits ("Merge branch X", "Revert commit Y"). Matching that style keeps your messages consistent with git's own. The mnemonic: "If applied, this commit will…" — followed by your subject line as a verb phrase.
Do I have to use Conventional Commits?
No. It is a convention popular in JavaScript/TypeScript ecosystems and increasingly elsewhere. The benefits — automated changelogs, semantic versioning, machine-readable history — only matter if you have tooling that consumes them. For a small personal project, "fix typo" is fine.
What is a "breaking change" footer?
Either ! after the type (feat!: ...) or a BREAKING CHANGE: <description> line in the footer. Tells semantic-release to bump major version. Required for any change that breaks downstream consumers — API renames, removed fields, schema changes, behavior changes that existing callers depend on.
How long should the body be?
As long as needed, no longer. A complex change explaining design trade-offs may run hundreds of words. A small fix needs none. Default to "if I read this in two years cold, would I understand WHY?" — write to that bar.
Should I reference Jira / Linear tickets?
Yes, in the footer. Most issue trackers auto-link from commit messages and many CI tools update ticket status on push. Convention: "Closes JIRA-123" closes the issue on merge; "References JIRA-123" just links without closing.
What is the difference between fix and chore?
fix is for code that addresses bugs visible to users or callers. chore is for non-functional changes — dependency bumps without behavior change, README updates, .gitignore tweaks. A typo fix in a public-facing string is fix (changed user-visible text); a typo fix in an internal comment is chore.
Related tools
Generate .gitignore files for any project. Templates for Node, Python, Java, Go, React, Vue, and more. Free online gitignore generator
Build docker-compose.yml files visually. Add MySQL, PostgreSQL, Redis, MongoDB services. Free online Docker Compose YAML generator
Format and beautify JSON, XML, CSS, HTML, JavaScript, SQL code. Auto-indent and syntax highlight. Free online code beautifier and formatter
Build Git commands interactively with options and flags. Learn branching, merging, rebasing with visualizations. Quick recipes for common Git workflows
Last updated · E-Utils editorial team