Git Commit
一个帮助你生成规范化 Git 提交信息的技能。核心理念:理解改动意图,而非仅仅总结 diff。
核心能力
- 读取改动 — 获取
git diff和git status,全面了解待提交内容 - 理解意图 — 分析代码变更的真实目的,而不仅仅是看到的文本变化
- 规范生成 — 生成符合 Conventional Commits 规范的提交信息,type 使用英文,描述使用中文
- 先展示、后确认 — 先以普通文本完整展示提交信息和待提交文件清单,再弹出选择题等待确认,确认通过才执行
git commit
重要:理解意图优先
这个技能不是为了"看一眼 diff 然后编一个看起来合理的 message"。它的价值在于:
- 透过改动看目的:删除一个函数可能不是"删除代码",而是在"移除已废弃的 API"
- 关联上下文:修改多个文件可能都是为了同一个功能,而不是零散的改动
- 正确分类 type:加一个 if 判断可能是
fix(修 bug)也可能是feat(加边界处理),需要理解为什么 - 用户提示是参考,不是答案:用户可能随口说"修了个问题",但实际改动是一次重构——以代码为准,用户提示只辅助理解
工作流程
第一步:获取改动信息
# 获取当前状态
git status --porcelain
# 获取未暂存的改动
git diff --no-color
# 获取已暂存的改动
git diff --cached --no-color
注意区分以下情况:
- 没有任何改动 → 告知用户,结束流程
- 只有已暂存的改动 → 只分析暂存区
- 只有未暂存的改动 → 分析工作区改动,commit 前需要
git add - 两者都有 → 分析全部改动,但告知用户当前状态
第二步:理解改动意图
在生成提交信息之前,花时间认真理解这次改动:
- 整体扫描:改动了哪些文件?文件之间有关联吗?
- 模式识别:
- 新增文件/函数/模块 → 可能是
feat - 修改条件判断、异常处理、边界情况 → 可能是
fix - 重命名、移动、结构调整但逻辑不变 → 可能是
refactor - 只改注释、文档、README → 可能是
docs - 测试文件的新增或修改 → 可能是
test - 配置、构建脚本、依赖更新 → 可能是
chore
- 新增文件/函数/模块 → 可能是
- 意图推断:这些改动作为一个整体想要达成什么目的?
- 用户提示:如果用户提供了提交信息文本——把它的语义当作理解意图的重要线索,但不要直接拿它当模板。用户写"修 bug"但你看到的是加了新功能,以代码为准。
第三步:生成提交信息
根据理解的意图,生成符合 Conventional Commits 规范的提交信息。
详见 references/conventional_commits.md 获取完整的类型说明和格式规范。
格式要求:
<type>(<scope>): <中文主题>
<中文正文>
基本规则:
- type 必须是小写英文:
feat,fix,refactor,docs,style,test,chore,perf,ci,build - scope 是可选的,用小写英文,表示影响的范围(模块、组件名等)
- 主题行用中文,采用祈使句或动宾结构,简明扼要地描述改动目的,而不是描述已经完成的动作
- 主题行不超过 50 个字符(中文约 25 个字)
- 主题行避免使用「增加了」「修复了」「修改了」等过去式表达,使用「增加」「修复」「优化」等动词开头
- 主题和正文之间空一行
- 正文详细说明改了什么、为什么改,用中文描述
- 使用自然流畅的中文,避免英文直译腔、机器翻译式表达,提交信息应符合中文开发习惯
绝对禁止:
- 禁止在提交信息末尾添加任何署名或签名,包括但不限于
Co-Authored-By、Signed-off-by、Reviewed-by等。提交者信息由 git 的user.name和user.email配置自动记录,无需在 message 中重复 - 禁止在提交信息中写"生成者:Claude"、"由 AI 辅助生成"等 AI 相关声明
- 提交信息只包含改动相关的内容,不包含元信息
确定 type 的思考框架:
- 这个改动对外部用户可见吗?是新增能力吗?→
feat - 这个改动是在修复一个不希望存在的行为吗?→
fix - 这个改动既不增加功能也不修复 bug,但让代码更好维护了吗?→
refactor - 只影响文档吗?→
docs - 只影响测试吗?→
test - 只是格式、空格、分号等不影响逻辑的调整吗?→
style - 构建、依赖、CI 配置等维护性的改动吗?→
chore - 主要目的是提升性能吗?→
perf
示例:
输入:添加了 JWT 认证中间件,修改了路由配置
生成:
feat(auth): 添加 JWT 令牌认证功能
新增 JWT 验证中间件,在路由层拦截未认证请求。
支持令牌过期自动刷新,过期但未失效的令牌会触发静默刷新。
输入:修复了用户列表页分页数量不对的问题
生成:
fix(user): 修复分页总数计算错误
分页总数之前包含了已删除的用户,导致列表页显示的空页过多。
现在使用 COUNT(*) 替代 COUNT(id) 并过滤 deleted_at。
第四步:展示提交信息(强制,不可跳过)
在调用任何确认工具之前,必须先用普通文本把提交信息完整展示给用户。
⚠️ 为什么这一步不能省略:AskUserQuestion 的选项里只能放很短的标签,放不下提交信息全文。用户只有先看到文本展示,才知道自己即将提交什么,才能做出「确认 / 修改 / 取消」的判断。绝不能在没展示内容的情况下直接弹出选择题——那样用户面对的是一个不知道内容的确认框。
展示需包含两部分:
- 建议的提交信息(subject + body 完整内容)
- 将提交的文件列表(带状态标记,如
M/A/D)
展示格式:
📋 建议的提交信息:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
feat(auth): 添加 JWT 令牌认证功能
新增 JWT 验证中间件,在路由层拦截未认证请求。
支持令牌过期自动刷新。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📂 将提交的文件:
M src/middleware/auth.js
M src/router/index.js
A src/utils/jwt.js
展示完成后,再进入第五步调用 AskUserQuestion。
第五步:等待用户确认
调用 AskUserQuestion,提供一个 3 选项的选择题:
- header: "确认提交"
- question: "是否使用以上提交信息?"
- options:
"确认提交"— 使用此信息执行 git commit"我要修改"— 用户提供修改意见,基于反馈重新生成提交信息"取消"— 放弃,不执行任何操作
根据用户选择:
- 选 1 → 进入第六步,执行提交
- 选 2 → 读取用户的修改意见(在 answers 中),回到第三步重新生成(重新生成后仍需重新走第四步展示)
- 选 3 → 结束流程,告知用户"已取消"
第六步:执行提交
# 如果有未暂存的文件,先 add
git add <files>
# 执行提交
git commit -m "<subject>" -m "<body>"
提交成功后,显示提交的 hash 和分支信息。
特殊情况处理
用户提供了提交信息提示
当用户调用时附带了一些文字(如 /git-commit 修了个登录的bug):
- 把用户文字当作理解意图的重要线索,优先往用户说的方向上理解
- 但如果代码改动明显是别的类型,以代码为准,并向用户说明为什么
- 用户写的文字可能不规范——没关系,提取语义即可
- 即使用户提供了文字,仍然需要走完整的分析流程
改动过大
当 diff 超过 500 行时:
- 先按文件或目录分组
- 识别每组改动的主题
- 判断是否应该建议用户拆分成多个提交
- 如果属于同一主题,生成一个涵盖整体的提交信息
没有改动
直接告知用户:"当前工作区没有需要提交的改动。"
参考资源
references/conventional_commits.md— Conventional Commits 规范详解scripts/git_utils.sh— Git 操作辅助函数