📝 Git & GitHub

How to Write Good Commit Messages ✍️

0
Author
04e5cc8b-58ac-4bdc-bdee-661bbb
📅
Published
06.05.2026
⏱️
Reading time
4 min
👁️
Views
49
🌱
Level
Beginner

A commit message is the signature on your code snapshot! It determines how readable the project history will be.

The Good Message Formula

<type>: <short description>

[optional longer description]

[optional footer]

Types:
- feat — new feature
- fix — bug fix
- docs — documentation
- refactor — refactoring without behavior change
- test — tests
- chore — routine tasks
- style — code formatting

Message Examples

Examples of Great Messages

feat: add user authentication
fix: resolve crash on empty input
docs: update API documentation
refactor: simplify database queries
test: add unit tests for login
chore: update dependencies

Examples of Bad Messages

update
fix
done
asdf
commit
stuff

Why they’re bad: A month from now YOU won’t remember what you did!

Writing Rules

1. First line — short description (50 characters)

# ✅ Good
feat: add two-factor authentication

# ❌ Bad (too long)
feat: add super amazing two-factor authentication with SMS and email support and a bunch of other stuff

2. Use the imperative mood

# ✅ Correct
fix: resolve memory leak in cache
feat: add export to PDF
docs: update installation guide

# ❌ Wrong
fix: resolved memory leak
feat: added export to PDF
docs: updated installation guide

Why: The commit makes a change, it doesn’t describe what you did.

3. Separate the subject from the body with a blank line

git commit -m "feat: add payment processing

Integrate Stripe API for payments.
Support credit cards and bank transfers. Support refunds and webhooks.
"

4. Explain “why”, not “what”

Bad (describes WHAT):

fix: change timeout from 30 to 60

Good (explains WHY):

fix: increase API timeout to prevent failures

30 seconds was too short for slow connections.
Users in remote areas experienced timeouts.
Increased to 60s based on metrics.

Commit Message Template

<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>

Example:

fix(auth): prevent duplicate user registration

Modified the registration endpoint to check for existing email
before creating a new user. Added unique constraint on email field
in database schema.

Fixes #453

When to Use a Detailed Description?

Short message is enough:

docs: fix typo in README
style: format code with prettier
chore: update package.json

Detailed description is needed:

refactor: redesign authentication flow

Old flow had security vulnerabilities:
- Session tokens stored in localStorage
- No CSRF protection
- Weak password requirements

New implementation:
- HttpOnly cookies for tokens
- CSRF tokens on all forms
- Enforced password complexity
- Rate limiting on login attempts

Breaking change: Need to clear browser data after update.

BREAKING CHANGE: Auth API changed from v1 to v2

Examples by Type

feat (new feature)

feat: add dark mode theme
feat: implement real-time notifications
feat(api): add GraphQL support

fix (bug fix)

fix: resolve crash on iOS Safari
fix: prevent XSS in user input
fix(payment): handle declined cards properly

docs (documentation)

docs: add deployment guide
docs: update API examples
docs(readme): add badges and shields

refactor

refactor: extract validation to separate module
refactor: use async/await instead of callbacks
refactor(db): optimize query performance

test

test: add unit tests for auth service
test: increase code coverage to 80%
test(api): add integration tests

chore

chore: update dependencies
chore: configure CI/CD pipeline
chore(git): add .gitignore rules

Linking to Issues and Tasks

# Reference an issue
fix: resolve login timeout issue

Fixes #123

# Breaking change
feat!: redesign API authentication

BREAKING CHANGE: API v1 deprecated, use v2 endpoints

GitHub automatically:
- Links the commit to the issue
- Closes the issue on merge (Fixes #123)
- Shows the link in the UI

Conventional Commits with Emoji (optional)

Some teams use emoji:

✨ feat: add new feature
🐛 fix: bug fix
📝 docs: documentation
♻️ refactor: code refactoring
✅ test: testing
🔧 chore: configuration
💄 style: styling

Example:

git commit -m "✨ feat: add user profile page"

Linting Tools and Checklist

Commitlint — automatic validation:

npm install --save-dev @commitlint/cli @commitlint/config-conventional

Husky — pre-commit check:

npx husky add .husky/commit-msg 'npx commitlint --edit $1'

Commit Message Checklist

  • [ ] Starts with a type (feat, fix, docs, etc.)
  • [ ] First line < 50 characters
  • [ ] Imperative mood (“add” not “added”)
  • [ ] Clear about what changed
  • [ ] Detailed description added if complex
  • [ ] Reference to issue/task if applicable
  • [ ] No typos

Examples of Great Commit Histories

Django project:

feat: add user authentication system
feat: create registration form
feat: implement email verification
fix: resolve CSRF token mismatch
test: add auth tests
docs: update README with auth setup
refactor: extract email sender to service
chore: add Django extensions

Conclusion

Good commit messages are a mark of a professional!

Employers look at your GitHub. Write messages as if your boss will read them! 💼

Remember:
1. Type + short description
2. Imperative mood
3. Explain “why”
4. Reference issues

Start right now — make your next commit the right way! ✍️

Your reaction to the article

💬 Comments (0)

🔐 Sign in to leave a comment
🚪 Login
💭

No comments yet

Be the first to share your opinion about this article!

🔗 Similar

Similar articles

Continue learning with these materials

📝

Git Hosting Platforms: Full Comparison 🏆

GitHub, GitLab, Bitbucket — which one to choose? A complete comparison with up-to-date data.

📅 06.05.2026 👁️ 52
📝

What Is a Git Commit and Why Do You Need It? 📸

A commit is a saved snapshot of your project at a specific point in time...

📅 06.05.2026 👁️ 56
📝

Why Git won over every other version control syst…

Today Git is the de facto standard for version control in software development. But it...

📅 06.05.2026 👁️ 51

Did you like the article?

Subscribe to our updates and receive new articles first. Grow with PyLand!