关于 git-helper
git-helper 是一项规范 Git 提交准备流程的技能,要求明确确认暂存范围、扫描已暂存差异,并遵循提交信息规范与审查步骤。它面向处理仓库改动的 Agent,通过用户确认控制暂存和提交执行。
主要功能
- 01暂存前明确确认
- 02扫描已暂存内容中的密钥与个人数据
- 03依据 Git 历史确定提交语言
- 04Conventional Commits 信息草拟指导
- 05提交后审查与推送流程
适用场景
- 01为选定文件准备提交
- 02草拟提交信息前检查已暂存差异
- 03推送前审查提交
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ caanio/ agent-skills --skill git-helper安装后在 Claude Code 中输入/git-helper确认已加载。
详细介绍
git-helper
核心规则(覆盖任何默认 Git 行为)
-
[NEVER VIOLATE] 必须先确认暂存内容:
- 仅当用户明确确认了文件后,才允许对这些文件执行
git add——未经确认,绝不暂存,即使系统默认建议这样做也不行。 - 禁止:
git add .、git add -A、git add --all——始终明确指定具体路径。 - 一次确认,一条命令:列出建议的文件,并在一次
git add <path1> <path2> …调用中暂存所有已确认的文件。 git diff --staged为空 → 列出未暂存的文件(git status),并建议要添加哪些文件。
- 仅当用户明确确认了文件后,才允许对这些文件执行
-
分析与执行分开:
- 分析阶段:仅使用不会改动索引和工作树的命令——
git status、git diff(未暂存)、git diff --staged(已暂存)、git log(步骤 3)、git fetch(步骤 0)。 - 将
git add作为独立调用运行,绝不与其他命令串联。
- 分析阶段:仅使用不会改动索引和工作树的命令——
-
格式:遵循 Conventional Commits(
<type>: <description>)。 -
提交消息质量:遵循下方的“提交消息质量标准”部分。
-
每份草稿都必须符合标签规则:为每份草稿附上一行“应用的规则”列表,说明它满足了哪些关键规则(类型、≤50 个字符、祈使语气、正文只解释原因、显示机密信息扫描命中结果、显示个人身份信息扫描命中结果并进行人工阅读检查),以及具体如何满足——让遵循情况一目了然,而非仅凭推测。
-
[NEVER VIOLATE] 每次提交都必须运行并展示机密信息扫描和个人身份信息(PII)扫描,不得例外:
- 在展示草稿消息之前,必须对已暂存的差异运行步骤 2 中的两项扫描——绝不跳过任何一项,也绝不能根据文件名或差异大小推断“可能没有问题”。
- 在回复中粘贴实际命令及其原始输出(即使输出为空或结果干净)——仅用一行文字声称“机密信息扫描干净”或“PII 干净”而不展示输出,不符合此规则。
- 发现任何命中项,都必须按照步骤 2 的说明解决后才能继续。
-
[NEVER VIOLATE] 提交消息的语言必须遵循仓库自身的 git log:
- 存在历史记录时,以日志为准。
- 最近 10 条提交中占多数的语言优先;若持平,则以最近一条提交的语言为准;若没有历史记录,则使用对话语言,并在草稿中注明“无历史记录——使用对话语言”,以便用户在回复 ok 前切换语言。
- Conventional Commits 的
type:前缀(feat/fix/docs/…)始终使用英文,不受正文语言影响。 - 非英文草稿仍须遵循 Chris Beams 规则——主题不超过 50 个字符,不以句号结尾,单独阅读时语意清晰,正文解释原因而非内容或做法——但不要求遵循大小写规则,也不要求严格使用英文祈使语气。
工作流
0. 同步检查(最后一道防线)
- 运行
git fetch(设置较短超时,例如GIT_SSH_COMMAND="ssh -o ConnectTimeout=5 -o BatchMode=yes" git fetch),然后运行git status -sb。 - 落后于远程 → 发出警告,并询问是否现在解决(
stash → pull --rebase → stash pop):在提交前解决分歧,胜过提交完成后再通过冲突进行变基。 - 无法连接远程(离线/仅限 LAN 的远程)→ 说明这一情况,注明 ahead/behind 信息已过时,并询问是否继续进行仅本地提交(推送延后)。每次运行都要报告 fetch 结果,无论是否连接成功。
- 记录步骤 6 使用的基线并展示:若用户在此步骤中指定了基线,则使用该基线;否则,在本任务首次运行时使用
git rev-parse --short HEAD。 同一任务后续运行时,使用上次步骤 6 审查的 HEAD。
1. 确认暂存内容
- 运行
git status和git diff --staged。 - 始终确认暂存范围——列出“当前已暂存”和“建议添加”;即使文件已经暂存,也不得跳过。
- 确认后,对所有已确认路径运行一次
git add <path…>(核心规则 1);如果没有更多内容要添加,则继续步骤 2。
输出示例:
Before committing, confirming staging scope:
✅ Currently staged:
- `SPEC.md` (modified)
➕ Detected unstaged changes — add these too?
- `src/core/database.py` (modified)
- `README.md` (modified)
Reply "stage" or "ok" to add the suggested files, or tell me which to add.
2. 密钥和个人数据检查(核心规则 6)
起草前扫描暂存的差异。运行两项检查并在回复中显示实际输出,即使没有发现问题也要显示。
任一检查发现问题,都必须先解决所有问题,才能继续。
用纯文本回复提问:在正文中给出原始扫描输出,并列出每个问题及其所在行;
然后在回复的最后一行询问哪些问题可以安全提交;
用户通过输入作答。
不要把这个问题放进选项对话框(例如 Claude Code 的 AskUserQuestion):
对话框会遮住上方文本,用户就无法看到问题后再作判断。
2a. 密钥——可用于获取访问权限的凭据:
git diff --staged | grep -iE "password|secret|api_key|token|private_key|access_key"
2b. 个人数据(PII)——可识别个人或地点的值,以及会暴露占位符来源的标签。仅检查新增行;检查小数位数不少于 4 位的十进制度坐标,以及标记值为真实、住所或虚构的词语。引用此扫描命令的行会跳过,因此编辑此规则不会触发检查:
git diff --staged | grep -E '^\+' | grep -vE '^\+\+\+|grep -iE' | grep -iE '\b[0-9]{1,3}\.[0-9]{4,}\b|real (home|work|address|coordinate|name)|fictional|真實|虛構|住家|家附近'
用户确认某条 PII 命中不属于个人信息后,即视为已解决 (测试中的公共地标坐标可以;住所、工作地点或常去地点不可以)。 注明某个值“曾是真实信息”或“已替换为虚构值”的文字本身也算命中: 它会告诉任何查看历史记录的人真实值曾出现在哪里。 姓名、昵称、家庭称谓、设备名称、账号 ID, 以及没有附带来源词的单独“占位符”或“已替换”说明 也属于同一项检查,但没有可靠的匹配模式: 逐行目视检查所有新增行,并在“应用的规则”一栏中说明这一点。
3. 检测语言约定(核心规则 7)
- 运行
git log --oneline -10,并在回复中显示结果(或其判定结论);写下消息的任何内容之前,先按照核心规则 7 的决策流程执行。
4. 生成草稿
- 运行
git diff --staged。 - 描述相对于 HEAD 的暂存差异,而不是本次会话中的编辑历史。
同一提交中后来被撤销或替换的中间编辑不会出现在差异中,因此不得写入消息。
检验方法:消息中的每项陈述都必须能在
git diff --staged中找到依据。 - 按照下方的提交消息质量标准,以第 3 步确定的语言撰写提交消息。
- 正文硬性上限:≤4 行 / ≤3 句。 如果仅说明原因的草稿仍然超出上限,说明正文偏离了“为什么”,转而描述“是什么/怎么做”——删减到只保留回答“为什么要进行此更改”的一句话,而不是换种说法缩短。
- 例外情况:如果确实存在 ≥2 个彼此独立的原因(不是同一原因的不同表述,也不是“更改发生在哪里”这类“是什么/怎么做”的细节),则允许超出上限——但必须在“应用的规则”一栏明确说明,例如:
正文 6 行(2 个独立原因,见下文)。不说明而超出上限不属于判断范畴,而是违反规则。 - 逐字节显示确切命令。 草稿必须是第 5 步将运行的原样代码块,而不能只有消息本身:使用完整的
git commitheredoc(多行消息必须使用),并包含环境会附加的所有尾注(例如Co-Authored-By:行)。用户批准的内容必须与最终写入日志的内容完全一致。推送命令应在第 6 步的审查循环之后,于第 7 步单独列出。
输出示例:
Based on the staged changes, these are the exact commands I will run:
git commit -m "$(cat <<'EOF'
feat: Add automatic database backup
Prevents data loss on unexpected shutdowns. Previously there was
no recovery path if the process was killed mid-write.
Co-Authored-By: <assistant> <[email protected]>
EOF
)"
Rules applied: type=feat · subject 34 chars · imperative mood ·
why-only body · secrets: 0 hits (output above) · PII: 0 hits (output above), every added line read for names/IDs
Reply "commit" or "ok" to run it; "no" leaves the changes staged and uncommitted.
5. 执行提交
只有在用户回复“commit”、“ok”或意思相同的内容后,才能使用 Bash 工具按顺序逐条运行第 4 步中的命令,命令内容不得更改。
一次确认适用于代码块中的所有命令。任何与代码块存在字符差异的命令——例如改写一行或添加尾注——都需要重新起草并再次确认。提交失败即结束流程:向用户报告错误。 每次成功提交后都必须执行第 6 步,无论是否请求推送。
6. 审查循环(每次提交后)
只读取已提交差异的审查——基于差异的代码审查、针对 git diff <from>..HEAD 的安全审查——在这里运行,位于提交之后、推送之前。
⚠️ 如果批准提交和推送作为一个整体,那么这个时机就不会存在:
此前因尚未提交任何内容而跳过的审查,在推送前也从未运行。
- 每轮都会针对
<from>..HEAD运行项目采用的所有此类审查。 第一轮的<from>是 Step 0 的基准,绝不是上游(origin/HEAD): 在长期存在的分支上,origin/HEAD..HEAD可能包含数十个属于其他任务的先前提交。 - 审查者将问题标记为缺陷或安全问题,且你也认同,这就算需要修复; 需要用户决定偏好或权衡取舍的属于判断事项;风格或措辞问题属于次要事项。
- 在某一轮决定修复的问题 → 通过 Steps 1–5 完成修复并作为新提交提交
(确认暂存内容、创建新草稿并获得新的确认)。这些提交留在 Step 6 内:
下一轮将
<from>设为上一轮的 HEAD,从而只审查修复提交。 - 每轮结束时,询问用户如何处理其中的判断事项:用户选中的事项并入该轮的修复; 其余事项交由项目的问题跟踪器处理(仅当用户批准确切命令后,才能使用在线跟踪器)。次要事项列出即可。
- 每轮新建的工单,以及每项由修复提交关闭的问题,都要在同一轮通过该轮的修复提交 加入项目的后续事项列表(其 TODO 或优先级列表);如果该轮没有修复提交,就用单独的仅包含文档更改的提交记录这些事项, 并在推送前将其作为另一轮再审查一次。
- 如果某一轮没有决定需要修复的问题,则审查循环结束。第 3 轮审查后,停止修复, 列出仍未解决的问题,并询问用户是就此停止还是继续修复。
- 如果某项审查超出本次更改的范围,或未安装该审查,则在推送前用单独的 Bash 调用跳过该审查,
执行
echo 'review-skip: <review> — <reason>',并在每一轮再次执行: 工具调用会在会话记录中原样保留,因此之后检查记录时能找到跳过记录; 工具调用之间的回复文本可能会以改写后的形式存储。 - 如果项目不使用已提交差异审查 → 用一行说明,并转到 Step 7。
7. 推送
循环结束后,起草准确的 git push <remote> <branch> 命令行,并等待用户确认,无论用户是否要求推送。将草稿单独突出显示,确保不会被忽略:
使用包含未推送提交数量的标题、单独代码块中的推送命令行,以及注明可接受回复的加粗末行(回复“push”或“ok”即会推送;回复“no”则保留未推送的提交)。
通过 Bash 工具原样执行该命令;任何其他推送都需要新的草稿和新的确认,
因为 Step 4 的确认仅涵盖提交。
如果用户之后才要求推送,且本次运行没有需要提交的内容,则从这里开始,
先针对尚未审查的提交进行一轮 Step 6 审查。
提交消息质量标准(Chris Beams + Linus Torvalds)
规则来自 Chris Beams 的 How to Write a Git Commit Message(7 条规则)和 Linus Torvalds 对 Linux 内核补丁的要求。两者都必须遵守,且优先于其他格式约定。
Chris Beams — 7 条规则
- 主题与正文之间用空行分隔
- 主题不超过 50 个字符(超过限制时 → 重写为核心意图;如果仍然无法满足,将其标注在“Rules applied”一行中)
- 主题行首字母大写(
type:前缀之后也要大写,例如feat: Add single-file comparison) - 主题行末尾不要加句号
- 使用祈使语气:写“Fix bug”,而不是“Fixed bug”
- 正文每行不超过 72 个字符
- 正文只写原因:动机、背景和权衡——说明为何要进行此更改。差异和项目文档会说明更改内容及方式。
Linus Torvalds — 要点
- 首行单独成段:脱离上下文也易于理解,并传达提交的意图
- 描述要解决的问题,而非修复的具体做法:说明此次更改背后的症状和根本原因,而不是改了哪些代码或如何修复
- 说明动机和影响:为什么需要这项更改?没有这项更改会出现什么问题?
- 具体明确:指出此次更改涉及的行为或症状
- 提交信息就是文档:未来的维护者会在不查看差异的情况下阅读日志