Issue 06 | /caveman-commit β€” Bringing Git Commit Messages Back to Basics

⏱ Est. reading time: 12 min Updated on 5/7/2026

🎯 Learning Objectives

After this issue, you will master:

  1. The output rules and format specifications of /caveman-commit
  2. The "Why over What" principle β€” why is more important than what
  3. How to use caveman-commit on five major platforms
  4. Automatic integration with Git Hook (prepare-commit-msg)

πŸ“– Core Content

6.1 Why Do Commit Messages Need Caveman?

Have you seen commit messages like this?

❌ Bad commit (real case):

"Updated the authentication middleware to properly validate token 
expiry by checking if the token's expiration timestamp is less than 
or equal to the current time instead of using a strict less-than 
comparison, which was causing tokens that expire at exactly the 
current second to not be properly caught and rejected"

This isn't a commit message; it's a thesis abstract.

Caveman Style:

βœ… fix(auth): token expiry use <= not <

13 characters. The same information. Perfectly displayed in git log --oneline.

6.2 Three Rules of caveman-commit

graph TD
    A["caveman-commit Rules"]
    
    A --> B["πŸ“ Length Constraint
Subject Line ≀ 50 characters"] A --> C["πŸ“‹ Format Specification
Conventional Commits"] A --> D["🧠 Content Principle
Why over What"] B --> B1["git log --oneline perfectly aligned
Not truncated"] C --> C1["type(scope): message
feat/fix/docs/chore/refactor"] D --> D1["Explain 'Why'
not 'What'"]

Rule 1: Conventional Commits Format

<type>(<scope>): <description>

type enumeration:
  feat     β†’ New feature
  fix      β†’ Bug fix
  docs     β†’ Documentation changes
  chore    β†’ Chores (dependency updates, config, etc.)
  refactor β†’ Refactoring (no behavior change)
  perf     β†’ Performance improvement
  test     β†’ Tests
  ci       β†’ CI/CD changes
  style    β†’ Code style (no logic impact)

Rule 2: Subject Line ≀ 50 characters

βœ… fix(auth): token expiry use <= not <       (38 chars)
βœ… feat(api): add rate limiting per user       (39 chars)
βœ… refactor(db): extract query builder         (40 chars)

❌ feat(api): add comprehensive rate limiting mechanism with sliding window (73 chars β†’ Truncated!)

Rule 3: Why over What

❌ What (describes what was done β€” already visible in code):
"change < to <= in token check"

βœ… Why (explains why it was done β€” not visible in code):
"fix(auth): token expiry use <= not <"
↑ Implies "because of boundary conditions, tokens were allowed to pass at the exact moment of expiry"

❌ What:
"add try-catch around database call"

βœ… Why:
"fix(db): handle connection timeout gracefully"

6.3 Usage

In Claude Code

# After completing code modifications
> /caveman-commit

# Claude will analyze your staged changes and generate:
# fix(auth): token expiry use <= not <
#
# Then you can:
> Commit with this message
# Or
> git commit -m "fix(auth): token expiry use <= not <"

In Antigravity

# Natural language trigger
> Help me write a commit message in caveman-commit style

# Or after configuring caveman rules in GEMINI.md:
> Analyze my changes and write a concise commit message

In Gemini CLI

> /caveman-commit
# Gemini will analyze the current diff and output a concise commit message

In Codex

> $caveman-commit
# Codex uses the $ prefix to trigger skills

In OpenCode

# Natural language trigger (no slash command)
> Write a commit message in caveman style, analyze current staged changes

6.4 Practical Before / After Comparison

Scenario ❌ Normal Claude βœ… Caveman Commit
Fix login Bug "Fixed a bug where users couldn't log in when their password contained special characters by properly escaping the input" fix(auth): escape special chars in password
Add dark mode "Added dark mode support to the application with a toggle button in the settings page and automatic detection of system preferences" feat(ui): dark mode + system pref detect
Refactor database layer "Refactored the database access layer to use the repository pattern instead of direct queries for better testability and maintainability" refactor(db): repository pattern for testability
Update dependencies "Updated React from version 18.2 to 19.0 and fixed breaking changes in the useEffect cleanup timing" chore(deps): react 19 + fix effect cleanup
Fix CSS layout "Fixed the mobile responsive layout issue where the sidebar was overlapping the main content area on screens smaller than 768px" fix(layout): sidebar overlap on mobile <768px

6.5 Automatic Integration with Git Hook

You can combine caveman-commit with Git's prepare-commit-msg Hook for automation:

#!/bin/bash
# .git/hooks/prepare-commit-msg

# Skip if it's a merge commit or amend
case "$2" in
    merge|squash) exit 0 ;;
esac

# Skip if commit message already has content (not a template)
if [ -s "$1" ] && [ "$(head -1 "$1")" != "" ]; then
    exit 0
fi

# Get diff of staged changes
DIFF=$(git diff --cached --stat)

# Use Claude Code to generate caveman-style commit message
# (requires claude CLI in PATH)
MSG=$(echo "Generate a caveman-commit message for this diff. Rules: Conventional Commits, ≀50 chars, why over what. Diff: $DIFF" | claude --print 2>/dev/null)

if [ -n "$MSG" ]; then
    echo "$MSG" > "$1"
fi
graph LR
    A["git commit"] --> B["prepare-commit-msg Hook"]
    B --> C["Read staged diff"]
    C --> D["Call Agent
Generate caveman-commit"] D --> E["Write commit message"] E --> F["Open editor
(editable)"] F --> G["βœ… Commit complete"]

πŸ“Š Five Platforms Commit Workflow Comparison

Dimension Claude Code Antigravity Gemini CLI Codex OpenCode
Trigger Command /caveman-commit Natural language /caveman-commit $caveman-commit Natural language
Automatically read diff βœ… git diff --cached βœ… βœ… βœ… βœ…
Directly execute commit βœ… Can be requested ⚠️ Requires confirmation βœ… Can be requested βœ… Can be requested ⚠️ Requires confirmation
Git Hook Integration βœ… Native support ❌ Manual setup required ⚠️ Limited βœ… hooks.json ❌ Manual setup required
Batch multiple commits βœ… βœ… βœ… βœ… βœ…

πŸ“ Key Takeaways

  1. /caveman-commit generates concise commit messages in Conventional Commits format
  2. Three rules: ≀50 character subject line + Conventional Commits + Why over What
  3. All platforms support it, but trigger methods differ (Claude Code uses /, Codex uses $, others use natural language)
  4. Can be integrated with Git's prepare-commit-msg Hook for automation
  5. Key principle: commit messages should tell the reader "why" rather than "what"

πŸ”— References