How to Write Git Commit Messages | Character Limits and Best Practices

Git commit messages are essential clues for understanding a codebase's change history. Well-written messages dramatically improve the efficiency of code reviews and bug investigations months later. Conversely, vague messages become technical debt that drags down the entire team's productivity. This article covers character count guidelines and practical best practices for commit messages. Use Character Counter to verify your message length.

Surprising Facts About Commit Messages

The "50-character subject, 72-character body wrap" convention traces back to the email era. Git creator Linus Torvalds carried over the practice of sending patches via email during Linux kernel development. Email clients typically displayed 80 columns, and accounting for quote markers and indentation, 72 characters was the optimal body width.

According to GitHub data, the average commit message length in open-source projects is estimated at 40–50 characters. However, message quality correlates with project health — projects with very short messages (under 10 characters) tend to have lower bug-fix efficiency.

Basic Structure and Character Count Guidelines

A Git commit message follows a two-part structure: a subject line and a body, separated by a blank line. This structure aligns with how git log --oneline and GitHub's commit list display only the subject.

ElementCharacter GuidelineReason
Subject line50 characters or lessDisplays without truncation in GitHub's list view
Subject (hard limit)72 characters or lessBeyond 72, GitHub adds an ellipsis (...)
Body line widthWrap at 72 charactersFits standard terminal width (80 cols) with indent margin
Body totalNo limitAdd detailed explanations as needed

Conventional Commits and Prefix Usage

Conventional Commits is a specification that gives commit messages a consistent structure. Adding a type prefix to the beginning of each message makes the nature of changes immediately identifiable and enables automated CHANGELOG generation and semantic versioning.

The basic format is <type>(<scope>): <description>. The scope is optional and indicates the module or component affected.

PrefixPurposeExample
featNew featurefeat(auth): add OAuth2 login support
fixBug fixfix(api): resolve null pointer in user endpoint
docsDocumentation changedocs: update API reference for v2
styleCode style (no behavior change)style: fix indentation in config file
refactorRefactoringrefactor(db): simplify query builder logic
testAdding or fixing teststest: add unit tests for payment module
choreBuild or tooling changeschore: upgrade webpack to v5
perfPerformance improvementperf(search): add index for full-text query
ciCI/CD configurationci: add GitHub Actions workflow

Good vs. Bad Commit Messages

Bad ExampleProblemGood Example
fix bugWhich bug?fix(cart): prevent duplicate items on rapid click
updateWhat was updated?docs: add setup instructions for local dev
WIPWork-in-progress left in historyfeat(ui): add skeleton loader for product list
asdfghMeaningless stringrefactor: extract validation logic into helper
Fixed the thing that was broken...Verbose, exceeds 50 charsfix(auth): restore session after token refresh

Team Commit Message Conventions

While personal projects allow flexibility, team development requires unified rules. The following practices help maintain message quality across an organization:

Overly strict rules can slow development, so adopt them incrementally. Start with prefix standardization, then introduce commitlint once the team is comfortable.

Conclusion

The widely accepted convention for Git commit messages is a subject line of 50 characters or less with body text wrapped at 72 characters. Conventional Commits prefixes make change types instantly recognizable and support automated CHANGELOG generation. Good messages concisely convey "what" and "why," while bad messages are vague and lack information. Use Character Counter to check your commit message length.