Conventional Commits Skill
This skill helps create git commits following the Conventional Commits specification v1.0.0.
Instructions
When creating a commit using Conventional Commits, follow these steps:
- •
Analyze the changes:
- •Run
git statusto see staged and unstaged files - •Run
git diffto review the actual changes - •Understand what type of change this represents
- •Run
- •
Determine the commit type:
- •
feat: A new feature (correlates with MINOR in SemVer) - •
fix: A bug fix (correlates with PATCH in SemVer) - •
docs: Documentation only changes - •
style: Changes that don't affect code meaning (formatting, whitespace) - •
refactor: Code change that neither fixes a bug nor adds a feature - •
perf: Performance improvement - •
test: Adding or correcting tests - •
build: Changes to build system or external dependencies - •
ci: Changes to CI configuration files and scripts - •
chore: Other changes that don't modify src or test files
- •
- •
Determine the scope (optional but recommended):
- •The scope should be a noun describing a section of the codebase
- •Examples:
api,parser,auth,ui,database - •Use parentheses:
feat(api):
- •
Check for breaking changes:
- •If the change introduces breaking changes, add
!before the colon - •Example:
feat(api)!:orfeat!: - •MUST also include
BREAKING CHANGE:footer with description
- •If the change introduces breaking changes, add
- •
Construct the commit message:
code<type>[optional scope][!]: <description> [optional body] [optional footer(s)]
- •
Follow these rules:
- •Description should be lowercase and concise
- •Description should complete the sentence "This commit will..."
- •Body should provide additional context (wrap at 72 characters)
- •Footers follow git trailer format:
Token: valueorToken #value - •
BREAKING CHANGE:footer must be uppercase - •Each footer should be on its own line
- •
Create the commit:
- •Use a heredoc for proper formatting:
bashgit commit -m "$(cat <<'EOF' type(scope): description Optional body explaining the changes in more detail. This can span multiple lines. BREAKING CHANGE: description of breaking change Fixes: #123 EOF )"
Commit Message Format
Header
code
<type>[optional scope][!]: <description>
- •type: Required. One of the types listed above
- •scope: Optional. A noun describing the affected section
- •!: Optional. Indicates a breaking change
- •description: Required. Brief summary in present tense
Body
- •Optional
- •Provides additional context about the changes
- •Separated from header by one blank line
- •Can contain multiple paragraphs
Footers
- •Optional
- •Separated from body (or header if no body) by one blank line
- •Follow git trailer format
- •Common footers:
- •
BREAKING CHANGE: <description>(for breaking changes) - •
Fixes: #<issue-number> - •
Refs: #<issue-number> - •
Reviewed-by: <name> - •
Co-authored-by: <name> <email>
- •
Examples
Simple feature
code
feat(auth): add OAuth2 login support
Bug fix with scope
code
fix(parser): handle null values in JSON response
Breaking change with body and footer
code
feat(api)!: redesign user authentication endpoints The authentication flow has been completely redesigned to use JWT tokens instead of session cookies. This provides better scalability and supports mobile clients. BREAKING CHANGE: POST /auth/login now returns a JWT token in the response body instead of setting a session cookie. Clients must include the token in the Authorization header for subsequent requests. Refs: #456
Documentation update
code
docs(readme): update installation instructions
Performance improvement
code
perf(database): optimize query for user search Replaced N+1 query pattern with a single JOIN query, reducing database calls from ~100 to 1 for typical searches. Closes: #789
Multiple footers
code
fix(ui): prevent memory leak in dashboard component The chart component was not properly cleaning up event listeners when unmounted, causing memory leaks in long-running sessions. Fixes: #123 Reviewed-by: Jane Doe Co-authored-by: John Smith <john@example.com>
Chore with no scope
code
chore: update dependencies to latest versions
Breaking change with scope
code
refactor(database)!: migrate from MongoDB to PostgreSQL BREAKING CHANGE: All database queries must be updated to use PostgreSQL syntax. The connection string format has changed.
Best Practices
- •Be consistent: Use the same type names and scope naming conventions across your project
- •Keep descriptions short: Aim for 50-72 characters in the description
- •Use imperative mood: "add feature" not "added feature" or "adds feature"
- •Scope should be specific: Use well-defined, consistent scope names
- •Breaking changes need both: Use both
!andBREAKING CHANGE:footer for clarity - •One concern per commit: Don't mix multiple types (e.g., feat + fix) in one commit
- •Body explains "why": Use the body to explain why the change was made, not what was changed
- •Reference issues: Use footers to link commits to issues/tickets
Integration with SemVer
Conventional Commits work with Semantic Versioning:
- •
fix:type commits = PATCH release (0.0.X) - •
feat:type commits = MINOR release (0.X.0) - •
BREAKING CHANGE:(any type with !) = MAJOR release (X.0.0)
Common Patterns
Multiple files in different areas
If changes span multiple areas, consider:
- •Making separate commits for each area
- •Using a more general scope or no scope
- •Using the most significant change as the type
Reverting commits
code
revert: feat(api): add OAuth2 login support This reverts commit abc123def456.
Work in progress (avoid in main branches)
code
wip(feature): partial implementation of new dashboard
Tools and Automation
This specification enables:
- •Automatic changelog generation
- •Automatic semantic versioning
- •Better git log filtering (
git log --grep="^feat") - •Automated release notes
Notes
- •Conventional Commits is a specification, not a strict rule - adapt to your team's needs
- •Some teams use additional types like
wip,hotfix, orrelease - •The specification is designed to work with automated tools but is human-readable
- •If using commitlint or similar tools, ensure your commits match their configuration