Conventional Commits
Commit git changes using the Conventional Commits v1.0.0 specification.
Commit Message Format
<type>[optional scope]: <description> [optional body] [optional footer(s)]
Commit Types
| Type | Description | SemVer |
|---|---|---|
feat | New feature | MINOR |
fix | Bug fix | PATCH |
docs | Documentation only | - |
style | Formatting, whitespace (no code change) | - |
refactor | Code restructuring (no feature/fix) | - |
perf | Performance improvement | - |
test | Adding/updating tests | - |
build | Build system or dependencies | - |
ci | CI configuration | - |
chore | Maintenance tasks | - |
revert | Reverting commits | - |
Breaking changes: Add ! after type/scope (e.g., feat!: or feat(api)!:) or include BREAKING CHANGE: footer.
Workflow
- •
Analyze workspace state
bashgit status git diff --stat git diff --staged --stat
- •
Review actual changes for each modified file to understand the nature of changes:
bashgit diff <file> # unstaged git diff --staged <file> # staged
- •
Group changes logically
- •Separate commits (default): Each distinct change gets its own commit
- •Combined commits: Only when changes are tightly coupled and make no sense apart
Examples of separate commits:
- •Adding a feature + updating docs → 2 commits
- •Fixing bug A + fixing bug B → 2 commits
- •Refactoring module X + adding tests → 2 commits
Examples of combined commits:
- •Feature code + its unit tests (if tests only make sense with the feature)
- •Migration file + model changes (if they're atomic)
- •
Determine commit order
- •Infrastructure/build changes first
- •Core functionality before dependent features
- •Tests can go with or after the code they test
- •Documentation typically last
When order is ambiguous: Ask the user before proceeding.
- •
Stage and commit each group
bashgit add <files> git commit -m "<type>[scope]: <description>"
Writing Good Commit Messages
Description (first line):
- •Use imperative mood: "add feature" not "added feature"
- •No period at end
- •Under 72 characters
- •Be specific: "fix null pointer in user auth" not "fix bug"
Scope (optional):
- •Module, component, or area affected
- •Examples:
feat(auth):,fix(parser):,docs(readme):
Body (when needed):
- •Explain what and why, not how
- •Wrap at 72 characters
- •Separate from description with blank line
Footer (when needed):
- •
BREAKING CHANGE: <description>for breaking changes - •
Refs: #123for issue references - •
Reviewed-by: Namefor attribution
Examples
# Simple feature git add src/auth/oauth.py git commit -m "feat(auth): add OAuth2 support for Google login" # Bug fix with scope git add lib/parser.js git commit -m "fix(parser): handle empty arrays in JSON input" # Docs only git add README.md git commit -m "docs: add installation instructions for Windows" # Breaking change git add api/v2/ git commit -m "feat(api)!: redesign user endpoints for v2 BREAKING CHANGE: /users endpoint now requires authentication. Old endpoint /users/list is removed, use /users instead." # Refactor with body git add src/utils/ git commit -m "refactor(utils): extract date formatting to separate module Moved date formatting logic from multiple components into a centralized utils/dates.py module to reduce duplication and ensure consistent formatting across the application."
Handling Ambiguity
Ask the user when:
- •Multiple unrelated changes exist and commit order matters for history
- •Changes span features that could be atomic or separate
- •It's unclear whether changes are one logical unit or multiple
Example prompt:
I see changes to the auth module and the API routes. Should I:
- •Commit them separately (auth first, then routes)?
- •Commit them together as a single feature?
- •Different order?