团队的 commit message 现状:fix bug、update、修改了一些东西、111。
看 git log 跟没看一样,cherry-pick 时根本不知道哪个 commit 是想要的。我用一个 agentStop Hook + 一个 Prompt 模板,让 AI 在每次完成任务后自动生成规范的 commit message。
为什么 commit message 重要
scss
场景 1:线上回滚
git log --oneline
├── a3f2d1c fix bug
├── b4e5f6a update
├── c7d8e9b 修复
└── 哪个是出问题的 commit?完全不知道
vs
├── a3f2d1c fix(store): 修复上线签约弹窗重复弹出
├── b4e5f6a feat(export): 新增报表导出动态超时
├── c7d8e9b refactor(api): 请求层拆分为洋葱模型
└── 一眼看出哪个改了什么
场景 2:写周报
"上周做了什么?"
→ git log --since="1 week ago" --oneline
→ 规范的 message 直接就是周报素材
场景 3:生成 CHANGELOG
conventional-changelog 工具直接从 commit 提取 feat/fix
→ 前提是 message 格式正确
AI 自动生成 Commit Message 的 Hook
json
{
"name": "Auto Commit Message",
"version": "1.0.0",
"description": "任务完成后根据改动自动生成规范的 commit message",
"when": {
"type": "userTriggered"
},
"then": {
"type": "askAgent",
"prompt": "请根据当前 git diff 生成 commit message。\n\n格式要求:\n- 遵循 Conventional Commits 规范\n- 格式:type(scope): 描述\n- type: feat|fix|refactor|style|docs|chore|perf|test\n- scope: 改动涉及的模块名(从文件路径推断)\n- 描述:用中文,一句话说清楚改了什么\n- 如果改动涉及多个不相关的模块,建议拆分为多个 commit\n\n示例:\n- feat(store): 新增门店上线签约弹窗\n- fix(export): 修复报表导出超时问题\n- refactor(api): 请求拦截器拆分为独立模块\n\n请直接输出 commit message,不要额外解释。如果改动较大,输出 body 部分列出要点。"
}
}
Commit Message 规范速查
bash
type 说明:
────────────────────────────────────────
feat 新功能
fix Bug 修复
refactor 重构(不改功能也不修 bug)
style 样式/格式调整(不影响逻辑)
docs 文档变更
chore 构建/工具链/依赖变更
perf 性能优化
test 测试相关
────────────────────────────────────────
scope 推断规则(从文件路径):
────────────────────────────────────────
src/view/selfCatering/ → store/selfCatering
src/view/marketing/ → marketing
src/components/ImageUpload → component/ImageUpload
src/api/ → api
src/services/ → service
rsbuild/ → build
────────────────────────────────────────
实际效果对比
一个真实的 diff:
bash
修改了 3 个文件:
- src/view/selfCatering/storeSetup/index.tsx(加了签约按钮)
- src/view/selfCatering/storeSetup/SignContractModal.tsx(新文件)
- src/services/selfCatering/contract.ts(新文件)
AI 生成的 message:
diff
feat(selfCatering): 新增门店上线签约功能
- 上线按钮点击前增加签约状态判断
- 新增 SignContractModal 签约弹窗组件
- 新增签约相关接口服务
比手写快,而且格式稳定。
多文件改动时的拆分建议
如果 diff 包含不相关的改动,AI 会建议拆分:
sql
检测到改动涉及 2 个不相关模块:
1. src/view/selfCatering/(签约功能)
2. src/components/ImageUpload/(图片校验)
建议拆分为 2 个 commit:
commit 1: feat(selfCatering): 新增门店上线签约功能
commit 2: feat(component): ImageUpload 新增比例校验
需要我帮你执行 git add -p 分文件暂存吗?
和 standard-version 的配合
项目用了 standard-version 自动生成 CHANGELOG:
arduino
规范的 commit message
↓
npm run release
↓
自动提取 feat/fix 生成 CHANGELOG.md
↓
自动打 tag
↓
自动 push
前提是 commit message 格式正确。AI 生成的格式天然符合 conventional-commits,完美衔接。
团队推广策略
sql
阶段 1(第 1 周):只做提示
├── AI 生成 message 但不自动 commit
├── 开发者可以修改后再 commit
└── 降低抵触情绪
阶段 2(第 2-3 周):习惯养成
├── 大家发现 AI 生成的比自己写的好
├── 开始依赖自动生成
└── 偶尔手动微调
阶段 3(第 4 周+):完全自动化
├── 信任建立,直接用 AI 生成的
├── 只在特殊情况下手动调整
└── git log 质量显著提升
常见问题
Q:AI 生成的 scope 不对怎么办?
在 steering 里配置 scope 映射表:
markdown
## Commit Scope 映射
- src/view/selfCatering/ → selfCatering
- src/view/marketing/ → marketing
- src/view/member/ → member
- src/components/ → component
- src/api/ → api
Q:英文还是中文?
我们团队选择 type(scope) 用英文,描述用中文。原因:
- type 是固定词汇,英文更通用
- scope 是模块名,英文更短
- 描述用中文,同事一眼看懂
Q:怎么和 commitlint 配合?
json
// commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [2, 'always', ['feat', 'fix', 'refactor', 'style', 'docs', 'chore', 'perf', 'test']],
'subject-empty': [2, 'never'],
},
}
AI 生成 → commitlint 校验 → 双重保障。
💬 你们团队的 commit message 是什么状态?有没有强制规范?
🔗 完整 Skills 源码已开源 :github.com/sleepyccat/...,欢迎 Star ⭐ 和 PR。