| name | git-commit |
| description | Use when user wants to create a commit NOW — says "commit this", "commit these changes", "create a commit". Routes to Java or custom project workflows when CLAUDE.md declares those types; falls back to generic commit for all others. Does NOT apply to discussions about past commits or questions about whether to commit.
|
Git Commit Helper
You are an expert in creating clean, conventional Git commits following the
Conventional Commits 1.0.0 specification.
⛔ ABSOLUTE RULE — NO EXCEPTIONS
NEVER add AI attribution to commit messages unless the user explicitly asks for it in that specific commit.
This means NO:
Co-Authored-By: Claude
Generated-by: anything
AI-assisted: anything
- Any mention of Claude, AI, LLMs, or tooling in the commit message
Commit messages describe WHAT changed and WHY. Not who or what wrote them. This rule cannot be overridden by any other instruction in this skill.
Core Rules
- Follow the Conventional Commits 1.0.0 specification.
- Subject line: imperative mood, max 50 chars, no trailing period.
- Never run
git commit until the user has explicitly confirmed.
Workflow
Step 0 — Route by project type
python3 ~/.claude/skills/project-init/ctx.py
Read PROJECT_TYPE and ISSUES_STATUS from the output.
| Type | Action |
|---|
java | Read ~/.claude/skills/git-commit/java.md and follow that workflow |
custom | Read ~/.claude/skills/git-commit/custom.md and follow that workflow |
blog | STOP and tell user: "This is a type: blog project. Please use /blog-git-commit or say 'blog commit'." |
skills, generic, all others | Continue with generic workflow below |
If CLAUDE.md missing or no Project Type section:
Interactively set up project type:
I notice this repository doesn't have a Project Type declared in CLAUDE.md.
Let me help you set this up - it only takes a moment.
What kind of project is this?
- Skills repository - Claude Code skills (has */SKILL.md files)
- Java project - Maven/Gradle (has pom.xml or build.gradle)
- Blog - GitHub Pages blog (Jekyll, date-prefixed posts)
- Custom project - Working groups, research, docs, etc.
- Generic project - No special handling needed
Reply with the number (1-5) or type the name.
Wait for user response.
For the full per-type CLAUDE.md creation dialogs, read project-type-setup.md and follow the instructions for the user's chosen type, then continue to Step 1.
Step 0b — Offer issue tracking (when absent)
Read ISSUES_STATUS from the ctx.py output (already run in Step 0).
If ISSUES_STATUS is absent (whether CLAUDE.md is freshly created or already exists), ask:
Enable GitHub issue tracking for this repo? (YES / n)
Enables automatic behaviours:
- Flag tasks that span multiple concerns and help break them into issues before starting
- Check staged changes for commit splits before committing
- All commits reference a GitHub issue, so release notes generate cleanly
Default: YES — type YES to enable, type n to skip.
If YES → invoke the issue-workflow skill in Setup mode before continuing.
If n → continue immediately. Do not ask again this session.
Step 1 — Inspect staged changes
git diff --staged --stat
git diff --staged
If nothing is staged, stop and tell the user:
"Nothing is staged. Run git add <files> first, or tell me which files
to stage."
Step 1a — Review skills (if SKILL.md changes)
Check if any SKILL.md files are staged:
git diff --staged --name-only | grep 'SKILL.md$'
If SKILL.md files found:
- Follow the
skill-validation.md workflow to validate structure and conventions
- If CRITICAL findings exist → stop and ask user to fix before continuing
- If only WARNING/NOTE findings → hold them, continue to Step 2
If no SKILL.md files:
Step 1c — Validate documentation files
Check for staged .md files (excluding SKILL.md which was validated in Step 1a):
git diff --staged --name-only | grep '\.md$' | grep -v 'SKILL\.md$'
For each .md file found:
python scripts/validate_document.py <file>
Handle validation results:
- Exit code 1 (CRITICAL issues):
- BLOCK commit
- Show issues to user
- Ask user to fix corruption manually
- Stop workflow
- Exit code 2 (WARNING issues):
- Show warnings to user
- Ask if they want to proceed anyway
- If NO → stop workflow
- If YES → continue to Step 2
- Exit code 0 (no issues):
This step runs for ALL project types (skills, java, blog, custom, generic).
If no .md files found:
Step 2 — Issue linking and commit split check (if Work Tracking enabled)
Read ISSUES_STATUS from the ctx.py output (already run in Step 0).
If ISSUES_STATUS is enabled:
2a — Check for commit split candidates
Invoke the issue-workflow skill's pre-commit analysis on the staged diff.
If it detects changes spanning multiple concerns, surface the split suggestion
and wait for the user's response before continuing.
2b — Link to an issue
gh issue list --state open --limit 15
Check if any open issue title obviously matches the staged changes. If yes:
This looks like it relates to #{N}: {title} — correct?
(YES · NO — show full list)
If no obvious match, show the list and ask the user to select or create one.
Once an issue is confirmed, include it in the commit:
- Work in progress: append
Refs #{N} to the commit body
- Completing the issue: append
Closes #{N} to the commit body
If the user explicitly says to skip issue linking (e.g. "commit as is",
"no issue", "just commit it"):
- Add
no-issue: <reason> to the commit body
- This satisfies the
commit-msg hook while making the skip deliberate and traceable
- Confirm once before proceeding — it must be an intentional choice
If not enabled or user has no gh CLI:
Skip this step entirely — no issue linking required.
Step 3 — Generate commit message
Analyze the staged changes and draft one conventional commit message (see commit-format.md).
Hold it — don't show it yet.
Step 3b — Squash check (unpushed commits only)
Check recent unpushed commits:
git log @{u}..HEAD --oneline 2>/dev/null || git log origin/HEAD..HEAD --oneline 2>/dev/null
If there are unpushed commits, compare the most recent one(s) to the commit being drafted. Suggest squashing when:
- Same conventional commit type (both
fix:, both feat:, both chore:, etc.)
- Related or overlapping scope — the two commits address the same concern
- No meaningful history boundary between them (not two distinct logical steps)
Do NOT suggest squash when:
- Commits are logically separate steps worth preserving independently
- Previous commit marks a milestone or completes a discrete unit of work
- The branch has already been pushed — never squash pushed history
If squash is worth considering, include in the Step 6 proposal:
Squash option: The previous commit <hash> <message> is also a <type> — squashing would produce a cleaner history. Reply SQUASH to combine, or YES to commit separately.
If user replies SQUASH:
python3 ~/.claude/skills/git-commit/commit_exec.py squash <project>
Read SQUASHED from output. If ERROR=no_parent → warn and continue without squashing.
Re-stage all (previous + new changes are now combined in working tree) and commit with a single message covering the combined change.
If no unpushed commits, or no squash benefit, continue silently.
Step 4 — Sync CLAUDE.md (if exists)
Check if CLAUDE.md exists:
ls CLAUDE.md 2>/dev/null
If CLAUDE.md exists:
- Invoke the
update-claude-md skill, passing the staged diff
- It will analyze workflow/convention changes and propose CLAUDE.md updates
- Hold those proposals too
If CLAUDE.md doesn't exist:
Step 5 — Sync README.md (if skills repo)
Check if README.md exists and skill changes detected:
ls README.md 2>/dev/null && git diff --staged --name-only | grep -E '(SKILL\.md|^[^/]+/$)'
If README.md exists and skill changes found:
- MANDATORY: Follow the
readme-sync.md workflow, passing the staged diff
- Do NOT skip this step — let readme-sync.md decide if changes warrant documentation
- Do NOT rationalize "just internal changes" or "not significant enough"
- It will analyze skill collection changes and propose README.md updates
- Hold those proposals too
If README.md doesn't exist or no skill changes:
- Skip to Step 6 (present proposal)
Step 6 — Present proposal
If skill validation, CLAUDE.md, or README.md updates proposed, show consolidated proposal:
## Staged files
<output of git diff --staged --stat>
## Skill review findings (if any)
<output from skill-validation.md workflow>
## Proposed commit message
<type>[optional scope]: <description>
<optional body>
<optional footer>
## Proposed CLAUDE.md updates (if any)
<output from update-claude-md skill>
## Proposed README.md updates (if any)
<output from readme-sync.md workflow>
Otherwise, show standard proposal:
## Staged files
<output of git diff --staged --stat>
## Proposed commit message
<type>[optional scope]: <description>
<optional body>
<optional footer>
Then ask exactly:
"Does this look good? Reply YES to commit, or tell me what to adjust."
Step 7 — Commit (only after explicit YES)
If documentation updates were proposed, run in this exact order:
- Let update-claude-md apply its changes (if proposed)
- Apply README.md changes per readme-sync.md workflow (if proposed)
- Stage updated doc files:
python3 ~/.claude/skills/git-commit/commit_exec.py stage-docs <project> files=CLAUDE.md,README.md
Read STAGED=<count> from output (only files that were actually changed get staged).
4. Commit all staged files:
python3 ~/.claude/skills/git-commit/commit_exec.py commit <project> message=<confirmed-message> files=<all-staged-files-csv>
Read COMMITTED=yes, SHA=<sha> from output. If ERROR=nothing_to_commit → warn user.
If no documentation updates, commit directly:
python3 ~/.claude/skills/git-commit/commit_exec.py commit <project> message=<confirmed-message> files=<staged-files-csv>
Read COMMITTED=yes, SHA=<sha> from output. If ERROR=nothing_to_commit → warn user.
Step 8 — Handle edge cases
| Situation | Action |
|---|
| Nothing staged | Stop at step 1, prompt user to stage files |
| Merge conflict markers in diff | Warn before proceeding |
| Large diff (10+ files) | Summarize by module/category rather than file-by-file |
Common Pitfalls
| Mistake | Why It's Wrong | Fix |
|---|
| Adding AI attribution (Co-Authored-By, Generated-by, etc.) | Violates Core Rules; user didn't ask for it | Never add attribution unless user explicitly requests |
| Committing before user confirms | User loses control | Always show proposal and wait for YES |
| Subject line > 50 chars | Truncated in git log | Keep under 50, use body for details |
| Subject ends with period | Not conventional commits standard | Remove trailing period |
| Using past tense ("Added X") | Not imperative mood (wrong mental model for git revert/cherry-pick) | Use "Add X" (command form) |
Type chore for production code | Wrong semantics | Use feat, fix, or refactor |
Wrong type (refactor for bug fix) | Misleading git history | fix if it was wrong, refactor if working |
Vague scope ((skills), (stuff)) | Unclear what changed, hard to search history | Use specific component name or omit scope entirely |
| Wrong scope level (too broad/narrow) | Misleading - doesn't match actual change scope | Choose primary affected component, omit if 5+ components |
| Inconsistent scope names | Hard to track changes across commits | Stick to established component names in the repo |
| No body for complex changes | Reviewers lack context | Add why/what in body (not how) |
| Committing merge conflict markers | Broken code in history | Check diff for <<<<<<< markers first |
| Forgetting BREAKING CHANGE footer | Hidden breaking changes | Add footer with ! in type/scope |
| Running commit without staged changes | Wastes time | Check git status first |
| Leaving redundant same-type commits on an unpushed branch | Clutters history with no added value | Check Step 3b — squash consecutive same-type commits before they pile up |
| Squashing pushed commits | Rewrites shared history; breaks others' branches | Only squash unpushed commits |
Success Criteria
Commit is complete when:
- ✅ All files staged (or user confirmed which files to stage)
- ✅ Commit message generated and presented to user
- ✅ Documentation updates applied (if CLAUDE.md, README.md, or skill review needed)
- ✅ User confirmed with explicit YES
- ✅ Commit executed successfully
- ✅
git log --oneline -1 confirms commit exists
Not complete until all criteria met and commit confirmed in git log.
Skill Chaining
Invoked by: User says "commit", "make a commit", or invokes /git-commit; [adr] to commit a new ADR; [idea-log] to commit IDEAS.md additions; [write-content] to commit a new blog entry; [python-code-review] and [ts-code-review] after review approval when user wants to commit
Routes to specialized workflows based on CLAUDE.md declaration:
- type: java → Reads
~/.claude/skills/git-commit/java.md and follows Java workflow
- type: custom → Reads
~/.claude/skills/git-commit/custom.md and follows custom workflow
- type: skills → Handles directly (this skill)
- type: generic → Handles directly (this skill)
Invokes (when handling directly):
- Follows
skill-validation.md workflow for SKILL.md validation (automatic if SKILL.md files staged, type: skills only)
- [
update-claude-md] for workflow sync (automatic if CLAUDE.md exists)
- Follows
readme-sync.md workflow for skill collection sync (automatic if README.md exists and skill changes detected, type: skills only)
Interactive setup: If CLAUDE.md missing or no Project Type declared, guides user through setup and creates CLAUDE.md
Can be invoked independently: Yes, this is the entry point for all commit workflows. It reads project type and routes accordingly.
Message Format
See commit-format.md for the full format spec, types table, scope guidance, and real scope decision examples.
Examples
See commit-examples.md for concrete examples of well-formed commits across all common scenarios.