- AI 应用
- CLI
- 开发工具
【免费下载链接】ccusage
npx ccusage
本篇文章深入解读 ccusage 仓库内置的commit技能(.agents/skills/commit/SKILL.md),完整还原这套由仓库维护者沉淀的提交规范:如何用git apply --cached以 hunk 粒度暂存补丁、如何保证每个提交可独立回滚、如何撰写符合 Conventional Commits 规范的 subject 与 body,以及commit-msghook 如何依据暂存路径自动校验 scope。读完本文,你将掌握一套可以直接复用的原子化提交方法论,并理解 ccusage 仓库从「提交 → 推送 → PR → CI 校验」全链路的工程约束。
技能定位:何时触发 commit 技能
在 ccusage 的 Agent 技能体系中(路由清单见 AGENTS.md),commit技能负责「原子化 Conventional Commits 与基于补丁的暂存」,其前置声明(frontmatter)明确了三类触发场景:
- 提交代码变更;
- 将一个 diff 拆分成多个可独立回滚的 hunk;
- 以非交互方式暂存精确的补丁,或编写提交信息。
技能支持一个可选参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
push | false | 提交完成后是否立即推送,置为true时执行推送流程 |
典型调用方式是/commit与/commit push=true。注意,这条技能不是普通文档,而是仓库内 Agent(如 Claude Code)在提交时会按需加载的「任务期指令」,其信息组织遵循「渐进式披露」原则——根级 AGENTS.md 只保留路由与全局策略,具体工作流全部下沉到技能文件。
工作流全解析:从状态读取到确认提交
技能定义的四步工作流,每一步都服务于「原子且可回滚」这个核心目标。
第 1 步:读取状态与近期历史
git status --short git diff HEAD git log --oneline -10这一步的目的不只是弄清改了什么,而是匹配仓库日志中已有的粒度、scope 与解释风格。ccusage 采用 Rust 优先的多适配器仓库结构(rust/adapters/<agent>对应不同编程 Agent),提交历史中的 scope 习惯(如fix(kimi)、feat(codex))本身就是后续 scope 校验的依据来源。
第 2 步:按 hunk 而非按文件拆分 diff
拆分单位是「hunk」(补丁块)而不是「文件」——一个文件中可能同时包含多个不相关的逻辑变更,应当被拆成多个提交。这为第 3 步的精确暂存奠定基础。
第 3 步:用 git apply 非交互式暂存
git apply --cached -v <patch>技能明确解释了为什么必须用补丁:git add -p与git add --interactive在仓库的 Agent 运行环境中会挂起(hang),因此补丁是唯一能只暂存文件一部分内容的方式。当补丁应用失败时,需要阅读 .agents/skills/commit/references/git-apply.md 参考文档,其中给出了完整的补丁应用工具箱:
| 场景 | 参数 | 说明 |
|---|---|---|
| 应用前预检 | git apply --check <patch> | 先验证补丁能否干净应用 |
| 查看受影响文件 | git apply --stat <patch> | 应用前列出将改动的文件 |
| 尾随空白导致失败 | --whitespace=fix | 自动修正空白问题 |
| 部分 hunk 冲突 | --reject | 写入.rej文件而非整体中止 |
| 上下文不匹配 | --ignore-whitespace | 忽略空白差异 |
| 行尾不一致 | --ignore-space-change | 忽略空格数量差异 |
| 撤销已应用补丁 | --reverse | 反向应用以撤销 |
始终保留-v参数,这样失败时能明确指出是哪个 hunk 被拒绝。
第 4 步:提交并确认
提交完成后用git show HEAD复核,确认提交内容与预期一致。
Revertability:可回滚性是提交质量的第一标准
技能的「Revertability」章节给出了一个自检问题:
如果我单独回滚这个提交,会不会破坏别的东西?
每个提交都必须能独立回答这个问题。仓库期望极小的提交(tiny commits):一条 review 意见、一处措辞修正、一次参考文件抽取,都可以各自成为一个提交。
但「小」不等于「部分」。技能特别区分了两种操作:
- 微提交:一个提交只含一个关注点;
- 移动/重命名/抽取:必须作为单个提交一次性落地,同时包含「旧路径删除、新路径添加、引用更新、生成的链接同步」两侧内容,避免提交处于半完成状态。
此外,不同的关注点必须分开提交——即便每个改动本身都是正确的,合并提交也会导致回滚一个关注点时误伤无关工作。
仓库的 PR 合并策略是 squash-merge(见 .agents/skills/create-pr/SKILL.md 与 AGENTS.md),因此review 修复应作为后续跟进提交堆叠(stack),而不是 amend 历史。git commit --amend仅限两类情况:尚未发布的本地失误,或用户明确要求。这一约定与 CONTRIBUTING.md 中「PR branches are squash-merged, so prefer small stacked follow-up commits」的表述完全一致。
Messages:subject 与 body 的分工
提交信息规范的核心是职责分离:
- subject(主题行):命名被改变的工件或行为,并且在提交列表中单独阅读时必须通顺。技能给出的对比示例极具说明性:
docs(skills): clarify reference routing(body 引用 CodeRabbit 反馈)优于chore: address review feedback——前者说明「改了什么、为什么」,后者只是描述动作本身。 - body(正文):面向 reviewer 的上下文,在 72 列处换行,覆盖问题(problem)、理由(rationale)、决策(decisions)与影响(impact)四个方面。
commit-msg hook 与 scope 校验
提交信息的最后一道防线是commit-msghook,它运行 scripts/validate-commit-scope.nu。该脚本的核心规则:
- 当暂存路径位于
rust/adapters/<agent>/下时,scope 必须是该 Agent 名(如fix(kimi))、跨领域 scope,或(当变更跨越多个 Agent 时)工作区级 scope; rust/adapters/common/派生出的 scope 是adapter而不是common;- 仓库中没有任何其他路径会派生 scope,其余变更的 scope 由作者自行选择。
之所以要依据暂存路径校验而不是信任 subject,脚本头部注释解释得很清楚:仅看 subject 无法识破编造的 scope——feat(coding)单独读起来完全合理,直到你发现实际改动的是 codex 的代码。因此它从git diff --cached --name-only读取所有权信息。
格式纯格式化的变更是chore: format;当 scope 规则适用时则为chore(<scope>): format。所有提交信息使用美式英语。
scope 校验脚本的源码级实现
从 scripts/validate-commit-scope.nu 的实现可以看出完整的校验逻辑:
- 白名单常量(第 15-22 行):
CROSS_CUTTING_SCOPES = [deps, release, pricing, revert](描述变更原因而非树的一部分)、WORKSPACE_SCOPES = [adapter, all, rust](仅当一次变更跨越多个 Agent 时额外接受),以及 git 自动生成或后续重写的前缀["Merge ", "Revert ", "fixup!", "squash!", "amend!"](这些前缀不要求 scope); - subject 解析:用正则
^(?<type>[a-z]+)(?:\((?<scope>[^()]+)\))?!?: \S拆分类型与可选 scope; - 路径归属映射(
owner-for-path):只有rust/adapters/*参与映射——rust/adapters/common/*映射为adapter,adapters/下带点的文件被视为文件而非 Agent,其余路径返回null不参与推导; - 三种裁决分支:无适配器路径变更 → 作者自选 scope 成立;单个归属 → scope 必须为该 Agent 名或跨领域 scope;多个归属 → 必须取其中一个 Agent 名或覆盖全部的工作区 scope;
- 违规时通过
reject打印普通错误信息并exit 1中止提交,故意不用error make——后者会把信息埋在 Nushell 诊断输出里,再被 git 缩进成噪音。
Push:功能分支 + 上游检查 + 全套 hooks
由于main只能通过 PR 合入(squash-merge),提交必须发生在功能分支上。/commit push=true触发推送流程时,需要先阅读 .agents/skills/commit/references/push.md:
# 1. 确认当前分支:在 main/master 上必须停下,先切到功能分支 git branch --show-current # 2. 检查是否有上游 git rev-parse --abbrev-ref --symbolic-full-name @{u}- 有上游:直接
git push; - 无上游:先询问用户是否执行
git push -u origin HEAD,用户拒绝则跳过推送。
推送后由 nix/git-hooks.nix 中配置的 hooks 接力校验,失败属于正常验证流程的一部分——在新提交中修复,而不是改写历史。按触发时机划分:
| 阶段 | hook | 校验内容 |
|---|---|---|
| pre-commit | treefmt | 全树格式化(--no-cache避免 prek 并行调用时的缓存竞争) |
| pre-commit | gitleaks protect | 对暂存内容做密钥扫描 |
| commit-msg | commit scope | 运行nushell scripts/validate-commit-scope.nu校验 scope |
| pre-push | treefmt-check | --fail-on-change确认无未格式化文件 |
| pre-push | gitleaks detect | 全量密钥检测 |
| pre-push | oxlint | TypeScript/JavaScript 静态检查 |
| pre-push | clippy | Rust 工作区clippy -D warnings(警告即错误) |
| pre-push | node test | Node 内置测试运行器执行 apps/ccusage/src/cli.test.ts 与 nix/tools/models-dev-gen/compact.test.ts |
| pre-push | cargo test | 整个 Rust 工作区全目标测试 |
可见,一次push=true的提交会触发从格式、密钥、Lint 到全量单测的完整验证链;任何一个环节失败,正确的应对都是追加一个小型修复提交,这正与「tiny commits」与「不 amend 已发布历史」的规范互相印证。
与其他技能的分工
commit技能只是仓库 Agent 工作流的一环,它和周边技能形成清晰的职责边界:
- .agents/skills/create-pr/SKILL.md:负责分支、推 PR、AI review、CI 跟进与合并(
gh pr merge <pr> --squash --delete-branch),其内部明确「提交来自 commit 技能,所以保持原子且可独立回滚」; - .agents/skills/skill-creator/SKILL.md:规定了技能文件的组织方式——
SKILL.md保持 160 行以内、条件性细节下沉到references/*.md,这正是 commit 技能将 git apply 与 push 细节拆成两个参考文件的原因; - .agents/skills/fix-ci/SKILL.md:负责修复 CI 失败,与提交 hook 失败后的修复流程衔接。
总结
ccusage 的commit技能是一套可独立迁移的提交工程规范,其要点可以浓缩为五条:
- hunk 级拆分:用
git apply --cached -v而非交互式命令暂存部分内容; - 可回滚性优先:每个提交都要能单独回滚且不破坏其他东西,移动/重命名类操作则整体单提交落地;
- subject 命名工件、body 交代背景,72 列换行,美式英语;
- scope 由暂存路径推导:
commit-msghook 依据scripts/validate-commit-scope.nu强制rust/adapters/<agent>下的提交使用真实 Agent 名作 scope; - 功能分支 + squash-merge:review 修复用堆叠跟进提交,不 amend 已发布历史,推送后接受 treefmt、gitleaks、oxlint、clippy 与全量测试的逐层校验。
这套规范之所以值得借鉴,在于它把「代码可回滚性」这一工程原则落到了提交粒度、暂存工具、信息格式与自动化 hook 的每一个环节上——对于任何多 Agent、多适配器、多人协作的仓库,都是一份现成的高质量蓝本。
- AI 应用
- CLI
- 开发工具
【免费下载链接】ccusage
npx ccusage
相关推荐
Theatre Git提交规范:Conventional Commits实践
Theatre Git提交规范:Conventional Commits实践 你是否还在为项目提交历史混乱而烦恼?团队协作时看不懂同事的提交意图?本文将详细介绍
前端ECC Git 工作流规范:Conventional Commits 提交约定与高质量 Pull Request 实战指南
ECC Git 工作流规范:Conventional Commits 提交约定与高质量 Pull Request 实战指南 导读 本文面向在 ECC(Effic
人工智能AI 技能AI 插件AI 评测Agent 评测MCP Clients开发工具终极指南:如何用Conventional Commits规范化你的Git提交信息
终极指南:如何用Conventional Commits规范化你的Git提交信息 Conventional Commits规范是一种轻量级的提交信息约定,它为创
文档
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考