Writing Good Commit Messages
A well-written commit message helps keep a project’s history clean, improves collaboration, and makes debugging easier. This guide covers best practices, structure, and examples of good commit messages.
Why Good Commit Messages Matter
- Clarity: Clearly explain what changed and why.
- Traceability: Helps track when and why a change was made.
- Collaboration: Makes it easier for others to understand the project’s history.
- Automation: Useful for generating changelogs and release notes.
Best Practices for Writing Commit Messages
1. Keep the Subject Line Concise
- Use imperative mood (e.g., "Fix bug" instead of "Fixed bug").
- Keep it under 50 characters.
- Capitalize the first word and avoid a period at the end.
✅ Good:
Add user authentication feature
❌ Bad:
Added user authentication feature.
2. Provide More Context in the Body
- Separate the subject from the body with a blank line.
- Wrap text at 72 characters per line for readability.
- Explain why the change was made, not just what was changed.
✅ Good Example:
Fix issue with login validation
The previous implementation allowed empty passwords due to a missing check.
This update ensures that an error is thrown when the password is blank.
3. Use Consistent Formatting
Recommended Commit Message Format:
<type>(<scope>): <subject>
<body>
<footer>
<type>
:feat
,fix
,chore
,docs
,refactor
,test
, etc.<scope>
(optional): Affected part of the project (ui
,api
, etc.).<subject>
: A short summary of the change.<body>
(optional): Explanation of what and why.<footer>
(optional): References to issues (Fixes #123
).
✅ Example with Conventional Commits:
feat(ui): improve button styling
Updated primary button colors and padding to align with the new design.
Fixes #42.
Examples of Good Commit Messages
✅ Adding a new feature:
feat(api): add user profile endpoint
Implemented a new `/profile` endpoint that returns user details.
Includes pagination support.
✅ Fixing a bug:
fix(auth): resolve token expiration issue
Refactored token validation logic to correctly handle expiration checks.
Previously, expired tokens were not invalidated immediately.
✅ Improving performance:
perf(database): optimize query for fetching user data
Reduced query execution time by adding an index on `email`.
Speeds up login response time by ~30%.
✅ Updating documentation:
docs(readme): add installation guide
Included setup instructions for new contributors.
Clarified the required dependencies.
✅ Refactoring code:
refactor(router): simplify route middleware logic
Removed redundant checks and refactored route guards for better efficiency.
No functionality changes, just cleaner code.
✅ Writing tests:
test(payment): add unit tests for transaction validation
Added test cases for payment validation edge cases.
Ensures correct behavior for invalid card numbers and expiration dates.
✅ Adding CI/CD automation:
ci(github-actions): add build and test workflow
Configured GitHub Actions to run tests automatically on every push.
Includes caching to improve build times.
✅ Handling dependencies:
chore(deps): update lodash to v4.17.21
Updated lodash to the latest version to address security vulnerabilities.
No breaking changes detected.
✅ Fixing a typo:
docs(contributing): fix typo in contribution guidelines
Corrected a minor spelling mistake in the README file.
Summary
✔ Use the imperative mood ✔ Keep the subject line under 50 characters ✔ Separate the subject from the body with a blank line ✔ Wrap body text at 72 characters per line ✔ Provide context for changes ✔ Use consistent commit message formatting
Following these best practices will help keep your project's history clean, readable, and maintainable. 🚀