Git Commit Message Best Practices: Write Messages That Matter
Learn how to write clear, meaningful git commit messages that improve collaboration, debugging, and automatic changelog generation. From conventional commits to practical examples, we'll cover everything you need to know.
Git Commit Message Best Practices: Write Messages That Matter
Your git commit messages are more than just notes to yourself—they're a communication tool for your team, future developers, and even automated systems like ShipLog that generate changelogs. A well-written commit message can save hours of debugging, make code reviews more effective, and ensure your changelogs are accurate and helpful.
Why Good Commit Messages Matter
Before diving into the how, let's understand the why:
- Team Collaboration: Clear messages help teammates understand what changed and why
- Debugging: When something breaks, good commit messages help identify the problematic change
- Code Reviews: Reviewers can focus on the code instead of trying to understand the intent
- Changelog Generation: Tools like ShipLog can automatically categorize and describe changes
- Project History: Future developers (including yourself) can understand the evolution of your codebase
The Conventional Commits Standard
The Conventional Commits specification provides a standardized format that makes commit messages machine-readable and human-friendly:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Commit Types
The most common types and when to use them:
feat
: A new feature for the userfix
: A bug fix for the userdocs
: Documentation only changesstyle
: Changes that don't affect the meaning of the code (formatting, missing semicolons, etc.)refactor
: A code change that neither fixes a bug nor adds a featureperf
: A code change that improves performancetest
: Adding missing tests or correcting existing testschore
: Changes to the build process or auxiliary tools
Examples of Good Conventional Commits
1feat: add dark mode toggle to user settings
2fix(auth): resolve login timeout issue on slow connections
3docs: update API documentation with new endpoints
4refactor(api): simplify user authentication logic
5perf: optimize database queries for user search
6test: add unit tests for user validation
7chore: update dependencies to latest versions
The 7 Rules of Great Commit Messages
1. Use the Imperative Mood
Write commit messages as if you're giving commands to the codebase:
1# ✅ Good - Imperative mood
2feat: add user authentication system
3fix: resolve memory leak in image processing
4
5# ❌ Bad - Past tense
6feat: added user authentication system
7fix: resolved memory leak in image processing
2. Keep the First Line Under 50 Characters
The first line should be concise and to the point:
1# ✅ Good - Clear and concise
2feat: implement OAuth 2.0 authentication
3
4# ❌ Bad - Too long and unclear
5feat: implement OAuth 2.0 authentication system with refresh tokens and proper error handling
3. Capitalize the First Letter
Start your description with a capital letter:
1# ✅ Good - Proper capitalization
2feat: Add user profile management
3
4# ❌ Bad - Lowercase start
5feat: add user profile management
4. Don't End with a Period
The first line should not end with punctuation:
1# ✅ Good - No period
2feat: add user profile management
3
4# ❌ Bad - Unnecessary period
5feat: add user profile management.
5. Use the Body to Explain What and Why
When you need more detail, use the commit body:
1feat: add user profile management
2
3- Implement profile creation and editing
4- Add avatar upload functionality
5- Include privacy settings for profile visibility
6- Support profile data export
7
8This change improves user experience by allowing users to
9customize their profiles and control their privacy settings.
6. Separate Subject from Body with a Blank Line
Always include a blank line between the subject and body:
1feat: add user profile management
2
3This commit implements a complete user profile system that
4allows users to manage their personal information, upload
5avatars, and control privacy settings.
7. Use the Footer for Breaking Changes and Issue References
1feat: change authentication API response format
2
3BREAKING CHANGE: The /auth/login endpoint now returns a JWT token
4instead of a session ID. Update your client code accordingly.
5
6Closes #123
7Fixes #456
Practical Examples by Category
Feature Development
1feat: add dark mode support
2
3- Implement theme toggle in user settings
4- Add CSS variables for color schemes
5- Include system preference detection
6- Support manual theme selection
7
8This improves accessibility and user experience by providing
9a dark theme option that reduces eye strain in low-light
10environments.
11
12Closes #234
Bug Fixes
1fix(auth): resolve login timeout after 30 minutes
2
3The previous implementation used a fixed timeout that didn't
4account for user activity. This change implements an adaptive
5timeout that extends the session when users are actively
6using the application.
7
8- Add activity tracking middleware
9- Implement adaptive timeout calculation
10- Update session management logic
11
12Fixes #567
Performance Improvements
1perf: optimize database queries for user search
2
3- Add database indexes on frequently searched fields
4- Implement query result caching
5- Use pagination for large result sets
6- Optimize JOIN operations
7
8This reduces search response time from 2.5s to 0.3s on
9average, significantly improving user experience.
10
11Performance improvement: 8.3x faster
Refactoring
1refactor(api): simplify user authentication logic
2
3- Extract authentication logic into separate service
4- Remove duplicate code across endpoints
5- Improve error handling consistency
6- Add better logging for debugging
7
8This refactoring makes the code more maintainable and
9easier to test, while preserving all existing functionality.
10
11No breaking changes
Advanced Techniques
Scoped Commits
Use scopes to group related changes:
1feat(auth): add two-factor authentication
2feat(ui): implement responsive navigation menu
3feat(api): add rate limiting for public endpoints
4fix(db): resolve connection pool exhaustion
Breaking Changes
Clearly mark breaking changes in the footer:
1feat: change user API response format
2
3BREAKING CHANGE: The user object structure has changed:
4- `fullName` is now `firstName` and `lastName`
5- `profileImage` is now `avatar`
6- `lastLogin` is now `lastActive`
7
8Migration guide: docs/migration/v2.0.md
9
10Closes #789
Issue References
Link commits to issues and pull requests:
1feat: add user notification preferences
2
3- Email notifications for security events
4- Push notifications for app updates
5- SMS for critical alerts
6- In-app notification center
7
8Closes #123
9Relates to #456
10Part of #789
What NOT to Do
Avoid These Common Mistakes
1# ❌ Too vague
2fix: fix stuff
3update: update things
4wip: work in progress
5
6# ❌ Too long without structure
7feat: implement a comprehensive user management system that includes user registration, authentication, profile management, role-based access control, and audit logging with proper error handling and validation
8
9# ❌ Inconsistent formatting
10feat:Add user management
11FIX: resolve bug
12docs:update readme
13
14# ❌ No context
15fix: it works now
16feat: new feature
17refactor: cleanup
How ShipLog Uses Your Commit Messages
When you use ShipLog, your commit messages become the foundation for automatic changelog generation. Here's how different commit types are processed:
Automatic Changelog Categorization
feat:
→ Added to "New Features" sectionfix:
→ Added to "Bug Fixes" sectionperf:
→ Added to "Performance Improvements" sectionrefactor:
→ Usually excluded (internal changes)chore:
→ Usually excluded (maintenance tasks)docs:
→ Added to "Documentation" section
Example: From Commit to Changelog
1# Your commit message
2feat: add dark mode toggle to user settings
3
4# ShipLog automatically generates
5## 🚀 New Features
6- **Dark Mode Toggle**: Added dark mode toggle to user settings
Setting Up Commit Message Templates
Git Commit Template
Create a .gitmessage
file in your project root:
1# .gitmessage
2<type>(<scope>): <subject>
3
4<body>
5
6<footer>
Set it as your default template:
1git config commit.template .gitmessage
Pre-commit Hooks
Use tools like commitlint
to enforce conventional commits:
1# Install commitlint
2npm install --save-dev @commitlint/cli @commitlint/config-conventional
3
4# Create commitlint.config.js
5module.exports = {
6 extends: ['@commitlint/config-conventional'],
7 rules: {
8 'subject-case': [2, 'never', 'sentence-case'],
9 'subject-empty': [2, 'never'],
10 'type-empty': [2, 'never']
11 }
12};
Tools and Extensions
VS Code Extensions
- Conventional Commits: Provides autocomplete for commit types
- GitLens: Enhanced git integration with commit history
- Git History: Visual commit history and diff viewer
Command Line Tools
commitizen
: Interactive commit message creationconventional-changelog
: Generate changelogs from conventional commitshusky
: Git hooks for pre-commit validation
Best Practices Summary
- Use conventional commits format for consistency
- Write clear, concise subject lines under 50 characters
- Use imperative mood (add, fix, update)
- Include detailed explanations in the body when needed
- Reference issues and breaking changes in the footer
- Be consistent across your team
- Think about the future - someone will read this later
- Consider automation - tools like ShipLog depend on good messages
Conclusion
Good commit messages are an investment in your project's future. They make your codebase more maintainable, your team more productive, and your changelogs more accurate. By following these best practices, you're not just writing better commit messages—you're building a better development workflow.
Remember: Every commit message is a small piece of documentation. Make each one count.
Ready to improve your commit messages and get better changelogs? Try ShipLog today and see how your well-written commits automatically generate beautiful, organized changelogs.