generate-commit
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGenerate Commit
生成提交
Write a commit message for the changes the user staged, in this repo's conventional commit style, and commit after they approve it.
The index is the user's decision about what goes into this commit. Treat it as input, not something to rebuild. Everything below follows from that: inspect what is staged, check only that, and leave the rest of the working tree exactly as you found it.
针对用户暂存的更改,按照本仓库的 conventional commit 风格编写 commit message,并在用户批准后提交。
index 是用户对本次提交内容作出的决定。将其视为输入,而不是需要重新构建的东西。后续所有步骤都遵循这一点:只检查已暂存的内容,并将 working tree 的其余部分保持原样。
Step 1: Snapshot and inspect the index
第 1 步:记录并检查 index
bash
git status --short --untracked-files=all
git write-tree # prints a tree hash: remember it as ORIG_TREE
git diff --cached --stat
git diff --cachedORIG_TREEgit read-tree <ORIG_TREE>If something is staged, use that and only that. Do not run , , or . Unstaged edits and untracked files stay out of the commit, even when they look related. Mention them in one line ("README.md is modified but not staged; leaving it out") so the user can add them if they meant to.
git add -Agit add .git commit -aIf nothing is staged:
- With a clean working tree, say there is nothing to commit and stop.
- Otherwise list the modified and untracked files and ask whether to stage all of them, a subset, or none. Stage only after the user agrees, and stage the paths they chose (). Do not fall back to
git add -- <paths>silently.git add -A
bash
git status --short --untracked-files=all
git write-tree # prints a tree hash: remember it as ORIG_TREE
git diff --cached --stat
git diff --cachedORIG_TREEgit read-tree <ORIG_TREE>如果存在已暂存内容,只使用这些内容。不要运行 、 或 。即使未暂存的编辑和未跟踪文件看起来与本次改动相关,也必须将其排除在 commit 之外。用一行说明(“README.md 已修改但未暂存;将其排除在外”),以便用户在确有需要时自行添加。
git add -Agit add .git commit -a如果没有任何已暂存内容:
- 如果 working tree 干净,说明没有可提交的内容并停止。
- 否则,列出已修改和未跟踪的文件,并询问用户要 stage 全部文件、一个子集,还是不 stage。只有在用户同意后才执行 stage,并且只 stage 用户选择的路径()。不要在未说明的情况下退回到
git add -- <paths>。git add -A
Step 2: Check for files that should not be committed
第 2 步:检查不应提交的文件
Before staging anything, and again over the staged file list, flag files that look like secrets or scratch work. Look at names, at the content of small untracked files, and at the diff (not the whole file) of modified tracked files, so a README that mentions does not raise an alarm:
API_KEY- Names: ,
.env*,*.pem,*.key,id_rsa*,*.p12,credentials*,secrets*,*scratch*,*notes*.txt,*.log,*.tmp,*.bak, large binaries..DS_Store - Contents (for example ):
git diff --cached | grep -nEi '...',api[_-]?key,token,secret,password,BEGIN .*PRIVATE KEY,sk-[A-Za-z0-9-]+,AKIA[0-9A-Z]{16},ghp_[A-Za-z0-9]+.xox[bp]-
If a staged file matches, stop and ask before going on, and offer to unstage it (). If an unstaged or untracked file matches, warn in one line and keep it out of the commit. A false positive costs one question; a committed key costs a rotation.
git restore --staged -- <path>在 stage 任何内容之前,以及再次检查已暂存文件列表时,标记看起来像 secret 或临时文件的项。检查文件名、小型未跟踪文件的内容,以及已修改的受跟踪文件的 diff(而不是整个文件),这样 README 中提到 就不会引发警报:
API_KEY- 名称:、
.env*、*.pem、*.key、id_rsa*、*.p12、credentials*、secrets*、*scratch*、*notes*.txt、*.log、*.tmp、*.bak、大型二进制文件。.DS_Store - 内容(例如 ):
git diff --cached | grep -nEi '...'、api[_-]?key、token、secret、password、BEGIN .*PRIVATE KEY、sk-[A-Za-z0-9-]+、AKIA[0-9A-Z]{16}、ghp_[A-Za-z0-9]+。xox[bp]-
如果已暂存文件匹配其中一项,停止并询问用户是否继续,同时提供取消暂存该文件的选项()。如果未暂存或未跟踪文件匹配其中一项,用一行警告并将其排除在 commit 之外。误报只会多问一次;提交密钥则意味着必须进行轮换。
git restore --staged -- <path>Step 3: Run the project's lint on the staged files
第 3 步:对已暂存文件运行项目的 lint
The goal is to catch problems in this commit, not to clean up the repo.
-
Find the command CI actually runs. Read(or
.github/workflows/*.yml,.gitlab-ci.yml, a.pre-commit-config.yaml/Makefilejustfileorlinttarget, or thecheckinscripts). Use those commands with the project's runner (package.json,uv run,npm run, and so on). Do not guess a formatter the project has not adopted. A repo that runspnpmin CI has not opted intoruff check.ruff format -
Run it in check mode on the staged paths only:bash
git diff --cached --name-only --diff-filter=ACMR -- '*.py' | xargs uvx ruff checkThat example uses CI's ruff; substitute the project's own command and globs. Piping throughavoids shell word-splitting differences (zsh does not splitxargs). Filter that list to the file types the tool handles. When a tool cannot take a path list (for example$FILES), limit it to the affected packages or directories. When no lint is configured, say so and continue. Do not invent one.go vet ./... -
On failure, report it and ask. Show the findings with file and line. Note any that sit on lines this diff did not touch, since those existed before. Then let the user choose: fix the staged files, commit anyway, or abort. Never reformat the whole repo, and never fix files outside the staged set.
-
If the user asks you to fix, edit only the staged files, then re-stage those paths. If a file is partly staged (it shows in bothand
git diff), re-staging also picks up its unstaged hunks. Say so and ask before you re-stage it.git diff --cached
Do not run the full test suite by default; it is slow and does not change the message. Run tests only when the user asks or the project's requires them before every commit. Then run only the tests related to the staged files and report the results.
CONTRIBUTING.mdDo not write the lint command, or anything else, into , , or any other tracked file. This skill changes nothing except the commit.
CLAUDE.mdAGENTS.md目标是发现本次提交中的问题,而不是清理整个仓库。
-
找出 CI 实际运行的命令。 阅读(或
.github/workflows/*.yml、.gitlab-ci.yml、.pre-commit-config.yaml/Makefile中的justfile或linttarget,或者check中的package.json)。使用项目的 runner 执行这些命令(scripts、uv run、npm run等)。不要猜测项目尚未采用的 formatter。一个在 CI 中运行pnpm的仓库,并不表示它已选择使用ruff check。ruff format -
仅以 check mode 对已暂存路径运行它:bash
git diff --cached --name-only --diff-filter=ACMR -- '*.py' | xargs uvx ruff check该示例使用 CI 中的 ruff;请替换为项目自己的命令和 glob。通过管道传给可以避免 shell 的 word-splitting 差异(zsh 不会拆分xargs)。将列表过滤为该 tool 能处理的文件类型。当某个 tool 无法接受路径列表时(例如$FILES),应将其限制在受影响的 package 或 directory。如果项目未配置 lint,就说明这一点并继续。不要自行虚构一个命令。go vet ./... -
失败时,报告问题并询问用户。 展示包含文件和行号的检查结果。指出位于本次 diff 未触及行上的问题,因为它们在改动前就已存在。然后让用户选择:修复已暂存文件、仍然提交,或中止。绝不要重新格式化整个仓库,也绝不要修复已暂存集合之外的文件。
-
**如果用户要求修复,**只编辑已暂存文件,然后重新 stage 这些路径。如果某个文件只有一部分已暂存(它同时出现在和
git diff中),重新 stage 也会把未暂存的 hunks 一并加入。务必说明这一点,并在重新 stage 之前征求同意。git diff --cached
默认不要运行完整 test suite;它速度慢,而且不会改变 commit message。仅当用户要求,或项目的 要求每次 commit 前运行测试时,才运行测试。然后只运行与已暂存文件相关的测试并报告结果。
CONTRIBUTING.md不要将 lint 命令或任何其他内容写入 、 或其他受跟踪文件。除本次 commit 之外,此 skill 不应进行任何更改。
CLAUDE.mdAGENTS.mdStep 4: Learn the repo's conventions
第 4 步:学习仓库的约定
bash
git log --format=%s -30Read the types and scopes this repo actually uses, for example , , , . Prefer them over any generic list. When the history is not conventional, use the standard types: , , , , , , , , , , . Skim for commit rules if it exists. Rules there override this skill.
docs(adr):ci:test(fitness-config):fix(fitness-config):featfixdocsstylerefactorperftestbuildcichorerevertCONTRIBUTING.mdScope: reuse a scope the log already uses for these files (check for a staged path). If none fits, use the most specific module or directory that covers every staged file, or leave the scope out. Never join several scopes into one, such as .
git log --format=%s -- <path>ci,docs,scriptsbash
git log --format=%s -30读取仓库实际使用的 type 和 scope,例如 、、、。优先使用这些约定,而不是任何通用列表。如果历史记录不遵循 conventional commit,则使用标准 type:、、、、、、、、、、。如果存在 ,快速浏览其中的 commit 规则。该文件中的规则优先于本 skill。
docs(adr):ci:test(fitness-config):fix(fitness-config):featfixdocsstylerefactorperftestbuildcichorerevertCONTRIBUTING.mdScope: 对这些文件复用日志中已经使用的 scope(针对某个已暂存路径检查 )。如果没有合适的 scope,就使用能够覆盖每个已暂存文件的最具体 module 或 directory,也可以省略 scope。绝不要把多个 scope 合并成一个,例如 。
git log --format=%s -- <path>ci,docs,scriptsStep 5: Check whether the diff is one change
第 5 步:检查 diff 是否只包含一项改动
When the staged files serve unrelated purposes (for example a CI timeout, a docs fix, and a new script feature), say so before writing the message. Propose a split: one commit per concern, with the files for each and a draft subject for each. Then ask whether to:
- Split. Unstage everything (). For each group, stage that group's paths, confirm the message, and commit. When done, the index holds nothing the user had not staged. If a single file mixes concerns, say so; splitting it needs
git restore --staged -- ., which the user has to do themselves.git add -p - Commit together. Write one message whose body lists every concern.
A change and its own tests, docs, or config are one concern, so do not suggest splitting those.
当已暂存文件服务于互不相关的目的时,例如 CI timeout、文档修复和新的 script 功能,应在编写 message 前说明这一点。提出拆分方案:每个 concern 一个 commit,并列出每组文件以及每个 commit 的 subject 草案。然后询问用户是否:
- 拆分。 取消暂存全部内容()。对每一组,stage 该组的路径,确认 message,然后 commit。完成后,index 中不应包含用户未曾暂存过的任何内容。如果单个文件混有多个 concern,说明这一点;拆分该文件需要
git restore --staged -- .,必须由用户自行完成。git add -p - 一起提交。 编写一条 message,其 body 列出每个 concern。
某项改动及其配套的 tests、docs 或 config 属于同一个 concern,因此不要建议拆分它们。
Step 6: Write the message
第 6 步:编写 message
text
type(scope): imperative summary of the change
Optional body: what changed and why, wrapped at 72 columns.
Use bullets when there are several distinct points.- Start the subject with an imperative verb ("add", "fix", "accept"), not "added" or "fixes". Keep it at 72 characters or fewer, and do not end it with a period.
- Add a body when the subject cannot say why the change was made, when it covers more than one point, or when the change is breaking. Leave it out for small, self-explanatory changes.
- Mark breaking changes with after the type or scope and a
!footer.BREAKING CHANGE: - Do not add , "Generated with", or any model or tool name. It adds noise to the history. If the user's own instructions require a trailer, follow them.
Co-Authored-By
text
type(scope): imperative summary of the change
Optional body: what changed and why, wrapped at 72 columns.
Use bullets when there are several distinct points.- subject 以祈使动词开头(“add”、“fix”、“accept”),而不是 “added” 或 “fixes”。将其控制在 72 个字符以内,且末尾不要加句号。
- 当 subject 无法说明为何进行改动、涵盖多个要点或属于 breaking change 时,添加 body。对于规模较小且不言自明的改动,可以省略 body。
- 在 type 或 scope 后添加 来标记 breaking change,并添加
!footer。BREAKING CHANGE: - 不要添加 、“Generated with” 或任何模型或 tool 名称。这会给历史记录带来噪声。如果用户自己的指令要求某个 trailer,则遵循该指令。
Co-Authored-By
Step 7: Present for review
第 7 步:提交审阅
Show the full message, the list of files it will commit, and any warnings from Steps 1-3. Then ask with AskUserQuestion:
- Use as-is: commit with this message.
- Edit: take the user's revised message and commit with it.
- Abort: no commit, and the index is restored.
展示完整 message、将要提交的文件列表,以及第 1 至第 3 步中的任何 warnings。然后使用 AskUserQuestion 询问:
- 原样使用:使用这条 message 提交。
- 编辑:采用用户修改后的 message 并提交。
- 中止:不提交,并恢复 index。
Step 8: Commit or abort
第 8 步:提交或中止
Commit with a HEREDOC so the body and line breaks survive:
bash
git commit -F - <<'EOF'
type(scope): subject
Body.
EOF- Let hooks run. Never pass . If a pre-commit hook fails or rewrites files, show its output and go back to Step 3. Do not retry blindly.
--no-verify - After committing, run and confirm that the files the user left unstaged or untracked are still there and still uncommitted.
git status --short - On abort: run to put the index back exactly as the user left it, including anything they had staged. Do not use
git read-tree <ORIG_TREE>, which also unstages their own staging. Undo any lint fixes you made only if the user asks. Then print "Aborted: no commit created; staging restored."git reset HEAD
使用 HEREDOC 提交,以保留 body 和换行:
bash
git commit -F - <<'EOF'
type(scope): subject
Body.
EOF- 让 hooks 正常运行。绝不要传入 。如果 pre-commit hook 失败或重写了文件,显示其输出并返回第 3 步。不要盲目重试。
--no-verify - 提交后,运行 ,并确认用户留下为未暂存或未跟踪的文件仍然存在,且仍未提交。
git status --short - 中止时: 运行 ,将 index 恢复为用户离开时的确切状态,包括用户已经暂存的任何内容。不要使用
git read-tree <ORIG_TREE>,因为它也会取消用户自己的暂存。只有在用户要求时才撤销你做出的 lint 修复。然后输出“已中止:未创建提交;暂存状态已恢复。”git reset HEAD
Constraints
约束
- Never commit without explicit confirmation.
- Never stage files the user did not stage or approve.
- Never edit files outside the staged set, and never edit or other agent notes as a side effect.
CLAUDE.md - Never push.
- 未获明确确认,绝不提交。
- 绝不 stage 用户未 stage 或未批准的文件。
- 绝不编辑已暂存集合之外的文件,也绝不因副作用而编辑 或其他 agent notes。
CLAUDE.md - 绝不 push。