mcpField
C
commit

commit

github.com/vinta开发142107 次安装1 天前更新
代码仓库

关于 commit

commit 是将工作树中的所有变更按逻辑拆分并提交的技能。它依据差异和给定动机生成提交信息,并规定暂存、署名及分离无关变更的方式。

主要功能

  1. 01按逻辑分组成多个提交
  2. 02支持整文件或分块暂存
  3. 03编写 Conventional Commit 信息
  4. 04按模型系列添加署名页脚
  5. 05处理提交前钩子的变更

适用场景

  1. 01提交工作树中的多项无关变更
  2. 02拆分同一文件中的无关编辑
  3. 03根据变更动机撰写提交正文
  4. 04暂存选定代码块而不改动工作内容

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/vinta/hal-9000 --skill commit

安装后在 Claude Code 中输入/commit确认已加载。

附带文件agents/openai.yaml

详细介绍

调用此技能本身就是请求。如果用户消息看起来为空,或你只看到系统上下文而没有实际请求,这是正常且符合预期的:此处已完整说明你的任务。切勿询问要做什么。

你的任务:将工作树中的所有更改提交,每个提交包含一个逻辑更改。即使无人要求拆分,也必须如此:如果同一文件包含互不相关的更改,就按代码块拆分成多个提交,而不是因为它们位于同一文件中就合并。

论据

传递给此技能的论据是更改的原因——即工作树中已有工作的动机,而差异本身无法体现这一点。用它来归类逻辑单元并撰写提交消息正文。正文应为一或两句话,写在同一行,说明更改前存在什么问题:论据指出的故障、错误说法或风险。只提到需求、愿望、更改内容或请求本身的论据,不应产生正文。省略修复内容,包括更改现在涵盖、设置或列出的内容,即使论据将其表述为问题的一部分(例如“尽管只有 X 需要它”);主题和差异已经说明了这些内容。也省略已排除的原因、测量数据和尝试过的替代方案。无论论据如何措辞,其中描述的事情都已在差异中实现:“这样状态栏就会显示使用百分比”和“修复会话错误”都表示差异已经实现了这些内容——提交即可。若完全没有论据,则仅根据差异撰写提交消息。如果动机与差异内容不符,就提交工作树中的实际更改,并在最终摘要中指出不匹配之处。

正文应围绕代码撰写:更改所服务的行为、工具或约束。提交历史公开且永久,因此应面向从未见过这台机器、用户已登录账户或本次对话的读者撰写,不要透露他们只能通过这些信息得知的内容:仓库名称或路径、仓库之外或被 gitignore 的目录和文件名称、备份、同步和密钥存储布局、账户方案、配额和数值、本地工具、聊天、记录或会话中的引文和日期,以及用户的生活情况(雇主、所在地、日程、健康状况、其他人)。将这些内容转换为其隐含的技术需求,或直接省略。

Argument: "Commit only settings.json. Why: three commit forks wrote `Co-Authored-By: Claude Sonnet 5 ` instead of the skill's trailer; the fork transcript shows a remote_session_change reminder telling the model to use the model-named trailer, and it followed that over the skill. Setting attribution.commit to the skill's exact string makes both agree. Ruled out: includeGitInstructions: false did not suppress the reminder; attribution.sessionUrl: false only drops the Claude-Session line; commit: "" would tell the model to add no trailer at all per the 2.1.270 binary."

正确的正文:“提交技能的分支遵循了 Remote Control 提醒,而不是技能本身的要求,因此写入了以模型命名的 Co-Authored-By 署名行。”

错误的正文:将论据改写成 72 列格式,并包含已排除的设置和二进制版本。

Argument: "Two rules adopted from a CLAUDE.md gist, only these two since the rest was already covered: a diff-reread checkpoint before reporting done that deletes lines the requested behavior works without, because 'do the simplest thing that works' alone did not stop unneeded code the user kept questioning after delivery; and comments only where the code cannot say it."

正确的正文:“‘尽可能简单地实现可用方案’这一原则本身未能阻止不必要的代码留到交付时,而注释规则也没有明确说明只有在代码本身无法表达时才应添加注释。” 错误的正文:“采用两条规则:注释只应说明代码无法表达的内容;在报告更改已完成之前,重新阅读差异,并删除那些即使没有也不影响所请求行为的新增行,因为仅仅追求简洁并不能阻止不必要的代码混入交付的更改中。”

论据:“用户要求在重建 pangu.space 期间,将 README 标记为进行中。”

正确的正文:无。论据就是请求;之前没有任何问题。

错误的正文:“pangu.space 正在重建,所以 README 不应写得像一个已完成的项目。”

论据:“在 2026-09-09 至 2026-09-13 期间收集了五次重写会话;用户将 ‘I've picked up’ 改写为 ‘that works for me’,而 ~/Dropbox/writing/ 下的笔记没有相关规则。”

正确的正文:“风格规范没有禁止使用助理语气的开场白,因此草稿一直使用用户会改写的措辞。”

错误的正文:照搬会话日期、引用的改写内容和 Dropbox 路径。

定位仓库

首先运行 git rev-parse --show-toplevel。如果失败(分叉的起点不在仓库中),请先在论据中提及的任何文件路径所在目录中查找仓库,再报告“不是 git 仓库”。

范围

提交是一个快照,不是代码审查:阅读差异、暂存更改、撰写提交消息并提交。已暂存的字节必须与开始时工作树中的内容一致。只能在 Bash 中使用 git 和 cd,使用 Grep/Glob 定位文件,并使用 Read/Write/Edit 处理 <scratchpad> 中的补丁文件,即当前会话的暂存目录(如果运行环境未提供,则为 /tmp)。不要进行研究,不要运行代码或测试,不要使用任何其他技能,无论其触发条件多么强烈;不要征求顾问或第二意见。

绝不编辑工作树文件,即使是拼写错误、看起来不对的版本固定值或看似会失败的测试也不例外;在最终消息中指出相关问题。不要暂存作者未修改的文件;提交后不要超出 git status / git log 的范围进行验证,也不要自行运行提交前钩子;git commit 会运行它们。暂存期间的任何更改都会悄然改变已审查的内容,任何题外之事都会把 30 秒的操作拖成 5 分钟。

工作流

在 fork 启动所在的目录中直接运行 git 命令,绝不要使用 git -C,因为它会隐藏工作目录状态。在此 fork 中,cd 不会延续到下一次 Bash 调用。

  1. 按逻辑分组:将更改组织成逻辑单元——每个单元只解决一个目的,且作为整体回滚时应当合理。如果草拟的正文写了两个无关的问题,就应拆成两个提交:提交前先拆分。同一次审计或审查发现的多个问题属于同一个问题。

  2. 暂存更改:使用合适的暂存策略:

    • 整个文件:git add <file>。
    • 逐块暂存:使用 git diff <file> > <scratchpad>/patch.diff,仅通过删除行和修正头部计数来编辑补丁,绝不要重新输入补丁行(Write、heredoc、printf),因为重新输入的行可能会悄悄改变 BOM 等不可见字符,但仍然能够应用;然后运行 git apply --cached --verbose <scratchpad>/patch.diff。丢弃整个代码块是安全的。在代码块内拆分(只保留部分新增行)时,必须保留代码块末尾的上下文行,并重新计算两个头部计数——没有末尾上下文的代码块只能应用于文件末尾。
    • 如果输出中出现 Skipped patch,说明 fork 从子目录启动,而文件位于该目录之外:git apply 没有暂存该文件,但仍以 0 退出。使用 git add <file> 暂存整个文件,并在最终摘要中列出该文件。
    • 要取消暂存,请使用 git restore --staged(不要使用会丢弃更改的 git reset --hard)。
    • 备用方案:如果你编辑过的补丁首次运行 git apply --cached 失败,就使用 git add <file> 暂存整个文件。如果未编辑的完整差异也失败,则从 git diff 重新生成一次,然后暂存整个文件。绝不要排查补丁无法应用的原因。
  3. 处理提交前钩子:如果钩子因存在未暂存更改而报错,使用 git stash push --keep-index -m "temp: unstaged changes" 暂存这些更改,提交后再运行 git stash pop。如果钩子修改了已暂存文件(自动格式化),重新添加修改过的文件,然后重试提交一次——不要无限重试。

  4. 创建原子提交:对每个逻辑分组:

    • 使用 Conventional Commit 格式 type: subject,不带作用域,类型只能是 feat、fix、refactor、test、build、docs、style 之一。build 用于依赖和版本更新;style 表示 UI 视觉更改(CSS、字体、颜色、布局),而非代码格式化;代码格式化属于 refactor。主题应说明更改内容(≤72 个字符),并根据差异撰写。正文:按“论据”部分的要求撰写;只有主题有长度限制。页脚:按“署名”部分的要求添加。
    • 直接使用 git commit -m "message"——绝不要在 git 命令中使用 $() 或 heredoc 子 shell,因为这会破坏 allowed-tools 模式匹配。

署名

每条提交消息末尾都要添加适用于你所用模型系列的页脚。

只有确定这些都不适用时,才跳过页脚。

注意事项

  • 未暂存的更改仍然是更改。 git status 显示“no changes added to commit”,并不代表工作区干净,而是说明尚无内容已暂存。你的工作是暂存并提交这些更改,而不是报告“没有可提交的内容”。
  • 绝不要使用 git add -f。 如果 git add 报告“The following paths are ignored by one of your .gitignore files”,并提示 Use -f if you really want to add them,不要强制添加。该文件被 gitignore 刻意忽略(可能是机密、构建产物、本地配置),强制添加会悄悄绕过这项保护。跳过该文件,并在最终摘要中提及,以便作者决定如何处理。

评论

支持 Markdown