Initial commit
This commit is contained in:
534
references/commit-message-guide.md
Normal file
534
references/commit-message-guide.md
Normal file
@@ -0,0 +1,534 @@
|
||||
# Commit Message Guide
|
||||
|
||||
A comprehensive guide to writing clear, consistent, and maintainable commit messages using the Conventional Commits format.
|
||||
|
||||
---
|
||||
|
||||
## Why Good Commit Messages Matter
|
||||
|
||||
- **Documentation**: Git history becomes a changelog
|
||||
- **Code Review**: Easier to understand what changed and why
|
||||
- **Debugging**: Quickly find when bugs were introduced
|
||||
- **Automation**: Enables automatic changelog generation and versioning
|
||||
- **Professionalism**: Shows attention to detail and respect for maintainers
|
||||
|
||||
---
|
||||
|
||||
## Conventional Commits Format
|
||||
|
||||
```
|
||||
<type>(<scope>): <subject>
|
||||
|
||||
[optional body]
|
||||
|
||||
[optional footer(s)]
|
||||
```
|
||||
|
||||
### Components
|
||||
|
||||
**Type** (required): Category of change
|
||||
**Scope** (optional): What section of codebase is affected
|
||||
**Subject** (required): Brief description of change
|
||||
**Body** (optional): Detailed explanation
|
||||
**Footer** (optional): Issue references, breaking changes
|
||||
|
||||
---
|
||||
|
||||
## Types
|
||||
|
||||
### Primary Types
|
||||
|
||||
**feat**: New feature for the user
|
||||
```
|
||||
feat(auth): add OAuth2 support for Google and GitHub
|
||||
```
|
||||
|
||||
**fix**: Bug fix for the user
|
||||
```
|
||||
fix(api): resolve memory leak in worker shutdown
|
||||
```
|
||||
|
||||
**docs**: Documentation changes only
|
||||
```
|
||||
docs(readme): update installation instructions for v2.0
|
||||
```
|
||||
|
||||
**style**: Code style changes (formatting, missing semicolons, etc.)
|
||||
```
|
||||
style(components): format code with Prettier
|
||||
```
|
||||
|
||||
**refactor**: Code change that neither fixes bug nor adds feature
|
||||
```
|
||||
refactor(auth): extract middleware to separate module
|
||||
```
|
||||
|
||||
**perf**: Performance improvement
|
||||
```
|
||||
perf(database): add index to user_id column
|
||||
```
|
||||
|
||||
**test**: Adding or updating tests
|
||||
```
|
||||
test(auth): add OAuth flow integration tests
|
||||
```
|
||||
|
||||
### Supporting Types
|
||||
|
||||
**build**: Changes to build system or dependencies
|
||||
```
|
||||
build(deps): upgrade React to v18.2.0
|
||||
```
|
||||
|
||||
**ci**: CI configuration changes
|
||||
```
|
||||
ci(github): add automated release workflow
|
||||
```
|
||||
|
||||
**chore**: Other changes that don't modify src or test files
|
||||
```
|
||||
chore(deps): update dev dependencies
|
||||
```
|
||||
|
||||
**revert**: Revert a previous commit
|
||||
```
|
||||
revert: feat(auth): add OAuth2 support
|
||||
|
||||
This reverts commit abc123def456.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Subject Line Rules
|
||||
|
||||
### The 7 Rules
|
||||
|
||||
1. **Limit to 50 characters** (hard limit: 72)
|
||||
2. **Use imperative mood** ("Add" not "Added" or "Adds")
|
||||
3. **Capitalize first word** after the colon
|
||||
4. **Don't end with punctuation**
|
||||
5. **Focus on WHAT changed** (body explains WHY)
|
||||
6. **Be specific** but concise
|
||||
7. **Start with type** (if using Conventional Commits)
|
||||
|
||||
### Examples
|
||||
|
||||
✅ **Good:**
|
||||
```
|
||||
feat(api): add user authentication endpoint
|
||||
fix(ui): resolve button alignment on mobile
|
||||
docs(contributing): clarify PR submission process
|
||||
refactor(utils): simplify date formatting logic
|
||||
```
|
||||
|
||||
❌ **Bad:**
|
||||
```
|
||||
Fixed stuff # Too vague
|
||||
Added new feature to the authentication system that allows users to login with OAuth # Too long
|
||||
updated code # Not specific, wrong tense
|
||||
feat(api): add user authentication. # Don't end with period
|
||||
Feat(api): add auth # Don't capitalize type
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Optional Scope
|
||||
|
||||
The scope provides context about what part of the codebase changed.
|
||||
|
||||
### Common Scopes
|
||||
|
||||
```
|
||||
feat(auth): ... # Authentication
|
||||
feat(api): ... # API layer
|
||||
feat(ui): ... # User interface
|
||||
feat(database): ... # Database
|
||||
feat(docs): ... # Documentation
|
||||
feat(tests): ... # Tests
|
||||
fix(deps): ... # Dependencies
|
||||
build(webpack): ... # Build tooling
|
||||
```
|
||||
|
||||
### Project-Specific Scopes
|
||||
|
||||
Check the project's recent commits for conventions:
|
||||
```bash
|
||||
git log --oneline -20
|
||||
```
|
||||
|
||||
### When to Omit Scope
|
||||
|
||||
Scope is optional. Omit when:
|
||||
- Change affects multiple areas
|
||||
- Project doesn't use scopes
|
||||
- Scope would be too generic
|
||||
|
||||
```
|
||||
feat: add dark mode support
|
||||
docs: update README
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Body (Optional)
|
||||
|
||||
The body provides detailed explanation of WHAT and WHY (code shows HOW).
|
||||
|
||||
### Rules
|
||||
|
||||
- Separate from subject with blank line
|
||||
- Wrap at 72 characters per line
|
||||
- Explain motivation and context
|
||||
- Contrast with previous behavior
|
||||
- Use bullet points for multiple points
|
||||
|
||||
### Example
|
||||
|
||||
```
|
||||
feat(api): add rate limiting to authentication endpoints
|
||||
|
||||
Users can now make up to 100 authentication attempts per hour
|
||||
per IP address. This prevents brute force attacks while allowing
|
||||
legitimate users to retry failed login attempts.
|
||||
|
||||
Implementation details:
|
||||
- Uses Redis for distributed rate limiting
|
||||
- Configurable via RATE_LIMIT_MAX environment variable
|
||||
- Returns 429 status with Retry-After header when exceeded
|
||||
- Resets hourly at top of the hour
|
||||
|
||||
Previous behavior allowed unlimited attempts, which was identified
|
||||
as a security vulnerability in audit #456.
|
||||
```
|
||||
|
||||
### When to Include Body
|
||||
|
||||
Include a body when:
|
||||
- Change is complex or non-obvious
|
||||
- Design decisions need explanation
|
||||
- Previous behavior needs context
|
||||
- Multiple related changes in one commit
|
||||
- Security or performance implications
|
||||
|
||||
### When to Skip Body
|
||||
|
||||
Skip the body when:
|
||||
- Change is self-explanatory
|
||||
- Subject line tells the complete story
|
||||
- Trivial changes (typos, formatting)
|
||||
|
||||
---
|
||||
|
||||
## Footer (Optional)
|
||||
|
||||
Footers provide metadata about the commit.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
Use `BREAKING CHANGE:` footer for breaking changes:
|
||||
|
||||
```
|
||||
feat(api)!: change authentication endpoint path
|
||||
|
||||
BREAKING CHANGE: The authentication endpoint has moved from
|
||||
/api/auth to /api/v2/auth. Update your API calls accordingly.
|
||||
|
||||
Migration guide available at docs/migration/v2.md
|
||||
```
|
||||
|
||||
Note the `!` after the type indicates a breaking change.
|
||||
|
||||
### Issue References
|
||||
|
||||
Link issues using keywords for automatic closing:
|
||||
|
||||
```
|
||||
fix(ui): resolve mobile layout issues
|
||||
|
||||
Fixes #123
|
||||
Closes #456, #789
|
||||
Relates to #234
|
||||
```
|
||||
|
||||
**Closing Keywords:**
|
||||
- `Closes #123`
|
||||
- `Fixes #123`
|
||||
- `Resolves #123`
|
||||
- Also: close, fix, resolve (case insensitive)
|
||||
|
||||
### Co-authored-by
|
||||
|
||||
Credit co-authors:
|
||||
|
||||
```
|
||||
feat(api): add GraphQL support
|
||||
|
||||
Co-authored-by: Jane Doe <jane@example.com>
|
||||
Co-authored-by: John Smith <john@example.com>
|
||||
```
|
||||
|
||||
### Other Footers
|
||||
|
||||
```
|
||||
Reviewed-by: Name <email>
|
||||
Signed-off-by: Name <email>
|
||||
Acked-by: Name <email>
|
||||
See-also: #123
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Complete Examples
|
||||
|
||||
### Example 1: Simple Feature
|
||||
|
||||
```
|
||||
feat(ui): add dark mode toggle
|
||||
|
||||
Adds a toggle button in settings to switch between light and dark
|
||||
themes. User preference is saved to localStorage and persists
|
||||
across sessions.
|
||||
|
||||
Closes #234
|
||||
```
|
||||
|
||||
### Example 2: Bug Fix
|
||||
|
||||
```
|
||||
fix(api): prevent race condition in cache invalidation
|
||||
|
||||
The cache invalidation logic wasn't thread-safe, causing occasional
|
||||
race conditions when multiple workers tried to invalidate the same
|
||||
key simultaneously.
|
||||
|
||||
Solution:
|
||||
- Added mutex locks around the critical section
|
||||
- Implemented timeout for lock acquisition (5s)
|
||||
- Added retry logic with exponential backoff
|
||||
- Updated tests to verify thread-safety
|
||||
|
||||
Fixes #456
|
||||
```
|
||||
|
||||
### Example 3: Breaking Change
|
||||
|
||||
```
|
||||
feat(api)!: migrate to TypeScript and update endpoint contracts
|
||||
|
||||
BREAKING CHANGE: All API endpoints now return ISO 8601 date
|
||||
strings instead of Unix timestamps. Update client code to parse
|
||||
dates accordingly.
|
||||
|
||||
Additionally, authentication now requires JWT tokens in the
|
||||
Authorization header instead of session cookies.
|
||||
|
||||
Migration guide: docs/migration/v3.md
|
||||
|
||||
Closes #567
|
||||
```
|
||||
|
||||
### Example 4: Refactoring
|
||||
|
||||
```
|
||||
refactor(auth): extract middleware to separate module
|
||||
|
||||
No functional changes, but auth logic is now easier to test and
|
||||
maintain. Consolidated duplicate code from 5 route handlers into
|
||||
reusable middleware functions.
|
||||
|
||||
Files affected:
|
||||
- New: middleware/authenticate.js
|
||||
- Updated: routes/*.js (5 files)
|
||||
- Tests: tests/middleware/auth.test.js
|
||||
|
||||
Relates to #301 (technical debt epic)
|
||||
```
|
||||
|
||||
### Example 5: Documentation
|
||||
|
||||
```
|
||||
docs(api): add examples for authentication flows
|
||||
|
||||
Added code examples for:
|
||||
- Basic authentication with username/password
|
||||
- OAuth2 flow with Google
|
||||
- API key authentication
|
||||
- JWT token refresh
|
||||
|
||||
Examples include curl commands and JavaScript fetch() snippets.
|
||||
|
||||
Closes #678
|
||||
```
|
||||
|
||||
### Example 6: Multiple Related Changes
|
||||
|
||||
```
|
||||
fix(auth): resolve multiple OAuth edge cases
|
||||
|
||||
- Handle expired refresh tokens gracefully
|
||||
- Prevent account linking when email doesn't match
|
||||
- Add rate limiting to token refresh endpoint
|
||||
- Log failed OAuth attempts for security monitoring
|
||||
|
||||
Each issue was related to OAuth implementation and fixing them
|
||||
separately would have caused merge conflicts.
|
||||
|
||||
Fixes #123, #456, #789
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tips for Writing Good Commit Messages
|
||||
|
||||
### Do:
|
||||
|
||||
✅ Write in imperative mood ("Add" not "Added")
|
||||
```
|
||||
feat: add user profile page
|
||||
```
|
||||
|
||||
✅ Be specific about what changed
|
||||
```
|
||||
fix(api): resolve timeout in user search endpoint
|
||||
```
|
||||
|
||||
✅ Explain WHY in the body
|
||||
```
|
||||
refactor(db): switch to connection pooling
|
||||
|
||||
The previous approach created a new connection for each request,
|
||||
which caused performance issues under load. Connection pooling
|
||||
reduces overhead and improves response times by 40%.
|
||||
```
|
||||
|
||||
✅ Use the body for complex changes
|
||||
✅ Reference issues and PRs
|
||||
✅ Follow project conventions
|
||||
|
||||
### Don't:
|
||||
|
||||
❌ Use past tense
|
||||
```
|
||||
feat: added user profile page ❌
|
||||
```
|
||||
|
||||
❌ Be vague
|
||||
```
|
||||
fix: bug fix ❌
|
||||
update: changes ❌
|
||||
```
|
||||
|
||||
❌ Write novels in the subject line
|
||||
```
|
||||
feat(api): add new user authentication endpoint with OAuth2 support for Google and GitHub that also includes rate limiting ❌
|
||||
```
|
||||
|
||||
❌ Skip the type (if project uses Conventional Commits)
|
||||
```
|
||||
Add user profile page ❌
|
||||
```
|
||||
|
||||
❌ Use abbreviations or jargon unnecessarily
|
||||
```
|
||||
fix(db): rm dup recs via opt idx ❌
|
||||
```
|
||||
|
||||
❌ Combine unrelated changes in one commit
|
||||
```
|
||||
feat: add dark mode, fix typo in README, update dependencies ❌
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Real-World Examples from Popular Projects
|
||||
|
||||
### React
|
||||
```
|
||||
feat(react-dom): Add support for CSS Layers
|
||||
|
||||
Implements support for @layer, enabling better CSS encapsulation.
|
||||
|
||||
Fixes #24556
|
||||
```
|
||||
|
||||
### Node.js
|
||||
```
|
||||
doc: add missing types to request and response
|
||||
|
||||
Added TypeScript type definitions for several Request and Response
|
||||
methods that were previously missing from the declarations.
|
||||
|
||||
Fixes: #12345
|
||||
Refs: #67890
|
||||
```
|
||||
|
||||
### Kubernetes
|
||||
```
|
||||
fix: prevent pod creation with invalid security context
|
||||
|
||||
Adds validation to reject pods with both `runAsUser: 0` and
|
||||
`allowPrivilegeEscalation: false`, which is an invalid combination.
|
||||
|
||||
Closes #12345
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Commit Message Checklist
|
||||
|
||||
Before committing, verify:
|
||||
|
||||
- [ ] Type is correct (feat, fix, docs, etc.)
|
||||
- [ ] Subject line under 50 characters (max 72)
|
||||
- [ ] Imperative mood ("Add" not "Added")
|
||||
- [ ] First word capitalized
|
||||
- [ ] No period at end
|
||||
- [ ] Body explains WHY (if needed)
|
||||
- [ ] Body wrapped at 72 characters
|
||||
- [ ] Blank line between subject and body
|
||||
- [ ] Issues referenced in footer
|
||||
- [ ] Breaking changes noted with BREAKING CHANGE:
|
||||
- [ ] Follows project conventions
|
||||
|
||||
---
|
||||
|
||||
## Tools & Automation
|
||||
|
||||
### Commitizen
|
||||
|
||||
Interactive tool for writing commits:
|
||||
```bash
|
||||
npm install -g commitizen
|
||||
git cz
|
||||
```
|
||||
|
||||
### Commitlint
|
||||
|
||||
Lint commit messages:
|
||||
```bash
|
||||
npm install --save-dev @commitlint/cli @commitlint/config-conventional
|
||||
```
|
||||
|
||||
### Husky
|
||||
|
||||
Git hooks to enforce commit message format:
|
||||
```bash
|
||||
npm install --save-dev husky
|
||||
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit ${1}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Resources
|
||||
|
||||
**Specifications:**
|
||||
- Conventional Commits: https://www.conventionalcommits.org/
|
||||
- Git Commit Guidelines: https://git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project
|
||||
|
||||
**Tools:**
|
||||
- Commitizen: https://github.com/commitizen/cz-cli
|
||||
- Commitlint: https://commitlint.js.org/
|
||||
|
||||
**Further Reading:**
|
||||
- "How to Write a Git Commit Message": https://chris.beams.io/posts/git-commit/
|
||||
- Angular Commit Guidelines: https://github.com/angular/angular/blob/main/CONTRIBUTING.md#commit
|
||||
Reference in New Issue
Block a user