commitlint checks if your commit message meets the conventional commit format
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Download binary from releases and add it to your PATH
go install github.com/conventionalcommit/commitlint@latest
cd to repository directorycommitlint init
commitlint init --global
--hookspath with desired locationcommitlint init --hookspath /path/to/hooks
commitlint init --global --hookspath /path/to/hooks
commitlint hook to create .commitlint/hooks containing git hooks--hookspath or -p to customize the hooks output pathgit config core.hooksPath /path/to/.commitlint/hooksgit config --global core.hooksPath /path/to/.commitlint/hookscommitlint remove
commitlint remove --global
Both commands ask for confirmation before unsetting core.hooksPath in git config. Hook files are left intact.
echo "feat: good commit message" | commitlint lint
# ✔ commit message
echo "fear: do not fear for commit message" | commitlint lint
# ❌ type-enum: type 'fear' is not allowed, you can use one of [build chore ci docs feat fix merge perf refactor revert style test]
To create a config file, run commitlint config create, this will create .commitlint.yaml with only the enabled rules and their settings (compact format)
To create a config file with all rules and settings written out (including disabled ones), run commitlint config create --all
To validate a config file, run commitlint config check /path/to/conf.yaml
To lint a message, you can use any one of the following
- run commitlint lint --message=file
- run echo "message" | commitlint lint
- run commitlint lint < file
commitlint lint follows below order for config and message
--config command-line argumentCOMMITLINT_CONFIG env variablestdin pipe stream--message command-line argument.git/COMMIT_EDITMSG in current directorycommitlint hook--hookspath or -p to customize the hooks output directory--replace or -r to overwrite existing hook filesTo prints useful information for debugging commitlint
run commitlint debug
min-version: v0.11.0
formatter: default
rules:
- header-min-length
- header-max-length
- body-max-line-length
- footer-max-line-length
- type-enum
severity:
default: error
rules: {}
settings:
body-max-line-length:
argument: 100
flags: {}
footer-max-line-length:
argument: 100
flags: {}
header-max-length:
argument: 72
flags: {}
header-min-length:
argument: 10
flags: {}
type-enum:
argument:
- feat
- fix
- docs
- style
- refactor
- perf
- test
- build
- ci
- chore
- revert
flags: {}
disable-default-ignores: false
ignores: []
Commonly used commit types
| Type | Description |
|---|---|
| feat | A new feature |
| fix | A bug fix |
| docs | Documentation only changes |
| style | Changes that do not affect the meaning of the code (white-space, formatting etc) |
| refactor | A code change that neither fixes a bug nor adds a feature |
| perf | A code change that improves performance |
| test | Adding missing tests or correcting existing tests |
| build | Changes that affect the build system or external dependencies |
| ci | Changes to our CI configuration files and scripts |
| chore | Other changes that don't modify src or test files |
| revert | Reverts a previous commit |
commitlint automatically skips linting for commit messages generated by git (merges, reverts, fixups, etc.). If the first line of a commit message matches any ignore pattern, linting is skipped entirely.
The following patterns are enabled by default
(source: config/default.go):
| Pattern | Matches |
|---|---|
^Merge pull request #\d+ |
GitHub pull request merges |
^Merge .+ into .+ |
Generic merge (X into Y) |
^Merge branch '.+' |
git merge branch |
^Merge tag '.+' |
git merge tag |
^Merge remote-tracking branch '.+' |
git merge remote-tracking branch |
^Merged .+ (in\|into) .+ |
Azure DevOps / Bitbucket merged |
^Merged PR #?\d+ |
Azure DevOps pull request |
^(R\|r)evert |
git revert |
^(R\|r)eapply |
git reapply |
^(amend\|fixup\|squash)! |
git commit --fixup/--squash/--amend |
^Automatic merge |
Automatic merges |
^Auto-merged .+ into .+ |
Auto-merged branches |
^Initial commit$ |
Initial commit (exact match) |
Add your own patterns in the config file under ignores:. User-defined patterns are
additive, they are checked alongside the built-in defaults.
ignores:
- "^WIP "
- "^TICKET-\\d+"
If you want only your custom patterns (no built-in defaults), set disable-default-ignores: true:
disable-default-ignores: true
ignores:
- "^WIP "
Rules marked ✅ enabled are active by default. All others can be opted into via the rules: list in your config.
| name | argument | flags | description | default |
|---|---|---|---|---|
header-min-length |
int | n/a | min length of header (first line) | ✅ enabled (10) |
header-max-length |
int | n/a | max length of header (first line) | ✅ enabled (72) |
body-min-length |
int | n/a | min length of body | N/A |
body-max-length |
int | n/a | max length of body | N/A |
body-max-line-length |
int | n/a | max length of each line in body | ✅ enabled (100) |
footer-min-length |
int | n/a | min length of footer | N/A |
footer-max-length |
int | n/a | max length of footer | N/A |
footer-max-line-length |
int | n/a | max length of each line in footer | ✅ enabled (100) |
type-min-length |
int | n/a | min length of type | N/A |
type-max-length |
int | n/a | max length of type | N/A |
scope-min-length |
int | n/a | min length of scope | N/A |
scope-max-length |
int | n/a | max length of scope | N/A |
description-min-length |
int | n/a | min length of description | N/A |
description-max-length |
int | n/a | max length of description | N/A |
| name | argument | flags | description | default |
|---|---|---|---|---|
type-enum |
[]string |
n/a | restrict type to given list of strings | ✅ enabled |
scope-enum |
[]string |
allow-empty: bool |
restrict scope to given list of strings | N/A |
footer-enum |
[]string |
n/a | restrict footer token to given list | N/A |
footer-type-enum |
[]{token, types, values} |
n/a | enforce footer notes for given type | N/A |
| name | argument | flags | description | default |
|---|---|---|---|---|
type-charset |
string | n/a | restrict type to given charset | N/A |
scope-charset |
string | n/a | restrict scope to given charset | N/A |
All case rules accept one of: lower-case, upper-case, camel-case, kebab-case, pascal-case, sentence-case, snake-case, start-case.
| name | argument | flags | description | default |
|---|---|---|---|---|
type-case |
string | n/a | enforce case format on type | N/A |
scope-case |
string | n/a | enforce case format on scope (skips empty) | N/A |
description-case |
string | n/a | enforce case format on description | N/A |
body-case |
string | n/a | enforce case format on entire body | N/A |
header-case |
string | n/a | enforce case format on full header | N/A |
These rules enforce that a field is not empty.
| name | argument | flags | description | default |
|---|---|---|---|---|
type-empty |
n/a | n/a | type must not be empty | N/A |
scope-empty |
n/a | n/a | scope must not be empty | N/A |
body-empty |
n/a | n/a | body must not be empty | N/A |
footer-empty |
n/a | n/a | footer must not be empty | N/A |
description-empty |
n/a | n/a | description must not be empty | N/A |
Check that a field does not end with a given character (default ".").
| name | argument | flags | description | default |
|---|---|---|---|---|
header-full-stop |
string | n/a | header must not end with given char (e.g. ".") |
N/A |
$ claude mcp add commitlint \
-- python -m otcore.mcp_server <graph>