Meaningful Commit Messages for Agent Work
The commit message problem
Agent-generated code needs human-quality commit messages. These messages become permanent history searchable for years, referenced during debugging and code review long after the original author has forgotten why they made the change. A poorly worded message survives even after the code it describes has been refactored away.
Agents can generate commit messages. Claude Code, Codex, GitKraken, and GitHub Copilot all offer this capability, with varying quality. Left unconfigured, AI-generated messages drift toward the verbose, the vague, or the inconsistent. They describe implementation details rather than intent, or summarize what changed without explaining why anyone should care.
Configure tools to follow project conventions and review messages before they become permanent.
How agents generate commit messages
Each tool approaches message generation differently.
Claude Code analyzes staged changes and recent commit history when generating messages.
The /commit command examines the diff, looks at previous commits in the repository, and drafts a message attempting to match the project's existing style.
By default, it adds attribution: a Co-Authored-By: Claude <noreply@anthropic.com> trailer and a "Generated with Claude Code" line.
The behavior is customizable through a .claude/commands/commit.md file:
Generate commit messages following these rules:
- Use conventional commit format (type: description)
- Keep subject line under 50 characters
- Use imperative mood ("Add feature" not "Added feature")
- Do not include AI attribution in commit messagesCodex lacks a dedicated commit command. It commits work within its sandboxed environment when tasks complete, then surfaces the changes for review. Developers typically write commit messages themselves or create custom skills for message generation via the skill-creator to enforce specific formats.
GitKraken offers AI commit message generation through its Commit Composer. Staging changes and clicking the AI button analyzes the diff and suggests a summary. GitKraken uses Gemini by default, but OpenAI, Claude, Azure, Mistral, Ollama, and custom endpoints are all configurable.
GitKraken doesn't enforce Conventional Commits natively. Specify it through custom prompts in GitLens settings:
"gitlens.experimental.generateCommitMessagePrompt": "Generate a commit message using the Conventional Commits format."GitHub Copilot generates commit messages when prompted in the Source Control panel.
Customization happens through settings.json:
{
"github.copilot.chat.commitMessageGeneration.instructions": [
{ "text": "Use conventional commit format: type(scope): description" },
{ "text": "Keep subject line under 50 characters" },
{ "text": "Use imperative mood" }
]
}A .copilot-commit-message-instructions.md file in the project root provides team-wide configuration.
The Conventional Commits format
Conventional Commits provides a structured format that humans and tools can parse consistently.
The specification:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]Required types: feat for new features (maps to MINOR in semantic versioning) and fix for bug fixes (maps to PATCH).
Extended types from the Angular convention: build, chore, ci, docs, style, refactor, perf, test.
Breaking changes are indicated by appending ! after the type/scope or by adding a BREAKING CHANGE: footer.
Either notation maps to a MAJOR version bump.
Examples:
feat: add user authentication endpoint
fix(ui): correct button alignment on dashboard
docs(readme): update installation instructions
feat!: change API response format for user endpoints
BREAKING CHANGE: user endpoint now returns nested address objectAn ICSE 2025 analysis found approximately 94.5% of 381 popular NPM projects contained commits conforming to the Conventional Commits standard.
Tools like commitlint can enforce it in pre-commit hooks.
For agent-generated messages, specifying Conventional Commits in tool configuration produces consistent, parseable history. Automated changelog generation, semantic versioning, and CI/CD workflows all benefit.
The 50/72 rule
The 50/72 rule originated with the Linux kernel team and was codified by Tim Pope in 2008.
50 characters for the subject line. This forces conciseness. Analysis of Linux kernel commits revealed 50 characters as the most common subject length. GitHub truncates subjects beyond 72 characters, and many git interfaces display only the first line, so staying under 50 ensures readability everywhere.
72 characters for body line wrapping.
The industry standard for readable line length is 80 characters.
Git adds 4 characters of padding on the left and reserves 4 on the right, leaving 72 that fits the standard while preventing awkward line breaks.
This also accommodates email formatting when commits are converted via git format-patch.
The seven rules of effective commit messages:
- Separate subject from body with a blank line
- Limit the subject line to 50 characters
- Capitalize the subject line
- Don't end the subject line with a period
- Use imperative mood ("Fix bug" not "Fixed bug")
- Wrap the body at 72 characters
- Use the body to explain what and why, not how
The imperative mood test: a properly formed subject should complete the sentence "If applied, this commit will ___."
AI-generated messages violate these rules regularly. Past tense ("Added feature"), excessive length ("This commit adds the user authentication feature with support for OAuth2 and JWT tokens"), missing blank lines between subject and body. Configure the tool to follow these rules and review before accepting.
Documenting agent involvement
Whether to document agent involvement in commit messages is a policy decision, not a technical requirement.
Arguments for attribution:
- Transparency builds trust with reviewers and auditors
- Future debugging benefits from knowing the code's origin
- Regulatory requirements in some industries expect traceability
- GitHub displays co-authors in commit history, making collaboration visible
Arguments against attribution:
- Many organizations have strict commit message conventions that don't accommodate extra trailers
- Attribution text can conflict with tooling that parses commit messages
- The agent is a tool, not a collaborator attributing a commit to Claude is like attributing it to your IDE
- Creates noise in history for compliance environments that must document human review anyway
Claude Code adds attribution by default. Disable it through settings:
{
"includeCoAuthoredBy": false,
"gitAttribution": false
}The includeCoAuthoredBy setting controls the co-author trailer.
The gitAttribution setting disables all attribution including the "Generated with Claude Code" line.
For enterprises requiring audit trails, consider a tiered approach:
# For human-supervised, agent-generated code:
Assisted-by: Claude Code
# For substantial agent contribution with human review:
Co-authored-by: Claude <noreply@anthropic.com>
# For mostly-generated code (rare in practice):
Generated-by: Claude Code
Reviewed-by: developer@company.comWhatever convention the team adopts, consistency matters more than the specific format. Document the policy, configure tools to follow it, enforce through review.
Reviewing before pushing
AI-generated commit messages require the same scrutiny as AI-generated code. Accepting a message without reading it creates permanent history no one verified.
The review checklist:
Does the message describe intent, not just mechanics? "Add authentication" tells a story. "Add auth.ts file with AuthService class and login method" describes implementation details that belong in the diff.
Is the scope accurate? Agents sometimes describe what they attempted rather than what they accomplished. A message claiming "Add comprehensive test coverage" when the commit adds three tests misrepresents the change.
Does it match reality? Agent messages can reflect the conversation context rather than actual changes. If the discussion mentioned five features but only three were implemented, the message shouldn't imply all five are present.
Is it appropriately sized? Agent-generated messages sometimes include excessive bullet points or implementation details. A focused subject line with minimal body text usually serves better than paragraphs of explanation.
Build explicit message review into the workflow. Read the generated message, edit it, then commit. The extra 30 seconds prevents permanent history pollution.
Configuring tools for project conventions
Project-level configuration ensures all team members generate consistent messages.
For Claude Code, the CLAUDE.md file can specify commit conventions:
## Git commit guidelines
- Follow Conventional Commits format
- Keep subject line under 50 characters
- Use imperative mood
- Reference issue numbers with # prefix
- Do not include AI attributionThe .claude/commands/commit.md file can define a custom commit command enforcing these rules.
For GitHub Copilot, add configuration to .vscode/settings.json and commit it:
{
"github.copilot.chat.commitMessageGeneration.instructions": [
{ "text": "Use conventional commit format" },
{ "text": "Reference issue numbers when applicable" },
{ "text": "Keep subject under 50 characters" }
]
}Or create .copilot-commit-message-instructions.md in the project root with the conventions documented.
For enforcement, add commitlint:
npm install --save-dev @commitlint/cli @commitlint/config-conventionalCreate commitlint.config.js:
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'header-max-length': [2, 'always', 72],
'subject-case': [2, 'always', 'sentence-case'],
'body-max-line-length': [2, 'always', 72]
}
};Integrate with Husky for pre-commit hooks:
npx husky install
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'This setup rejects commits with non-conforming messages.
The payoff is a repository where every commit message tells a clear story about what changed and why whether configuration, enforcement, or review discipline got it there.