Guide to automate the git commit workflow. Use when users want to commit changes, stage and commit, generate a commit message, or finalize an editing session with a commit. Also triggers when users mention commit my changes, help me commit, ok commit it, or looks good commit.
Run all checks in order. If any check fails, report the error and abort immediately.
Inside a git repository: Run git rev-parse --is-inside-work-tree. If it
fails, abort:
Error: Not inside a git repository.
Run `git init` first, or navigate to a git project directory.
Not in a conflicted state: Check for in-progress operations by testing
whether .git/MERGE_HEAD, .git/rebase-merge/, .git/rebase-apply/, or
.git/CHERRY_PICK_HEAD exist. If any are present, abort:
Error: Repository is in the middle of a merge/rebase/cherry-pick.
Resolve conflicts and finalize or abort the operation first, then try again.
Has uncommitted changes: Run git status --porcelain. If the output is
empty, abort:
Error: Nothing to commit — working tree is clean.
Staging area: Run git diff --staged --quiet. If the staging area is
empty (exit code 0), automatically run git add -A and inform the user:
No staged changes found — automatically staged all changes with `git add -A`.
This does not block execution — proceed to Step 1.
Check for reusable context first. Skip the diff analysis if both of the following are true:
If context is reusable, extract the change summary from the conversation and proceed directly to Step 2.
If new changes were made after the last review, note the delta and ask the user whether to re-analyze or proceed with the prior context.
Standard path (no reusable context): Run git diff --staged and analyze:
Construct the message following conventional commits:
<type>: <subject>
Type selection guide:
| Type | When to use |
|---|---|
feat | Introduces new functionality visible to users or consumers |
fix | Corrects a bug or unintended behavior |
refactor | Code restructuring with no behavior change |
perf | Performance improvement |
test | Adding or updating tests |
docs | Documentation only |
chore | Build process, tooling, dependencies, config |
style | Formatting, whitespace, semicolons — no logic change |
ci | CI/CD pipeline changes |
Rules for the subject line:
Default: short format only (header line). Body and footer are intentionally omitted unless one of these conditions clearly applies:
BREAKING CHANGE: in footer)Fixes #xxx, Closes #xxx)If body/footer are needed, proceed to Step 3. Otherwise, proceed directly to Step 4.
MUST use the question tool to present options to the user. Never execute git commit with a multi-line message without user confirmation.
Use the question tool with:
<type>: <subject>Before presenting the question, show the prepared extended message:
I've prepared an extended commit message:
<type>: <subject>
<body — explains the why, not the what>
<footer — BREAKING CHANGE, Fixes #xxx, etc.>
Short message: git commit -m "<header>"
Extended message (approved in Step 3):
git commit -m "$(cat <<'EOF'
<type>: <subject>
<body>
<footer>
EOF
)"
On success, output the commit hash and message, then stop.
On failure, proceed to Step 5.
Track attempt count. Maximum 3 retries total.
On each failure:
Failure types and fix strategies:
| Failure type | Fix strategy |
|---|---|
| lint/format hook failure (autofix available) | Run the autofix command reported by the hook (e.g., eslint --fix, prettier --write), re-stage affected files with git add, then retry |
| lint/format hook failure (no autofix command) | Read the error details, directly edit the offending source files to resolve the reported violations, re-stage, then retry |
| commit message rejected by hook | Adjust the message to satisfy the hook's requirements (e.g., length, format regex), then retry |
| type check or test failure triggered by hook | Analyze the failure output; if the fix is mechanical (e.g., a missing import, a type annotation), apply it directly; otherwise surface to user |
| file lock or permission error | Do not retry; report immediately with the suggested manual resolution |
| merge/rebase state detected mid-run | Do not retry; report immediately |
After 3 failed attempts, stop retrying and report:
Commit failed after 3 attempts. Here is a summary of what was tried and what
remains unresolved:
- Attempt 1: <what was tried> — <what failed>
- Attempt 2: <what was tried> — <what failed>
- Attempt 3: <what was tried> — <what failed>
Suggested next steps:
<concrete, actionable steps the user can take to resolve this manually>
Keep suggestions specific: name the files, commands, and error lines involved. Avoid generic advice like "fix the lint errors".