Skip to content

๐Ÿ–Š Commit Message Format

Mitup uses a custom commit message formatter that automatically transforms your commit messages into a consistent, emoji-based format. This makes the commit history more readable and visually informative.

How It Works

When you commit, the pre-commit hook automatically:

  • Recognizes your commit type (case-insensitive: feat, Feat, or FEAT all work)
  • Replaces the type prefix with an emoji from the configuration
  • Capitalizes the first letter of your description
  • Preserves scopes and breaking change indicators

Example Transformations

Here's what happens to your commits:

feat: add user authentication        โ†’ โœจ Add user authentication
fix(api): correct validation         โ†’ ๐Ÿ›(api) Correct validation
docs: update installation guide      โ†’ ๐Ÿ“š Update installation guide
refactor(handlers)!: change callback โ†’ ๐Ÿงน(handlers)! Change callback

๐Ÿ“ Writing Commit Messages

Basic Format

Write your commits using the conventional commits format:

Type[(scope)][!]: description

[optional body]

[optional footer(s)]

Rules

Type (required):

  • Case-insensitive (use feat, Feat, or FEAT - all work!)
  • Will be replaced with the corresponding emoji
  • Must be one of the allowed types

Scope (optional):

  • Enclosed in parentheses: (api), (handlers), (cli)
  • Should be lowercase
  • Can contain alphanumerics, hyphens, underscores, slashes, commas, and spaces

Breaking Change Indicator (optional):

  • Add ! after type or scope to indicate breaking changes
  • Example: feat!: or feat(api)!:

Description (required):

  • Separated from type/scope with a colon and space: :
  • Can be lowercase (will be auto-capitalized) or uppercase
  • Describe what the commit does in imperative mood

Body (optional):

  • Separated from subject by a blank line
  • Can be multiple paragraphs
  • Provide additional context about the changes

Footer (optional):

  • Separated from body by a blank line
  • Common footers: BREAKING CHANGE:, Closes #123, Co-authored-by:

Valid Examples

All these formats are valid:

โœ… feat: add user authentication
โœ… Feat: add user authentication
โœ… FEAT: add user authentication
โœ… fix(api): correct endpoint validation
โœ… docs(readme): update installation guide
โœ… refactor(handlers)!: change callback structure
โœ… test: add unit tests for api module
โœ… chore: update dependencies

Invalid Examples

These will fail with helpful error messages:

โŒ feat:missing space              # Missing space after colon
โŒ feat (scope): description       # Space between type and scope
โŒ build: compile project          # 'build' is not an allowed type
โŒ not a valid message             # No type prefix

โœจ Allowed Commit Types

The allowed types are defined in commits_check_config.yaml:

Type Emoji Description
Feat โœจ Introduce new features
Fix ๐Ÿ› Fix a bug
Docs ๐Ÿ“š Add or update documentation
Style ๐Ÿ’Ž Improve code style without affecting functionality
Refactor ๐Ÿงน Refactor code without changing functionality
Perf ๐Ÿš€ Improve performance
Test ๐Ÿงช Add or update tests
Infra ๐Ÿ—๏ธ Infrastructure changes
CI ๐Ÿ‘ท Continuous Integration changes
Chore โ™ป๏ธ Other changes that don't modify src or test files
Revert โช Revert changes
Merge ๐Ÿ”€ Merge branches
Update ๐Ÿš€ Update dependencies or other changes
Monitoring ๐Ÿ“ˆ Add or update monitoring
WIP ๐Ÿšง Work in progress
Translations ๐Ÿ—ฃ๏ธ Translations updates

๐Ÿ”ง Adding Custom Types

If you need a commit type that's not in the list, you can add it to commits_check_config.yaml:

additional_commit_types:
  YourType:
    description: Your custom type description.
    emoji: ๐ŸŽฏ

The formatter will automatically recognize and use your new type.

๐Ÿงช Testing Locally

Test Your Commit Message

Before committing, you can test how your message will be formatted:

Manual testing command
# Create a test commit message
echo "feat: add new feature" > /tmp/test_commit.txt

# Run the formatter
./bin/check_commit_message.py /tmp/test_commit.txt

# View the result
cat /tmp/test_commit.txt

Run the Test Suite

The repository includes a comprehensive test suite:

python bin/test_commit_checker.py

This runs 18 test cases covering various scenarios including:

  • Case-insensitive type matching
  • Scope handling
  • Breaking change indicators
  • Description capitalization
  • Invalid format detection

๐Ÿ“– Technical Details

Implementation

The commit message formatter is implemented in bin/check_commit_message.py and integrated with pre-commit hooks via .pre-commit-config.yaml.

How It's Different

Unlike traditional validators that only check format, this tool:

  • Transforms your messages instead of rejecting them
  • Accepts any case for commit types
  • Automatically capitalizes descriptions
  • Uses emojis for visual clarity in git history

Customizing Validation

If you need to modify the validation rules, edit bin/check_commit_message.py:

Key customization points * **Line 20-27**: Regex pattern for commit format * **Line 57-118**: Formatting logic * **Line 120-177**: Error message formatting For example, to change how descriptions are capitalized, modify the logic around line 95-97.

โ“ Troubleshooting

Hook Not Running

If the formatter isn't running automatically:

# Reinstall the commit-msg hook
pre-commit install --hook-type commit-msg

Import Errors

The formatter requires PyYAML. If you get import errors:

# Install PyYAML in your environment
pip install pyyaml

Or if using hatch:

hatch run dev:pip install pyyaml

Commit Rejected

If your commit is rejected:

  1. Read the error message - it explains what's wrong and shows examples
  2. Check that your type is in the allowed types list
  3. Ensure you have : (colon + space) after the type/scope
  4. If you need a new type, add it to commits_check_config.yaml

The commit message formatter helps maintain a clean, consistent git history that's easy to read and understand at a glance.