Built byPhoenix

© 2026 Phoenix

← Blog
GitVersion ControlBest PracticesConventional CommitsDevelopment

Complete Git Commit Message Guide

Phoenix·November 8, 2025·10 min read

Complete Git Commit Message Guide

Writing good commit messages is an essential skill for any developer. This comprehensive guide will teach you everything you need to know about crafting professional, standardized commit messages following the specification.

Commit Types

TypeCategoryDescription
featFeaturesA new feature for the user
fixBug FixesA bug fix for the user
docsDocumentationDocumentation only changes
styleStylesChanges that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
refactorCode RefactoringA code change that neither fixes a bug nor adds a feature
perfPerformance ImprovementsA code change that improves performance
testTestsAdding missing tests or correcting existing tests
buildBuildsChanges that affect the build system or external dependencies (example scopes: gulp, broccoli, yarn, webpack, npm)
ciContinuous IntegrationsChanges to CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs, Jenkins)
choreChoresOther changes that don't modify source or test files (maintenance tasks)
revertRevertsReverts a previous commit
securitySecuritySecurity improvements or vulnerability fixes
i18nInternationalizationChanges related to internationalization and localization
a11yAccessibilityAccessibility improvements
depsDependenciesDependency updates (alternative to build)
configConfigurationConfiguration file changes
wipWork in ProgressWork in progress (should be avoided in main branches)

Commit Message Structure

Basic Format

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

Components Explained

1. Type (Required)

  • Choose from the types listed above
  • Always lowercase
  • Example: feat, fix, docs

2. Scope (Optional)

  • Specifies the part of codebase affected
  • Use parentheses
  • Examples: (auth), (api), (ui), (parser)

3. Subject (Required)

  • Brief summary of the change
  • Use imperative mood ("add" not "added" or "adds")
  • Don't capitalize first letter
  • No period at the end
  • Maximum 50-72 characters

4. Body (Optional)

  • Detailed explanation of the change
  • Use imperative mood
  • Explain what and why, not how
  • Wrap at 72 characters
  • Separate from subject with blank line

5. Footer (Optional)

  • Breaking changes: BREAKING CHANGE: <description>
  • Issue references: Closes #123, Fixes #456, Relates to #789
  • Co-authors: Co-authored-by: Name <email>

Writing Rules

✅ DO:

  • Use imperative mood: "add feature" not "added feature"
  • Keep subject line under 50 characters (hard limit 72)
  • Start subject with lowercase
  • Separate subject from body with blank line
  • Wrap body at 72 characters
  • Use body to explain what and why vs. how
  • Reference issues and pull requests in footer
  • Use present tense

❌ DON'T:

  • Don't end subject line with period
  • Don't use past tense
  • Don't include unnecessary details
  • Don't be vague ("fixed stuff", "updated code")
  • Don't combine multiple unrelated changes

Examples

Simple Commit

feat(auth): add password reset functionality

Commit with Body

fix(api): resolve null pointer exception in user serviceThe user service was throwing null pointer exceptions whenattempting to process requests with missing authenticationtokens. Added validation to check for token presence beforeprocessing.Fixes #342

Breaking Change

feat(api): change authentication endpoint structureRestructured the authentication endpoints to follow RESTfulconventions. The /login endpoint is now /auth/login andrequires different request parameters.BREAKING CHANGE: Authentication endpoint moved from /login to/auth/login. Request body now requires 'credentials' objectinstead of flat username/password fields.Closes #156

Multiple Issues

fix(ui): correct button alignment on mobile devicesThe submit button was overflowing on screens smaller than375px width. Adjusted flex properties and added responsivebreakpoints.Fixes #234, #567Relates to #890

With Scope Examples

feat(dashboard): add user activity chartfix(payment): handle declined card transactionsdocs(readme): update installation instructionsstyle(header): format navigation componentrefactor(utils): simplify date formatting logicperf(images): implement lazy loadingtest(auth): add unit tests for login flowbuild(webpack): upgrade to version 5ci(github): add automated deployment workflowchore(deps): update dependencies to latest versions

Best Practices

  1. Atomic Commits: Each commit should represent one logical change
  2. Commit Often: Small, frequent commits are better than large ones
  3. Review Before Committing: Use git diff to review changes
  4. Meaningful Messages: Future you (and your team) will thank you
  5. Consistency: Follow your team's conventions
  6. Test First: Ensure code works before committing

Conventional Commits Specification

This guide follows the specification, which:

  • Provides a standardized format for commit messages
  • Enables automatic changelog generation
  • Simplifies semantic versioning
  • Makes it easier to understand project history

Quick Reference

Good Examples

feat: add email notificationsfix: prevent racing conditiondocs: update API documentationstyle: format code with prettierrefactor: extract validation logicperf: improve query performancetest: add integration tests

Bad Examples

❌ Fixed bug❌ Updated files❌ WIP❌ Minor changes❌ Stuff❌ Fixed #123 (missing type and description)

Tools & Automation

  • commitlint: Lint commit messages
  • husky: Git hooks for commit message validation
  • commitizen: Interactive commit message builder
  • standard-version: Automated versioning and changelog

Common Scenarios

Feature Development

bash
feat(user-profile): add avatar upload functionalityfeat(settings): implement dark mode togglefeat(dashboard): add analytics widget

Bug Fixes

bash
fix(login): resolve session timeout issuefix(api): handle null values in responsefix(ui): correct responsive layout on mobile

Documentation Updates

bash
docs(readme): add installation instructionsdocs(api): update endpoint documentationdocs(contributing): add code review guidelines

Dependency Management

bash
deps: upgrade react to v18.2.0deps(dev): update typescript to 5.0build(npm): update all dependencies

Configuration Changes

bash
config(eslint): add new linting rulesconfig(docker): optimize production buildci(github): add automated testing workflow

Multi-Line Commit Messages

For complex changes, use the full commit message format:

bash
git commit -m "feat(auth): implement two-factor authentication" -m "Added 2FA support using TOTP (Time-based One-Time Password).Users can now enable 2FA in their security settings.Features:- QR code generation for authenticator apps- Backup codes for account recovery- SMS fallback optionCloses #234Relates to #189"

Team Conventions

When working in a team, establish conventions for:

  1. Scope naming: Agree on component/module names
  2. Issue references: How to link commits to tickets
  3. Breaking changes: How to communicate API changes
  4. Review process: When to amend vs. create new commits

Advanced Patterns

Monorepo Commits

bash
feat(web): add new landing pagefeat(mobile): implement push notificationsfix(api): resolve CORS issues

Multiple Co-authors

bash
feat(payment): integrate stripe payment gatewayImplemented Stripe payment integration with support forcredit cards and ACH transfers.Co-authored-by: Alice Developer <alice@example.com>Co-authored-by: Bob Engineer <bob@example.com>

Reverting Commits

bash
revert: feat(api): add caching layerThis reverts commit a1b2c3d4e5f6.The caching implementation was causing data inconsistencyissues in production. Reverting while we investigate.

Troubleshooting Common Mistakes

Mistake 1: Vague Messages

❌ Bad: fix: bug fix ✅ Good: fix(auth): resolve token expiration issue

Mistake 2: Multiple Changes

❌ Bad: feat: add login, fix header, update docs ✅ Good: Create separate commits for each change

Mistake 3: Missing Context

❌ Bad: refactor: change code ✅ Good: refactor(utils): extract date formatting to utility function

Mistake 4: Wrong Tense

❌ Bad: feat: added new feature ✅ Good: feat: add new feature

Integrating with Your Workflow

Pre-commit Hooks

bash
# .husky/commit-msg#!/bin/shnpx --no -- commitlint --edit $1

Commitlint Configuration

javascript
// commitlint.config.jsmodule.exports = {  extends: ['@commitlint/config-conventional'],  rules: {    'type-enum': [2, 'always', [      'feat', 'fix', 'docs', 'style', 'refactor',      'perf', 'test', 'build', 'ci', 'chore', 'revert'    ]],    'subject-case': [2, 'never', ['upper-case']],    'subject-full-stop': [2, 'never', '.'],  }};

Commitizen Setup

bash
# Install commitizennpm install -g commitizen cz-conventional-changelog# Initialize in your projectcommitizen init cz-conventional-changelog --save-dev --save-exact# Use itgit cz

Changelog Generation

Well-formatted commits enable automated changelog generation:

bash
# Using standard-versionnpm install --save-dev standard-version# Generate changelognpx standard-version

This creates a CHANGELOG.md with all your changes organized by type!

Conclusion

Good commit messages are a love letter to your future self and your team. They:

  • Make code review easier
  • Enable automated tooling
  • Improve project documentation
  • Facilitate debugging and maintenance
  • Support better collaboration

By following this guide and the specification, you'll write commit messages that are clear, consistent, and valuable for the entire development lifecycle.


References:

Tools:

Remember: Consistency is key. Choose a convention and stick to it!

← All postsShare on X
<type>(<scope>): <subject><body><footer>
feat(auth): add password reset functionality
fix(api): resolve null pointer exception in user serviceThe user service was throwing null pointer exceptions whenattempting to process requests with missing authenticationtokens. Added validation to check for token presence beforeprocessing.Fixes #342
feat(api): change authentication endpoint structureRestructured the authentication endpoints to follow RESTfulconventions. The /login endpoint is now /auth/login andrequires different request parameters.BREAKING CHANGE: Authentication endpoint moved from /login to/auth/login. Request body now requires 'credentials' objectinstead of flat username/password fields.Closes #156
fix(ui): correct button alignment on mobile devicesThe submit button was overflowing on screens smaller than375px width. Adjusted flex properties and added responsivebreakpoints.Fixes #234, #567Relates to #890
feat(dashboard): add user activity chartfix(payment): handle declined card transactionsdocs(readme): update installation instructionsstyle(header): format navigation componentrefactor(utils): simplify date formatting logicperf(images): implement lazy loadingtest(auth): add unit tests for login flowbuild(webpack): upgrade to version 5ci(github): add automated deployment workflowchore(deps): update dependencies to latest versions
feat: add email notificationsfix: prevent racing conditiondocs: update API documentationstyle: format code with prettierrefactor: extract validation logicperf: improve query performancetest: add integration tests
❌ Fixed bug❌ Updated files❌ WIP❌ Minor changes❌ Stuff❌ Fixed #123 (missing type and description)
feat(user-profile): add avatar upload functionalityfeat(settings): implement dark mode togglefeat(dashboard): add analytics widget
fix(login): resolve session timeout issuefix(api): handle null values in responsefix(ui): correct responsive layout on mobile
docs(readme): add installation instructionsdocs(api): update endpoint documentationdocs(contributing): add code review guidelines
deps: upgrade react to v18.2.0deps(dev): update typescript to 5.0build(npm): update all dependencies
config(eslint): add new linting rulesconfig(docker): optimize production buildci(github): add automated testing workflow
git commit -m "feat(auth): implement two-factor authentication" -m "Added 2FA support using TOTP (Time-based One-Time Password).Users can now enable 2FA in their security settings.Features:- QR code generation for authenticator apps- Backup codes for account recovery- SMS fallback optionCloses #234Relates to #189"
feat(web): add new landing pagefeat(mobile): implement push notificationsfix(api): resolve CORS issues
feat(payment): integrate stripe payment gatewayImplemented Stripe payment integration with support forcredit cards and ACH transfers.Co-authored-by: Alice Developer <alice@example.com>Co-authored-by: Bob Engineer <bob@example.com>
revert: feat(api): add caching layerThis reverts commit a1b2c3d4e5f6.The caching implementation was causing data inconsistencyissues in production. Reverting while we investigate.
# .husky/commit-msg#!/bin/shnpx --no -- commitlint --edit $1
// commitlint.config.jsmodule.exports = {  extends: ['@commitlint/config-conventional'],  rules: {    'type-enum': [2, 'always', [      'feat', 'fix', 'docs', 'style', 'refactor',      'perf', 'test', 'build', 'ci', 'chore', 'revert'    ]],    'subject-case': [2, 'never', ['upper-case']],    'subject-full-stop': [2, 'never', '.'],  }};
# Install commitizennpm install -g commitizen cz-conventional-changelog# Initialize in your projectcommitizen init cz-conventional-changelog --save-dev --save-exact# Use itgit cz
# Using standard-versionnpm install --save-dev standard-version# Generate changelognpx standard-version