name: yy-commit description: > 帮助用户创建规范的 Git 提交。 当用户想要提交代码、创建 commit、保存改动并提交时触发。 不适用于:仅暂存文件、仅查看 git 状态或历史、执行 push/pull/merge 等非提交操作、修改代码或实现功能。
yy-commit
描述
帮助用户创建规范的 Git 提交,生成符合项目自定义规范的提交信息或生成符合 Conventional Commits 规范的中文提交信息。
使用场景
- 用户说"提交代码"、"commit"、"创建提交"
- 用户说"提交一下"、"commit 一下"
- 用户说"保存已完成的改动并提交"
- 用户完成某个功能或修复后需要提交
- 用户说"提交 src/a.ts src/b.ts"、"提交 src/ 目录"(指定具体文件/目录)
- 用户说"提交全部文件"、"全部提交"(语义等价于提交所有改动)
不应触发:
- 用户只想暂存文件或执行
git add - 用户只是查看 git 状态或历史
- 用户要求执行 git push、pull、merge 等其他操作
- 用户要求修改代码或实现功能
指令
步骤 1. 分析当前状态与运行模式
参数解析
检测用户是否在调用时指定了文件/目录路径(如"提交 src/a.ts src/b.ts"、"提交 src/ 目录"、“提交全部变更”)。
决策分支:
- 用户指定了文件/目录路径(包括"全部文件"、"所有文件"等语义等价表达):标记为用户指定提交范围模式,仅对指定路径运行下方命令;跳过步骤 2(不判断原子性、不划定分组),直接以指定文件为提交范围,进入步骤 3
- 用户未指定文件/目录路径:保持常规流程,对全部改动运行下方命令,后续进入步骤 2
并行运行以下命令(用户指定文件/目录时,git diff 和 git diff --staged 仅针对指定路径):
git status
git diff
git diff --staged
git log --oneline -5
git status 输出解读规则:
Changes not staged for commit+modified:开头的行 → 有已修改文件,需要提交Untracked files:+ 文件名 → 有新增文件,需要提交Changes to be committed:+ 文件名 → 有已暂存文件,需要提交nothing to commit, working tree clean→ 无改动,告知用户并终止流程no changes added to commit→ 仅表示暂存区为空,不代表无改动;需结合上述条目判断
收集以下信息供后续步骤使用:
- 哪些文件已修改
- 变更的具体内容
- 当前是否已有暂存内容(
git diff --staged非空时记录已暂存文件清单,用于步骤 4 的副作用提示) - 最近的提交记录(用于步骤 3 推断项目提交风格)
快速提交模式判定:在本步骤一次性判定是否启用快速模式,避免后续步骤再做重复判断。
- 用户请求中包含"直接提交"、"立即提交"、"马上提交"、"无需确认"、"不用确认"、"跳过确认"、"直接 commit" 等明确表达 → 标记为快速提交模式
- 用户表达虽不在上述关键词内但语义等价(如"别再问我了"、"go ahead")→ 同样标记为快速提交模式
- 其他情况 → 常规模式
步骤 2. 理解改动并划定提交范围
前置条件:仅在步骤 1 未检测到用户指定文件/目录时执行本步骤。用户已指定提交范围时,跳过本步骤直接进入步骤 3。
2.1 理解改动意图
综合以下信息理解此次提交的目的:
- 代码变更分析:从 diff 中识别新增功能、修复问题、优化重构、文档更新等
- 对话上下文:提取用户想要实现的功能、提到的问题或需求
- 变更范围:确定影响的模块或功能区域
- 深层理解:不仅理解"做了什么",更要理解"为什么要这么做"
2.2 划定本次提交分组
以原子性为主要标准判断所有改动内容是否适合一次性提交。
本技能一次只处理一个原子单元的提交。如不适合一次性提交,告知用户哪些改动适合作为分组,让用户从以下选项中选择:
- 选择单个分组提交(单选)
- 强制一次性提交全部改动
- 自动分组提交(分别提交每个分组)
选项处理规则:
- 选择单个分组:以选定的分组为提交范围,进入步骤 3
- 强制一次性提交:以全部改动为提交范围,进入步骤 3
- 自动分组提交:进入循环流程,为每个分组依次执行步骤 3-5,直到所有分组提交完成
原子性判断标准:
- 核心标准:一次提交是否构成一个原子逻辑单元——所有改动围绕同一意图、共享同一回滚边界,单独取出任一部分都不影响其余部分的可工作性
- 如果根据核心标准仍无法明确如何分组,参考 resources/atomicity-criteria.md 中的具体参考信号进行分组判断
步骤 3. 生成提交信息
确定提交信息生成规范:
- 项目已定义提交规范(在 AGENTS.md、README 或其他明确规则中声明):必须优先使用项目约定的规范
- 项目未定义提交规范:使用定制版 Conventional Commits 规范
复杂改动提供候选选项:
当单次改动涉及多个维度(如同时包含功能新增和重构),或改动意图可以从不同角度描述时,提供 2 个候选提交信息供用户选择,帮助用户找到最准确的表达。简单改动(意图明确、变更单一)只需生成 1 个即可。
候选选项展示与选择交互:
- 在候选列表中提供"重新生成"和"自填提交信息"两个出口
- 用户选定候选后进入步骤 4 的最终确认;用户选择"重新生成"时回到本步骤重新生成候选;用户选择"自填提交信息"时直接收集用户输入并跳到步骤 4
- 快速提交模式(步骤 1 已判定):直接生成 1 个候选并进入步骤 4 展示,跳过候选展示与选择交互
步骤 4. 展示并确认
向用户展示:
- 暂存区副作用提示(仅当步骤 1 检测到
git diff --staged非空,且本次提交的暂存范围与已有暂存内容不一致时):明确告知"执行提交前会先git reset HEAD清空当前暂存区,仅暂存以下文件",并在用户确认前等待用户明确同意 - 将要暂存的文件列表
- 敏感文件警告(如暂存列表中存在敏感命名特征文件,详见 resources/sensitive-file-patterns.md;新增文件触发强制阻塞,修改/删除文件仅警告)
- 关键变更摘要(从 diff 提取的主要改动)
- 生成的完整提交信息(含 body)
- 主分支保护提醒(当步骤 1 检测到
git status输出包含On branch main或On branch master时,始终执行):提示用户当前位于主分支,建议在功能分支工作
快速提交模式的限制:
- 主分支提醒不受快速提交模式影响,始终执行
- 暂存区副作用强制阻塞:步骤 1 检测到已有暂存内容且与本次提交范围不一致时,即使命中快速提交模式也必须停止流程,回退到常规确认
- 新增敏感文件强制阻塞:暂存列表中存在新增的敏感命名特征文件时,即使命中快速提交模式也必须停止流程,回退到常规确认;用户须明确豁免该文件或将其从暂存列表移除后才能继续
- 修改/删除敏感文件警告:暂存列表中存在修改或删除的敏感命名特征文件时,展示警告提示但不阻塞流程
常规模式: 以编号列表向用户展示确认选项
1. 确认提交
0. 取消提交
用户选择处理:
- 选
1:进入步骤 5 执行提交 - 选
0:终止本次提交流程,输出"已取消" - 用户表达修改意见:按"修改提交信息规则"重新生成,回到步骤 4 重新展示确认选项
- 用户直接给出完整提交信息:以用户提供的内容为准,回到步骤 4 展示并等待最终确认
- 用户回复内容意图不明确(既非确认/取消编号,也非可识别的修改意见或完整提交信息):主动询问具体哪里不满意,引导用户表达修改方向
修改提交信息规则:
- 默认将用户反馈视为对冒号后
description语义的修正,不要求用户手工重写前缀 - 基于新 description、代码改动、对话上下文与项目规范,重新评估前缀是否匹配;按以下优先级处理:
- 项目有固定前缀规范:前缀必须优先适配到项目规范(如
功能:、重构:、文档:) - 项目无固定规范且当前前缀与改动性质匹配:保留前缀,只调整 description
- 项目无固定规范但前缀与改动性质不匹配:自动重新推导 type/scope
- 项目有固定前缀规范:前缀必须优先适配到项目规范(如
- 用户只指出"标题不合适"、"这不是修复"、"这其实是需求"等模糊反馈 → 视为允许 AI 根据真实改动自动重算前缀
- 仅当用户明确指定前缀类型时,才将该前缀作为强约束保留
- 如果提交信息包含 body(默认情况),优先保留 body,只更新受用户反馈直接影响的部分
- 仅在用户明确要求重新生成整个提交信息时,才重新生成完整的提交信息
展示格式(项目使用中文前缀规范时,将示例中的 feat(auth): 替换为对应的中文前缀,如 功能:):
即将提交以下更改:
⚠️ 检测到当前暂存区已有改动,提交前将先清空暂存区,仅保留以下文件(仅在副作用场景出现)
📝 暂存文件:
- src/auth/login.ts
- src/components/LoginForm.vue
- vite.config.ts
⚠️ 敏感文件警告:
- [新增] .env(环境变量文件)
- [修改] config/credentials.json(凭据文件)
📊 主要变更:
- 新增 JWT token 生成逻辑
- 添加登录表单验证
- 调整 vite 构建别名以支持新模块
💬 提交信息:
feat(auth): 添加 JWT 用户认证功能
- 新增 JWT token 生成逻辑
- 添加登录表单验证
- 补充登录失败场景的错误提示
⚠️ 当前位于 main 分支,建议在功能分支工作。
是否确认提交?
步骤 5. 执行提交
用户确认后,按顺序执行(不可并行)。
# 1. 清空暂存区,确保最终暂存内容仅包含最终选定的改动
git reset HEAD
# 2. 暂存选定的文件
git add <file1> <file2> ...
# 3. 创建提交
# 默认:title + body
git commit -m "<title>" -m "<body>"
# 仅 title
git commit -m "<title>"
提交命令约束:
- 提交信息必须使用
-m参数传递,禁止使用 heredoc(cat <<'EOF')、here-string(@'...'@)或其他 shell 特定语法 - 多行提交信息使用多个
-m参数:git commit -m "<title>" -m "<body line 1>" -m "<body line 2>",此写法在 bash、pwsh、zsh 等主流 shell 中均兼容
禁止事项:
- 禁止添加
Co-Authored-By:等署名备注 - 禁止使用 heredoc、here-string 或其他 shell 特定语法传递提交信息,必须使用
-m参数
步骤 6. 输出结果
输出提交结果,包括:
- 提交的文件列表
- 提交信息
- 提交哈希值
输出内容参考示例如下:
✓ 提交成功
提交文件:
- skills/yy-create-rule/SKILL.md
- skills/yy-create-rule/resources/rule-best-practices.md
提交哈希:7660360
提交信息:refactor(yy-create-rule): 添加规则内容通用性约束
变更统计:2 files changed, 2 insertions(+)
特殊情况处理
无变更内容
如果 git status 显示没有变更,告知用户:
当前工作区没有未提交的变更。
如果你期望有变更,可能的原因:
- 文件尚未保存
- 变更已经在之前的提交中
- .gitignore 忽略了这些文件
冲突或未推送的提交
在步骤 1 解析 git status 输出时识别以下信号并提醒用户:
- 合并冲突:状态中出现
UU、AA、DD、AU、UA、DU、UD标记的文件 → 提醒用户先解决冲突再提交 - 未推送的本地提交:状态中出现
Your branch is ahead of 'origin/...' by N commit(s)→ 仅提示存在未推送提交,不阻断本次提交 - 本地落后远端:状态中出现
Your branch is behind 'origin/...'→ 仅提示,不阻断本次提交
安全边界
禁止主动执行:
- 跳过 hook:不使用
--no-verify等标志 - 强制操作:不使用
--force或--amend(除非用户明确要求) - 添加署名:不添加
Co-Authored-By:等署名备注
主分支保护:
- 当前位于
main/master分支时,提醒用户考虑在功能分支工作,不得添加额外确认交互阻塞提交流程
排除来源权威性:
- 以
.gitignore为权威排除来源,不在其之上叠加二级黑名单 - 未被忽略的文件视为允许提交,对敏感命名特征文件始终给出展示警告
- 新增敏感文件触发强制阻塞,修改/删除敏感文件仅警告不阻塞
最佳实践
- 提交信息应该回答"这个提交做了什么,以及为什么要这么做"
- 优先说明改动的目的/原因,而不只是描述改动本身
- 保持提交信息的精确性:小改动要有具体的描述,避免过于宽泛
- 认真对待用户反馈:如果用户认为提交信息不够好,立即调整优化
- 优先使用对话上下文理解真实意图
- 当不确定变更意图时,询问用户
- 保持提交小而聚焦
- 使用有意义的 scope 帮助快速定位
- 提交信息涉及具体文件名时,必须保留原文件名,不得翻译
路径格式规范
- 在文档中提及文件路径时,优先使用相对路径
- 在终端中提及文件路径时,优先使用绝对路径
- 使用正斜杠作为路径分隔符,路径包含空格时使用引号包裹