cm · diff

git:20260915.3cdb381 to git:20260926.7dc7ead

27 added, 26 removed. Audit A to A.

---
name: cm
- description: 分批分类按规范提交
+ description: 按规范提交当前改动:先查代码审过没有,每个 commit 前查密钥、调 vet 核对 message
disable-model-invocation: true
argument-hint: "[可选:限定文件或范围]"
---
- 把当前改动分批分类提交。
+ 把当前改动提交。带参数时只提交指定的那部分,其余不动。
- 先看清全部改动:`git status --porcelain`(含未跟踪文件,`git diff` 看不到它们)+ `git diff`。顺手扫一眼有没有密钥、调试输出、误加的文件。
+ ## 先看改动
- ## 分组
+ - `git status --porcelain`(含未跟踪文件,`git diff` 看不到它们)+ `git diff`。以实际改动为准,上下文里的任务列表只是线索。
+ - 改动里有代码文件(`.md`、`.txt`、图片、锁文件之外的都算),而本会话在最后一次改代码之后没跑过 `/code-review`:停下告诉我「这批代码还没审」,我回「跳过」才继续。审查放在提交前,审出的问题修进同一个 commit,不用事后改写已提交的历史。
- - 合在一起是默认,拆需要给出理由。算数的理由只有两种:这两部分放同一个 commit 里会让人看不清改了什么,或者将来想回退其中一半会连累另一半;message 的 body 需要第二段讲另一件事。说不出这两个理由就不拆。
- - 以下都不算理由:文件不同、目录不同、语言不同、改动类型不同(顺手改的一行文档不需要单独一个 docs commit)、改动行数多、跨了前后端。
- - 一两行的清理(`.gitignore` 条目、空行、拼写、格式)不单独成 commit:并进这一批里最相关的组,没有相关的就并进最大的组,message 里不提。
- - 每个 commit 必须能独立成立——单独看是完整的一件事,不是半截。一件事的所有必要部分放同一个 commit:改函数签名和它的调用点、新增配置项和读它的代码、改动和它对应的测试,不许分开提交攒数量。
- - 先看 `git log` 里这个项目历史 commit 的粒度,按同样的粒度分,不套模板。
- - 上下文里已有的任务列表只是线索,不是分组依据:任务里夹带的无关改动要拆出去,任务列表之外的零散改动要捡进来,以实际 `git diff` 为准。
- - 一个文件里混了两件事,整个文件放进主要那边,在 message 里说明。不做文件内拆分。
- - 分组必须是文件清单的一个划分:每个文件属于且只属于一个组,不重不漏。
+ ## 分几个 commit
- ## 提交操作
+ - 默认全部放进一个 commit。只有改动里明显是互不相干的两件事,比如一个 bug 修复加一个无关的新功能,才分开。一件事改了多少文件、跨了多少目录都放一起。
+ - 一两行的清理(`.gitignore` 条目、拼写、格式)跟着最相关的 commit 走,message 里不提。
+ - 分开时每个 commit 单独看都要完整:改函数签名和它的调用点、改动和它的测试放在同一个。
+ - 一个文件里混了两件事,整个文件放进主要那边,不做文件内拆分。
- - `git add <路径…>` 逐组提交,全程不动工作区。禁 `git add -A`、`git commit -a`。
- - 禁止用 `git stash` / `git reset` / `git checkout` 来回倒腾着切割改动——这条路会走到 `git reset --hard` 丢数据(claude-code issue #14293),主流 commit skill 里也没人这么做。
- - 个人项目默认直接提交到当前分支;只有改动大或有风险、主分支受保护、或多人协作时,才先开分支。
+ ## 每个 commit
+ 1. `git add <路径…>`。不用 `git add -A`、`git commit -a`;不用 `git stash` / `git reset` / `git checkout` 切割改动,这条路会走到 `git reset --hard` 丢数据(claude-code issue #14293)。
+ 2. 查密钥,按顺序用第一个能用的:
+ - `gitleaks git --pre-commit --staged --redact --verbose --no-banner .`
+ - `docker run --rm -v "$PWD":/repo ghcr.io/gitleaks/gitleaks:v8.30.1 git --pre-commit --staged --redact --verbose --no-banner /repo`
+ - 都没有就自己把暂存的 diff 扫一遍。
+
+ 退出码 1 就停下,把查到的文件和行号告诉我,不提交。我确认是误报的,在那一行加 `gitleaks:allow` 注释再继续。
+ 3. 按下面的规则写 message 草稿。
+ 4. 调一次 `/flow:vet`,把草稿原文当参数传给它。按它的建议改 message;它标出的注释改在文件里,再 `git add`。改完就提交,不再调第二次。
+ 5. `git commit`。
+
## Message
- 格式和禁忌照我全局 `~/.claude/CLAUDE.md` 里的 commit 规范执行,这里不重复。
- - 先只看这一组的 diff 写草稿,写完再想有没有 diff 看不出的 why 要补。不要从对话出发写。
- - 每句话要同时满足两条:指向 diff 里某处改动,指不到的删;提供看 diff 得不到的 why,看 diff 就知道的删。
- - diff 外的信息只能是关于最终代码的 why(设计取舍、约束);对话过程、被否掉的中间版本、「为什么没有某东西」、会话待办的编号都不是。
- - body 按方面分段,空行隔开,每段 2 到 4 行,行宽 72 列(中文约 36 字),断行落在标点处。段与段讲同一件事的不同方面;哪一段讲的是另一件事,就拆成两个 commit。
- - 没有值得写的 why 就不写 body,单行 subject 完事,不要为了「像样」硬凑段落。版本号、顺带的清理这类看 diff 就知道的不写。
- - 每组 `git add` 之后、commit 之前调 `/flow:vet`,把草稿原文当参数传给它。按它标出的句子删改;注释的问题改在文件里再重新 `git add`。再调一次,直到它回「vet 通过」。
+ - 先只看这个 commit 的 diff 写,不要从对话出发。
+ - 每句话要指向 diff 里某处改动,并给出看 diff 得不到的 why;做不到的删。
+ - diff 外能写的只有最终代码的 why:设计取舍、约束,包括为什么选这个做法、而不选读者会想到的另一个。开发经过、试过又删掉的写法、会话待办的编号都不写。
+ - 没有值得写的 why 就只写 subject。
## 收尾
- - 提交前把分组方案 + 每条 message(都过了 vet 的)列给我看一眼。
- - 全部提交完跑一次 `git status` 核对,剩余改动必须是事先说好不提交的那些。
+ - 全部提交完,列出每个 commit 的 hash 和 subject,再跑一次 `git status`,剩余改动必须是参数范围外、本来就不提交的那些。
- 未经我明确同意不要 push。
-
- 带参数时只提交指定的那部分,其余不动。