smart-commit
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTriggers: When the user says "commit", "smart commit", or /commit.
触发条件:当用户说"commit"、"smart commit"或输入/commit时。
When to Use
适用场景
Triggers: When the user says "commit", "smart commit", or /commit.
- Committing staged changes in any git repository
- When you want a well-structured conventional commit message
- When you want automatic detection of common commit issues before pushing
触发条件:当用户说"commit"、"smart commit"或输入/commit时。
- 在任意Git仓库中提交已暂存的变更
- 希望生成结构清晰的符合规范的提交信息(conventional commit message)
- 希望在推送前自动检测提交中的常见问题
Process
执行流程
Step 1 — Read working-tree state
步骤1 — 读取工作区状态
Run these commands and collect their output:
bash
git status --porcelain # full working-tree state: staged, unstaged, untracked
git diff --cached # full diff for content analysis (staged changes)Also check:
bash
git log --oneline -5 # recent commits to match message styleParse the output and assign a staging-status tag to each file:
git status --porcelain- Lines where → tag
XY = "??"untracked - Lines where X is ,
A,M,R, orD(index column non-space) → tagCstaged- If X = (rename), split the entry on
Rand include both the old path and the new path; both receive tag" -> "staged
- If X =
- Lines where X = and Y is
" ",M, orD(worktree column non-space) → tagTunstaged - When both X and Y are non-space (staged change also has worktree modifications), the index change takes precedence: tag
staged
If returns empty output, report:
git status --porcelainNothing to commit. Working tree is clean.
And stop — do not proceed.
运行以下命令并收集输出:
bash
git status --porcelain # 完整工作区状态:已暂存、未暂存、未跟踪
git diff --cached # 用于内容分析的完整差异(已暂存变更)同时执行:
bash
git log --oneline -5 # 最近提交记录,用于匹配提交信息风格解析的输出,为每个文件分配暂存状态标签:
git status --porcelain- 当→ 标签
XY = "??"(未跟踪)untracked - 当X为、
A、M、R或D(索引列非空格)→ 标签C(已暂存)staged- 若X = (重命名),将条目按
R拆分,同时包含旧路径和新路径;两者均标记为" -> "staged
- 若X =
- 当X = 且Y为
" "、M或D(工作区列非空格)→ 标签T(未暂存)unstaged - 当X和Y均为非空格(已暂存变更同时存在工作区修改),优先以索引变更为准:标记为
staged
若返回空输出,提示:
git status --porcelain没有可提交的内容。工作区干净。
并终止流程——不再继续执行。
Step 1b — Group detected files
步骤1b — 对检测到的文件分组
Using the file paths collected in Step 1, apply the following grouping heuristic in priority order. Each detected file is assigned to exactly one group — the first rule that matches wins, and the file is not reconsidered by later rules. Each file's tag (assigned in Step 1) travels unchanged through the grouping step and is preserved in the group record.
staging-statusRule 1 — Test files (highest priority, applied before any directory check):
- Paths matching ,
*.test.*,*.spec.*, or_test.*→ group*_test.*test - This rule applies regardless of which directory the file lives in.
Rule 2 — Config/infra files:
- Root-level files (no subdirectory) matching ,
*.json,*.yaml,*.yml,*.toml, or*.sh→ group*.env*chore
Rule 3 — Docs files:
- Paths under → group
docs/docs - Root-level files matching or
*.md→ groupREADME*docs
Rule 4 — Directory prefix:
- Remaining files are grouped by their first path segment (e.g., → group
skills/smart-commit/SKILL.md;skills→ grouphooks/smart-commit-context.js)hooks
Fallback:
- Files that match none of the rules above (e.g., a root-level with no subdirectory and no recognized extension) → group
foo.rbmisc
No detected file may appear in more than one group. Every detected file must appear in exactly one group.
Single-group fast-path: If grouping produces exactly one group → skip the multi-commit plan and fall through to Step 2 unchanged. Behavior is identical to the pre-grouping version of this skill. If the single group contains any files tagged or , print then issue before proceeding to Step 2.
unstageduntrackedAuto-staging N file(s): <list of those files>git add <unstaged/untracked files>Multi-group branch: If grouping produces two or more groups → proceed to Step 1c (multi-commit plan) before executing any commit.
使用步骤1中收集的文件路径,按以下优先级顺序应用分组规则。每个检测到的文件仅分配到一个组——匹配的第一条规则生效,后续规则不再考虑该文件。每个文件的暂存状态标签(步骤1中分配)在分组过程中保持不变,并保留在组记录中。
规则1 — 测试文件(优先级最高,先于任何目录检查):
- 路径匹配、
*.test.*、*.spec.*或_test.*→ 分组*_test.*test - 此规则适用于所有目录下的文件。
规则2 — 配置/基础设施文件:
- 根目录文件(无子目录)匹配、
*.json、*.yaml、*.yml、*.toml或*.sh→ 分组*.env*chore
规则3 — 文档文件:
- 路径位于下 → 分组
docs/docs - 根目录文件匹配或
*.md→ 分组README*docs
规则4 — 目录前缀:
- 剩余文件按首个路径段分组(例如:→ 分组
skills/smart-commit/SKILL.md;skills→ 分组hooks/smart-commit-context.js)hooks
兜底规则:
- 不匹配上述任何规则的文件(例如:根目录下无扩展名的)→ 分组
foo.rbmisc
每个检测到的文件只能属于一个组,且必须属于某一个组。
单组快速路径:若分组结果仅为一个组 → 跳过多提交计划,直接执行步骤2。行为与该技能的预分组版本完全一致。若单组包含任何标记为或的文件,先打印,再执行,之后继续步骤2。
unstageduntrackedAuto-staging N file(s): <list of those files>git add <unstaged/untracked files>多组分支:若分组结果为两个或更多组 → 在执行任何提交前,先进入步骤1c(多提交计划)。
Step 1c — Present multi-commit plan
步骤1c — 展示多提交计划
For each group identified in Step 1b, run Steps 2 and 3 independently using a scoped diff limited to that group's files:
bash
git diff --cached -- <file-1> <file-2> ... # scoped to this group's file list onlyUse this scoped diff (not the full ) as the input for both the commit message generation (Step 2) and the issue detection (Step 3) for that group.
git diff --cachedERROR collection before display: Collect all ERROR-severity findings across every group before printing anything to the user. If any group yields one or more ERRORs:
- Print all ERRORs found across all groups.
- Print:
Commit plan blocked. Fix the errors above before committing. - Stop — do not display the plan, do not proceed to any .
git commit
Display the full plan (only when no ERRORs are present):
This annotation MUST appear before any or is issued, so the user can review the exact staging-status of every file before confirming.
git addgit commitundefined针对步骤1b中识别的每个组,使用限定于该组文件的范围差异,独立执行步骤2和步骤3:
bash
git diff --cached -- <file-1> <file-2> ... # 仅限定于该组文件列表使用此范围差异(而非完整的)作为该组的提交信息生成(步骤2)和问题检测(步骤3)的输入。
git diff --cached展示前收集错误:在向用户输出任何内容前,收集所有组中的ERROR级问题。若任何组存在一个或多个ERROR:
- 打印所有组中发现的ERROR。
- 打印:
提交计划已阻止。修复上述错误后再提交。 - 终止流程——不展示计划,不执行任何。
git commit
展示完整计划(仅当无ERROR时):
此注释必须在执行任何或前显示,以便用户在确认前查看每个文件的准确暂存状态。
git addgit commitundefinedSmart Commit Plan (N commits)
智能提交计划(共N次提交)
────────────────────────────────────
Commit 1 of N — [label]
Files: file-a.md [staged], file-b.md [unstaged]
Proposed message:
type(scope): short description
────────────────────────────────────
Commit 2 of N — [label]
Files: skills/smart-commit/SKILL.md [untracked]
Proposed message:
type(scope): short description
────────────────────────────────────
Issues detected across all groups:
⚠️ WARNING in commit 1: <message>
Each file in the `Files:` line is annotated with its staging-status marker: `[staged]`, `[unstaged]`, or `[untracked]`.
Display any WARNING-severity findings in the plan summary (non-blocking). If there are no issues, omit the "Issues detected" section.
**Plan-level confirmation prompt**:
Proceed with all commits? [commit all / step-by-step / abort]
- `commit all` → proceed to Step 5, multi-group "commit all" path
- `step-by-step` → proceed to Step 5, multi-group "step-by-step" path
- `abort` → print `Commit plan aborted. No files were staged. Working tree is unchanged.` and stop; no `git add` or `git commit` is executed────────────────────────────────────
第1次提交(共N次) — [标签]
文件:file-a.md [staged], file-b.md [unstaged]
提议的提交信息:
type(scope): short description
────────────────────────────────────
第2次提交(共N次) — [标签]
文件:skills/smart-commit/SKILL.md [untracked]
提议的提交信息:
type(scope): short description
────────────────────────────────────
所有组中检测到的问题:
⚠️ 第1次提交中的警告:<message>
`文件:`行中的每个文件都标注了其暂存状态标记:`[staged]`、`[unstaged]`或`[untracked]`。
在计划摘要中展示WARNING级问题(非阻塞)。若无问题,省略“检测到的问题”部分。
**计划级确认提示**:
是否执行所有提交?[全部提交 / 分步提交 / 终止]
- `全部提交` → 进入步骤5,多组“全部提交”路径
- `分步提交` → 进入步骤5,多组“分步提交”路径
- `终止` → 打印`提交计划已终止。未暂存任何文件。工作区未更改。`并终止流程;不执行任何`git add`或`git commit`Step 2 — Analyze changes
步骤2 — 分析变更
From the diff output, determine:
| Signal | Derivation |
|---|---|
| type | |
| scope | The primary directory or domain that changed (e.g. |
| summary | One-line description of WHAT changed and WHY (present tense, lowercase, no period) |
| body | Bullet list of key changes if more than one file is affected |
从差异输出中确定:
| 信号 | 推导方式 |
|---|---|
| type | |
| scope | 变更涉及的主要目录或领域(例如 |
| summary | 一行描述变更内容及原因(现在时、小写、无句号) |
| body | 若涉及多个文件,列出关键变更的项目符号列表 |
Step 3 — Detect issues
步骤3 — 检测问题
Scan output for these patterns. Report as ERROR (blocking) or WARNING (non-blocking):
git diff --cached| Severity | Condition | Message |
|---|---|---|
| ERROR | Any file matching | |
| ERROR | Added lines ( | |
| WARNING | Added lines contain | |
| WARNING | Added lines contain | |
| WARNING | Any staged file is a known binary and exceeds 1 MB | |
| WARNING | Any staged path starts with | |
扫描输出中的以下模式,标记为ERROR(阻塞)或WARNING(非阻塞):
git diff --cached| 严重级别 | 条件 | 提示信息 |
|---|---|---|
| ERROR | 任何匹配 | |
| ERROR | 新增行( | |
| WARNING | 新增行包含 | |
| WARNING | 新增行包含 | |
| WARNING | 已暂存的已知二进制文件超过1MB | |
| WARNING | 已暂存路径以 | |
Step 4 — Present summary
步骤4 — 展示摘要
Output a structured report before committing:
undefined提交前输出结构化报告:
undefinedSmart Commit Summary
智能提交摘要
Staged: N files +X −Y lines
Proposed commit message:
──────────────────────────────
type(scope): short description
- bullet change 1
- bullet change 2 ──────────────────────────────
Issues detected:
⛔ ERROR: .env.local is staged — unstage with: git restore --staged .env.local
⚠️ WARNING: console.log in pages/api/auth.js (2 occurrences)
⚠️ WARNING: TODO: left in domain/payment/PaymentService.js
Then, based on severity:
- **ERRORs present** → Print: `Commit blocked. Fix the errors above before committing.` Do NOT proceed.
- **Warnings only** → Ask: `Proceed with commit? [y / edit message / abort]`
- **No issues** → Ask: `Proceed with commit? [y / edit message / abort]`
If the user chooses **edit message**: ask them to provide the new message, then use it verbatim.
If the user chooses **abort**: stop, print `Commit aborted.`已暂存: N个文件 +X −Y行
提议的提交信息:
──────────────────────────────
type(scope): short description
- 变更点1
- 变更点2 ──────────────────────────────
检测到的问题:
⛔ 错误: .env.local已暂存 — 取消暂存请执行: git restore --staged .env.local
⚠️ 警告: pages/api/auth.js中存在console.log(共2处)
⚠️ 警告: domain/payment/PaymentService.js中遗留TODO:
然后根据严重级别处理:
- **存在ERROR** → 打印: `提交已阻止。修复上述错误后再提交。` 不继续执行。
- **仅存在警告** → 询问: `是否继续提交?[是 / 编辑信息 / 终止]`
- **无问题** → 询问: `是否继续提交?[是 / 编辑信息 / 终止]`
若用户选择**编辑信息**: 请用户提供新信息,直接使用该内容。
若用户选择**终止**: 停止流程,打印`提交已终止。`Step 5 — Execute commit
步骤5 — 执行提交
After confirmation, execute:
bash
git commit -m "$(cat <<'EOF'
type(scope): short description
- bullet change 1
- bullet change 2
EOF
)"On success, report:
✅ Committed: <hash> — type(scope): short descriptionOn failure, report the full git error and suggest remediation.
Multi-group "commit all" path (when user chose at Step 1c):
commit allIterate through every group in the order shown in the plan. For each group:
0. For each file in this group tagged or , issue ; skip files already tagged .
unstageduntrackedgit add <file>staged- Execute with the group's proposed message.
git commit - Print the resulting commit hash immediately after each commit fires.
- Do not present any intermediate prompt between groups.
After all groups have been committed, print the full-execution summary (see below).
Multi-group "step-by-step" path (when user chose at Step 1c):
step-by-stepBefore each group's commit, print the per-commit confirmation block:
undefined确认后执行:
bash
git commit -m "$(cat <<'EOF'
type(scope): short description
- 变更点1
- 变更点2
EOF
)"成功后提示:
✅ 已提交: <hash> — type(scope): short description失败后,输出完整的Git错误信息并建议修复方案。
多组“全部提交”路径(用户在步骤1c中选择):
全部提交按计划中显示的顺序遍历每个组。针对每个组:
0. 对该组中标记为或的文件执行;跳过已标记为的文件。
unstageduntrackedgit add <file>staged- 使用该组提议的信息执行。
git commit - 每次提交后立即打印生成的提交哈希。
- 组间不显示任何中间提示。
所有组提交完成后,打印完整执行摘要(见下文)。
多组“分步提交”路径(用户在步骤1c中选择):
分步提交每个组提交前,打印单次提交确认块:
undefinedCommit N of M — [label]
第N次提交(共M次) — [标签]
Files: file-a.md, file-b.md
Proposed message:
──────────────────────────────
type(scope): short description
- bullet 1 ──────────────────────────────
Proceed? [y / edit message / skip / abort remaining]
Apply the user's choice before moving to the next group:
- `y` → for each file in this group tagged `unstaged` or `untracked`, issue `git add <file>`; skip files already tagged `staged`; then execute `git commit` with the proposed message; print the resulting hash; continue to the next group.
- `edit message` → prompt: `Enter replacement message:` — use the provided text verbatim for this commit only; for each file in this group tagged `unstaged` or `untracked`, issue `git add <file>`; skip files already tagged `staged`; then execute and print the hash; continue to the next group.
- `skip` → no `git add` is issued for this group; leave this group's files in their original state without committing; move to the next group.
- `abort remaining` → no `git add` is issued for remaining groups; stop processing after the current group (do not commit any subsequent groups); print the partial-execution summary.
**Partial-execution summary** (triggered when all groups complete or when `abort remaining` is chosen mid-sequence):
When **all groups succeeded** (or were skipped without aborting):N of N commits executed.
✅ <hash-1> — type(scope): description (commit 1)
✅ <hash-2> — type(scope): description (commit 2)
...
When **execution was aborted mid-sequence** (M commits executed, remaining groups not committed):M of N commits executed.
✅ <hash-1> — type(scope): description (commit 1)
✅ <hash-2> — type(scope): description (commit 2)
Not committed — files remain in original state:
Commit <next> of N — [label]
Files: file-x.md [staged], file-y.md [unstaged]
Proposed message: type(scope): description
Commit <next+1> of N — [label]
Files: file-z.md [untracked]
Proposed message: type(scope): description
Do NOT attempt to undo or roll back any commits that have already been executed.
---文件: file-a.md, file-b.md
提议的提交信息:
──────────────────────────────
type(scope): short description
- 变更点1 ──────────────────────────────
是否继续?[是 / 编辑信息 / 跳过 / 终止剩余]
根据用户选择处理后进入下一组:
- `是` → 对该组中标记为`unstaged`或`untracked`的文件执行`git add <file>`;跳过已标记为`staged`的文件;然后使用提议信息执行`git commit`;打印哈希;进入下一组。
- `编辑信息` → 提示: `输入替换信息:` — 仅将该内容用于本次提交;对该组中标记为`unstaged`或`untracked`的文件执行`git add <file>`;跳过已标记为`staged`的文件;执行提交并打印哈希;进入下一组。
- `跳过` → 不对该组执行`git add`;保留该组文件的原始状态不提交;进入下一组。
- `终止剩余` → 不对剩余组执行`git add`;当前组处理完成后停止(不提交后续组);打印部分执行摘要。
**部分执行摘要**(所有组完成或中途选择`终止剩余`时触发):
当**所有组提交成功**(或被跳过未终止):共执行N次提交中的N次。
✅ <hash-1> — type(scope): description(第1次提交)
✅ <hash-2> — type(scope): description(第2次提交)
...
当**执行中途终止**(已执行M次提交,剩余组未提交):共执行N次提交中的M次。
✅ <hash-1> — type(scope): description(第1次提交)
✅ <hash-2> — type(scope): description(第2次提交)
未提交的文件保持原始状态:
第<next>次提交(共N次) — [标签]
文件: file-x.md [staged], file-y.md [unstaged]
提议信息: type(scope): description
第<next+1>次提交(共N次) — [标签]
文件: file-z.md [untracked]
提议信息: type(scope): description
请勿尝试撤销或回滚已执行的任何提交。
---Anti-Patterns
反模式
Don't generate vague messages
不要生成模糊的提交信息
undefinedundefinedBad
错误示例
git commit -m "update"
git commit -m "fix stuff"
git commit -m "changes"
git commit -m "update"
git commit -m "fix stuff"
git commit -m "changes"
Good
正确示例
git commit -m "fix(auth): prevent session expiry on page reload"
git commit -m "feat(player): add shuffle mode to playlist"
undefinedgit commit -m "fix(auth): prevent session expiry on page reload"
git commit -m "feat(player): add shuffle mode to playlist"
undefinedDon't bypass ERRORs
不要绕过ERROR
If a file or credential pattern is detected, stop unconditionally. Do not commit even if the user asks to skip.
.env若检测到文件或凭证模式,无条件停止。即使用户要求跳过,也不执行提交。
.envDon't stage files that were not confirmed
不要暂存未确认的文件
Issue only for groups the user explicitly confirmed; never batch-stage all detected files upfront before the plan confirmation.
git add仅对用户明确确认的组执行;切勿在计划确认前批量暂存所有检测到的文件。
git addQuick Reference
快速参考
| Situation | Commit format |
|---|---|
| Single file changed | |
| Multiple files, same domain | |
| Multiple unrelated domains | |
| Only documentation | |
| Only dependency changes | |
| Only formatting/whitespace | |
| Only test additions | |
| 场景 | 提交格式 |
|---|---|
| 仅单个文件变更 | |
| 多个文件变更,同一领域 | |
| 多个文件变更,无关领域 | |
| 仅文档修改 | |
| 仅依赖变更 | |
| 仅格式/空白字符修改 | |
| 仅新增测试 | |
Rules
规则
- Never commit without first presenting the generated message summary and waiting for explicit user confirmation
- Detect and block commits that contain secrets (API keys, tokens, passwords) found by pattern matching in the diff
- Detect and warn on ,
console.log,debugger, and large binary files in the staged diff before committingTODO - Commit messages must follow conventional commits format (); generated messages that cannot be classified must default to
type(scope): descriptionwith a descriptive subjectchore: - Detect files from the full working tree via ; assign each file a staging-status tag (
git status --porcelain,staged,unstaged) during Step 1untracked - Auto-stage only the files of a confirmed group — issue for files tagged
git add <files>orunstagedimmediately before that group'suntracked; never re-add already-staged filesgit commit - For skipped or aborted groups, issue no — their files must remain in the exact state they were in when the skill was invoked
git add - When detected files span two or more functional groups, present the full multi-commit plan before executing any commit
- ERROR conditions in any group block the entire multi-commit plan — no partial execution allowed when ERRORs are present
- Every commit in a multi-commit sequence uses the proposed message without additional trailers
- The grouping heuristic is applied in priority order: test → config/infra → docs → directory prefix → misc fallback; no file may appear in more than one group
- The single-group fast-path preserves exact backward compatibility — no behavior change when all staged files resolve to one group
- 必须先展示生成的信息摘要并等待用户明确确认,才能执行提交
- 检测并阻止包含通过差异模式匹配发现的密钥(API密钥、令牌、密码)的提交
- 提交前检测已暂存差异中的、
console.log、debugger和大二进制文件并发出警告TODO - 提交信息必须遵循conventional commits格式();无法分类的生成信息默认使用
type(scope): description开头并附带描述性主题chore: - 通过检测整个工作区的文件;步骤1中为每个文件分配暂存状态标签(
git status --porcelain、staged、unstaged)untracked - 仅自动暂存已确认组的文件 — 在该组执行前立即对标记为
git commit或unstaged的文件执行untracked;切勿重新暂存已暂存的文件git add <files> - 对于被跳过或终止的组,不执行— 其文件必须保持技能调用时的原始状态
git add - 当检测到的文件涉及两个或更多功能组时,先展示完整的多提交计划再执行任何提交
- 任何组中的ERROR条件会阻止整个多提交计划 — 存在ERROR时不允许部分执行
- 多提交序列中的每次提交均使用提议信息,不添加额外尾部内容
- 分组规则按优先级顺序应用:测试 → 配置/基础设施 → 文档 → 目录前缀 → 兜底杂项;每个文件只能属于一个组
- 单组快速路径保持完全向后兼容性 — 当所有已暂存文件归为一个组时,行为无变化