smart-commit

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
Triggers: 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 style
Parse the
git status --porcelain
output and assign a staging-status tag to each file:
  • Lines where
    XY = "??"
    → tag
    untracked
  • Lines where X is
    A
    ,
    M
    ,
    R
    ,
    D
    , or
    C
    (index column non-space) → tag
    staged
    • If X =
      R
      (rename), split the entry on
      " -> "
      and include both the old path and the new path; both receive tag
      staged
  • Lines where X =
    " "
    and Y is
    M
    ,
    D
    , or
    T
    (worktree column non-space) → tag
    unstaged
  • When both X and Y are non-space (staged change also has worktree modifications), the index change takes precedence: tag
    staged
If
git status --porcelain
returns empty output, report:
Nothing 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 =
    " "
    且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
staging-status
tag (assigned in Step 1) travels unchanged through the grouping step and is preserved in the group record.
Rule 1 — Test files (highest priority, applied before any directory check):
  • Paths matching
    *.test.*
    ,
    *.spec.*
    ,
    _test.*
    , or
    *_test.*
    → group
    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
    ,
    *.sh
    , or
    *.env*
    → group
    chore
Rule 3 — Docs files:
  • Paths under
    docs/
    → group
    docs
  • Root-level files matching
    *.md
    or
    README*
    → group
    docs
Rule 4 — Directory prefix:
  • Remaining files are grouped by their first path segment (e.g.,
    skills/smart-commit/SKILL.md
    → group
    skills
    ;
    hooks/smart-commit-context.js
    → group
    hooks
    )
Fallback:
  • Files that match none of the rules above (e.g., a root-level
    foo.rb
    with no subdirectory and no recognized extension) → group
    misc
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
unstaged
or
untracked
, print
Auto-staging N file(s): <list of those files>
then issue
git add <unstaged/untracked files>
before proceeding to Step 2.
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.rb
    )→ 分组
    misc
每个检测到的文件只能属于一个组,且必须属于某一个组。
单组快速路径:若分组结果仅为一个组 → 跳过多提交计划,直接执行步骤2。行为与该技能的预分组版本完全一致。若单组包含任何标记为
unstaged
untracked
的文件,先打印
Auto-staging N file(s): <list of those files>
,再执行
git add <unstaged/untracked files>
,之后继续步骤2。
多组分支:若分组结果为两个或更多组 → 在执行任何提交前,先进入步骤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 only
Use this scoped diff (not the full
git diff --cached
) as the input for both the commit message generation (Step 2) and the issue detection (Step 3) for that group.
ERROR 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
git add
or
git commit
is issued, so the user can review the exact staging-status of every file before confirming.
undefined
针对步骤1b中识别的每个组,使用限定于该组文件的范围差异,独立执行步骤2和步骤3:
bash
git diff --cached -- <file-1> <file-2> ...   # 仅限定于该组文件列表
使用此范围差异(而非完整的
git diff --cached
)作为该组的提交信息生成(步骤2)和问题检测(步骤3)的输入。
展示前收集错误:在向用户输出任何内容前,收集所有组中的ERROR级问题。若任何组存在一个或多个ERROR:
  • 打印所有组中发现的ERROR。
  • 打印:
    提交计划已阻止。修复上述错误后再提交。
  • 终止流程——不展示计划,不执行任何
    git commit
展示完整计划(仅当无ERROR时):
此注释必须在执行任何
git add
git commit
前显示,以便用户在确认前查看每个文件的准确暂存状态。
undefined

Smart 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:
SignalDerivation
type
feat
new files/features;
fix
bug fixes;
refactor
restructure;
chore
config/deps;
docs
docs only;
test
tests only;
style
formatting only
scopeThe primary directory or domain that changed (e.g.
auth
,
payment
,
player
). Omit if changes span many unrelated domains.
summaryOne-line description of WHAT changed and WHY (present tense, lowercase, no period)
bodyBullet list of key changes if more than one file is affected
从差异输出中确定:
信号推导方式
type
feat
新增文件/功能;
fix
修复bug;
refactor
重构代码;
chore
配置/依赖变更;
docs
仅文档修改;
test
仅测试代码修改;
style
仅格式调整
scope变更涉及的主要目录或领域(例如
auth
payment
player
)。若变更涉及多个无关领域,可省略。
summary一行描述变更内容及原因(现在时、小写、无句号)
body若涉及多个文件,列出关键变更的项目符号列表

Step 3 — Detect issues

步骤3 — 检测问题

Scan
git diff --cached
output for these patterns. Report as ERROR (blocking) or WARNING (non-blocking):
SeverityConditionMessage
ERRORAny file matching
*.env
,
.env
,
.env.*
,
.env.local
is staged
.env file staged — unstage with: git restore --staged <file>
ERRORAdded lines (
+
prefix) match
password\s*=\s*\S+
,
api_key\s*=\s*\S+
,
secret\s*=\s*\S+
,
token\s*=\s*\S+
(case-insensitive, value present)
Possible credential in <file>:<line> — verify before committing
WARNINGAdded lines contain
console.log
,
debugger
,
print(
,
puts 
Debug statement in <file> (N occurrences)
WARNINGAdded lines contain
TODO:
or
FIXME:
Unresolved TODO/FIXME in <file>
WARNINGAny staged file is a known binary and exceeds 1 MB
Large file staged: <file> (<size>MB)
WARNINGAny staged path starts with
node_modules/
or contains
/dist/
Build artifact staged: <file>
扫描
git diff --cached
输出中的以下模式,标记为ERROR(阻塞)或WARNING(非阻塞):
严重级别条件提示信息
ERROR任何匹配
*.env
.env
.env.*
.env.local
的文件已暂存
.env文件已暂存 — 取消暂存请执行: git restore --staged <file>
ERROR新增行(
+
前缀)匹配
password\s*=\s*\S+
api_key\s*=\s*\S+
secret\s*=\s*\S+
token\s*=\s*\S+
(不区分大小写,存在有效值)
<file>:<line>中可能包含凭证 — 提交前请验证
WARNING新增行包含
console.log
debugger
print(
puts 
<file>中存在调试语句(共N处)
WARNING新增行包含
TODO:
FIXME:
<file>中存在未处理的TODO/FIXME
WARNING已暂存的已知二进制文件超过1MB
已暂存大文件: <file>(大小<size>MB)
WARNING已暂存路径以
node_modules/
开头或包含
/dist/
已暂存构建产物: <file>

Step 4 — Present summary

步骤4 — 展示摘要

Output a structured report before committing:
undefined
提交前输出结构化报告:
undefined

Smart 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 description
On failure, report the full git error and suggest remediation.
Multi-group "commit all" path (when user chose
commit all
at Step 1c):
Iterate through every group in the order shown in the plan. For each group: 0. For each file in this group tagged
unstaged
or
untracked
, issue
git add <file>
; skip files already tagged
staged
.
  1. Execute
    git commit
    with the group's proposed message.
  2. Print the resulting commit hash immediately after each commit fires.
  3. 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
step-by-step
at Step 1c):
Before 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. 对该组中标记为
unstaged
untracked
的文件执行
git add <file>
;跳过已标记为
staged
的文件。
  1. 使用该组提议的信息执行
    git commit
  2. 每次提交后立即打印生成的提交哈希。
  3. 组间不显示任何中间提示。
所有组提交完成后,打印完整执行摘要(见下文)。
多组“分步提交”路径(用户在步骤1c中选择
分步提交
):
每个组提交前,打印单次提交确认块:
undefined

Commit 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

不要生成模糊的提交信息

undefined
undefined

Bad

错误示例

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"
undefined
git commit -m "fix(auth): prevent session expiry on page reload" git commit -m "feat(player): add shuffle mode to playlist"
undefined

Don't bypass ERRORs

不要绕过ERROR

If a
.env
file or credential pattern is detected, stop unconditionally. Do not commit even if the user asks to skip.
若检测到
.env
文件或凭证模式,无条件停止。即使用户要求跳过,也不执行提交。

Don't stage files that were not confirmed

不要暂存未确认的文件

Issue
git add
only for groups the user explicitly confirmed; never batch-stage all detected files upfront before the plan confirmation.

仅对用户明确确认的组执行
git add
;切勿在计划确认前批量暂存所有检测到的文件。

Quick Reference

快速参考

SituationCommit format
Single file changed
type(scope): description
(no body)
Multiple files, same domain
type(scope): description
+ bullet body
Multiple unrelated domains
type: description
(no scope) + bullet body
Only documentation
docs(scope): update ...
Only dependency changes
chore(deps): update X to Y.Z
Only formatting/whitespace
style(scope): format ...
Only test additions
test(scope): add tests for ...
场景提交格式
仅单个文件变更
type(scope): description
(无正文)
多个文件变更,同一领域
type(scope): description
+ 项目符号正文
多个文件变更,无关领域
type: description
(无scope) + 项目符号正文
仅文档修改
docs(scope): update ...
仅依赖变更
chore(deps): update X to Y.Z
仅格式/空白字符修改
style(scope): format ...
仅新增测试
test(scope): add tests for ...

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
    ,
    TODO
    , and large binary files in the staged diff before committing
  • Commit messages must follow conventional commits format (
    type(scope): description
    ); generated messages that cannot be classified must default to
    chore:
    with a descriptive subject
  • Detect files from the full working tree via
    git status --porcelain
    ; assign each file a staging-status tag (
    staged
    ,
    unstaged
    ,
    untracked
    ) during Step 1
  • Auto-stage only the files of a confirmed group — issue
    git add <files>
    for files tagged
    unstaged
    or
    untracked
    immediately before that group's
    git commit
    ; never re-add already-staged files
  • For skipped or aborted groups, issue no
    git add
    — their files must remain in the exact state they were in when the skill was invoked
  • 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:
    开头并附带描述性主题
  • 通过
    git status --porcelain
    检测整个工作区的文件;步骤1中为每个文件分配暂存状态标签(
    staged
    unstaged
    untracked
  • 仅自动暂存已确认组的文件 — 在该组执行
    git commit
    前立即对标记为
    unstaged
    untracked
    的文件执行
    git add <files>
    ;切勿重新暂存已暂存的文件
  • 对于被跳过或终止的组,不执行
    git add
    — 其文件必须保持技能调用时的原始状态
  • 当检测到的文件涉及两个或更多功能组时,先展示完整的多提交计划再执行任何提交
  • 任何组中的ERROR条件会阻止整个多提交计划 — 存在ERROR时不允许部分执行
  • 多提交序列中的每次提交均使用提议信息,不添加额外尾部内容
  • 分组规则按优先级顺序应用:测试 → 配置/基础设施 → 文档 → 目录前缀 → 兜底杂项;每个文件只能属于一个组
  • 单组快速路径保持完全向后兼容性 — 当所有已暂存文件归为一个组时,行为无变化