This skill provides guidelines for writing consistent and meaningful Git commit messages following the Conventional Commits specification with enhanced professional terminology formatting.
Conventional Commits is a specification for adding human and machine readable meaning to commit messages. It makes it easier to write automated tools on top of the commit history. This enhanced version emphasizes proper formatting of technical terms using backticks.
Each commit message consists of a header, an optional body, and an optional footer.
<type>(<scope>): <subject> #<issue> !<mr|pr>
[optional body]
[optional footer(s)]
The header is mandatory and must conform to the format:
<type>(<scope>): <subject> #<issue> !<mr|pr>
# (e.g., #123).| **mr | pr**: Optional. Merge Request or Pull Request ID prefixed with ! (e.g., !456). |
| Type | Description |
|---|---|
feat |
New feature |
perf |
Performance improvement or functionality enhancement |
breaking |
Backwards-incompatible change that causes compatibility issues |
fix |
General bug fix that is externally perceivable |
security |
Security issue fix (prefer over fix for security issues) |
cosmetic |
UI issue fix, can be abbreviated as cos |
exception |
Exception-triggering issue fix, including frontend JS exceptions |
test |
Writing, correcting, or supplementing test cases |
docs / doc |
Documentation update |
refactor |
Code refactoring |
lint |
Code style changes (formatting, convention compliance adjustments) |
style |
(*lint) Prefer lint; use only for pure formatting changes |
typo |
Typo correction |
chore |
Miscellaneous tasks (avoid when a more specific type can be used) |
ci |
CI/CD tasks |
build |
Build tasks (boundary with CI/CD may be fuzzy) |
release |
Release tasks (e.g., version bump operations) |
revert |
Code revert |
The following types from kazupon/git-commit-message-convention are also supported as aliases:
| Type | Maps To | Description |
|---|---|---|
new |
feat |
for new feature implementing commit |
feature |
feat |
for new feature implementing commit (equal new) |
bug |
fix |
for bug fix commit |
performance |
perf |
for performance issue fix commit |
improvement |
perf |
for backwards-compatible enhancement commit |
deprecated |
- | for deprecated feature commit |
examples |
docs |
for example code commit |
dependency |
build |
for dependencies upgrading or downgrading commit |
config |
chore |
for configuration commit |
update |
- | for update commit |
wip |
- | for work in progress commit |
The scope should be the name of the module/component affected. Examples:
coreapiuiauthconfigdepsGood Examples:
feat(auth): add `OAuth2` login supportfix(api): resolve `null` pointer exception in `UserServicedocs(readme): update `install()` instructionsfeat(auth): add `OAuth2` login support #123fix(api): resolve `null` pointer in `userService` #456 !789chore(deps): update `webpack` to v5 #100 !200Bad Examples:
feat(auth): add OAuth2 login support (technical term not wrapped)fix(api): resolve null pointer exception (keywords not wrapped)feat: Added OAuth2 login support. (capitalized, ends with dot)Add issue ID prefixed with # to link the commit to a specific issue:
#<issue-number>feat(auth): add login #123Add Merge Request or Pull Request ID prefixed with ! to link the commit:
!<mr|pr-number>feat(auth): add login #123 !456Example:
feat(auth): add `OAuth2` login support
Implement `OAuth2` authentication flow to allow users to sign in with
third-party providers. This replaces the previous `BasicAuth` mechanism
which was less secure and harder to maintain.
The implementation supports `Google`, `GitHub`, and `Microsoft` providers.
New functions added:
- `authenticateWithProvider()`
- `handleCallback()`
- `getUserInfo()`
The footer can contain:
BREAKING CHANGE: followed by descriptionCloses #123, Fixes #456Breaking Change Example:
refactor(core): rename configuration options #200 !300
BREAKING CHANGE: Configuration options have been renamed for clarity:
- `maxItems` is now `maxLimit`
- `showAll` is now `displayAll`
Update your configuration files accordingly.
Wrap the following technical elements with single backticks:
calculateTotal(), getUserDataUserService, ButtonComponentuserId, isLoadingpackage.json, /src/utils/helpers.jsnpm install, git commitnull, undefined, this, async, awaitmaxRetries, timeoutGET, POST, PUT, DELETE200, 404, 500React, Vue, ExpressBefore (Poor):
fix(api): handle undefined values in user service
Fixed a bug where the application would crash when user data was missing.
The getUserData function now properly validates responses and returns
default values instead of crashing.
After (Enhanced):
fix(api): handle `undefined` values in `UserService`
Fixed a bug where the application would crash when user data was missing.
The `getUserData()` function now properly validates responses and returns
default values instead of crashing.
Added null checks for `userId` and `email` properties.
fix(button): resolve `click` event not firing on `iOS`
feat(auth): add `OAuth2` login support #123
fix(api): resolve `null` pointer in `UserService` #456 !789
feat(dropdown): add `keyboard` navigation support #101
Users can now navigate dropdown options using arrow keys and select
with `Enter`. This improves accessibility and user experience for
keyboard-only users.
New methods implemented:
- `handleKeyDown()`
- `selectOption()`
- `closeDropdown()`
Event listeners added for `keydown` events on `dropdown-container`.
refactor(core): rename configuration options #200 !300
BREAKING CHANGE: Configuration options have been renamed for clarity:
- `maxItems` is now `maxLimit`
- `showAll` is now `displayAll`
Update your `config.json` files accordingly.
The `initConfig()` function signature has changed.
fix(parser): handle malformed `JSON` input #123 !456
Add validation to prevent crashes when parsing invalid `JSON` data.
The `parseData()` function now uses `try-catch` blocks and returns
`null` for invalid inputs.
Fixes #123
Closes #456
Be Specific: Vague messages like "fix bug" or "update code" are unhelpful.
Keep It Short: Subject line should be under 72 characters.
Use Imperative Mood: Write as if you're giving a command: "add feature" not "added feature".
Explain Why, Not What: The diff shows what changed; the message should explain why.
Reference Issues: Link to relevant issues, PRs, or tickets.
Atomic Commits: Each commit should represent one logical change.
Format Technical Terms: Always wrap technical elements with backticks for clarity.
Consistent Formatting: Apply the same formatting rules across all commits.
Professional Language: Use precise technical terminology appropriate for the domain.
This convention works well with:
module.exports = {
extends : ['@commitlint/config-conventional'],
rules : {
'type-enum' : [2, 'always', [
// Recommended types
'feat',
'perf',
'breaking',
'fix',
'security',
'cosmetic',
'cos',
'exception',
'test',
'docs',
'doc',
'refactor',
'lint',
'style',
'typo',
'chore',
'ci',
'build',
'release',
'revert',
// Type aliases
'new',
'feature',
'bug',
'performance',
'improvement',
'deprecated',
'examples',
'dependency',
'config',
'update',
'wip',
]],
'subject-case' : [2, 'never', ['upper-case']],
'subject-full-stop' : [2, 'never', '.'],
'header-max-length' : [2, 'always', 72],
},
};
{
"scripts" : {
"commit" : "cz",
"release" : "standard-version",
"release:beta" : "standard-version --prerelease beta"
}
}