希曼日记

git提交规范

本页目录 15
  1. 标准流程
  2. feat
  3. fix
  4. perf
  5. refactor
  6. style
  7. test
  8. docs
  9. build
  10. ci
  11. revert
  12. chore
  13. 落地:commitlint 校验
  14. 修订记录
  15. 参考

标准流程

  1. https://zhuanlan.zhihu.com/p/689467888

遵循 Conventional Commits(Angular 风格):

<type>(<scope>): [:emoji:] <subject>

<body>

<footer>
  • type 取下面十一类之一,不可自造
  • scope 是模块名,可省略
  • emoji 可选,但一旦写了就必须与 type 相符(见下表)
  • subject 末尾不加标点

emoji 一律用 gitmoji 短代码:bug:)而不是 Unicode 字面量(🐛):短代码是纯 ASCII, 终端、diff 工具、git log --oneline 的列对齐都不会因为宽字符而错位。

语义以 gitmoji.dev 官方定义为准。同一个 emoji 允许对应多个 type——:necktie:(业务逻辑)新写是 feat、改错是 fix、只挪不改行为是 refactor, 三种都成立。但 :bug: 只能是 fix:sparkles: 只能是 feat,这类没有第二种读法。

feat

添加了新功能/特性

emoji含义也可用于
:sparkles:引入新特性
:boom:破坏性变更refactor
:globe_with_meridians:国际化与本地化fix
:chart_with_upwards_trend:添加或更新分析、埋点代码
:speech_balloon:添加或更新文案与字面量docs / style
:triangular_flag_on_post:添加、更新或删除特性开关chore
:label:添加或更新类型refactor / chore
:necktie:添加或更新业务逻辑fix / refactor
:safety_vest:添加或更新校验相关代码fix / refactor
:passport_control:授权、角色与权限相关代码fix
:stethoscope:添加或更新健康检查chore
:card_file_box:数据库相关变更fix / chore
:loud_sound:添加或更新日志chore
:goal_net:捕获错误fix
:thread:多线程与并发相关代码fix / perf / refactor
:wheelchair:提升可访问性fix
:seedling:添加或更新种子数据chore
:egg:添加或更新彩蛋

fix

修复错误

emoji含义也可用于
:bug:修复 bug
:ambulance:关键热修复
:adhesive_bandage:非关键问题的简单修复
:pencil2:修复拼写错误docs
:lock:修复安全或隐私问题
:rotating_light:修复编译器或 linter 告警style / chore
:alien:因外部 API 变更而修改代码refactor
:green_heart:修复 CI 构建ci

perf

优化,提升性能/体验

emoji含义也可用于
:zap:提升性能
:mag:改进 SEOfeat
:children_crossing:改善用户体验与可用性feat / fix
:thread:优化多线程与并发代码feat / fix / refactor

⚠️ perf 只放真的让程序更快或更省的改动。重构、删死代码、移动文件、 改注释都不是 perf——它们不改变运行时开销,只改变代码的样子。

refactor

既不是新增功能,也不是修复 bug 的代码变动

emoji含义也可用于
:recycle:重构代码
:building_construction:架构变更
:art:改进代码结构与格式style
:truck:移动或重命名资源chore
:coffin:删除死代码chore
:fire:删除代码或文件chore
:wastebasket:弃用需要清理的代码chore
:mute:删除日志chore
:bulb:添加或更新源码注释docs

style

不影响语义的格式与 UI 样式变动

emoji含义也可用于
:lipstick:添加或更新 UI 与样式文件feat
:iphone:响应式设计feat
:dizzy:添加或更新动画与过渡feat

test

添加、修改测试代码

emoji含义
:white_check_mark:添加、更新或让测试通过
:test_tube:添加一个失败的测试(TDD)
:clown_face:mock 数据
:camera_flash:添加或更新快照

docs

文档修改

emoji含义也可用于
:memo:添加或更新文档
:bulb:添加或更新源码注释refactor
:page_facing_up:添加或更新许可证chore
:busts_in_silhouette:添加或更新贡献者chore
:money_with_wings:添加赞助或资金相关chore

build

影响构建系统或外部依赖的变动

emoji含义也可用于
:heavy_plus_sign:添加依赖
:heavy_minus_sign:移除依赖
:arrow_up:升级依赖
:arrow_down:降级依赖
:pushpin:将依赖锁定到指定版本
:package:添加或更新编译产物与分发包
:bricks:基础设施相关变更chore / feat
:wrench:添加或更新配置文件chore
:hammer:添加或更新开发脚本chore

ci

CI 配置文件与脚本的变动

emoji含义也可用于
:construction_worker:添加或更新 CI 构建系统
:green_heart:修复 CI 构建fix
:rocket:部署chore

revert

还原之前的修改

emoji含义
:rewind:回退变更

chore

以上都不是的杂项

emoji含义也可用于
:closed_lock_with_key:添加或更新密钥
:see_no_evil:添加或更新 .gitignore
:construction:工作进行中
:twisted_rightwards_arrows:合并分支
:alembic:进行实验feat
:monocle_face:数据探查与检查
:technologist:改善开发者体验
:tada:初始化项目feat
:poop:写下待改进的糟糕代码fix
:bento:添加或更新静态资源feat
:seedling:添加或更新种子数据feat

落地:commitlint 校验

光有文档没用,得让 git commit 真的拦得住。参考 ecommerce 仓库的做法:

commitlint.config.mjs            # 规则 + emoji↔type 白名单
package.json(仓库根)            # devDeps: @commitlint/cli + config-conventional
frontend/.vite-hooks/commit-msg  # pnpm exec commitlint --edit "$1"

配置里除了 extends: ['@commitlint/config-conventional'],关键是一条自定义规则: 从 subject 开头抓 :xxx:,没有就放行,有就查白名单并核对 type 是否在允许集合里。

装钩子的人不一定是 husky。ecommerce 的前端用 vite-plus,它自带一套和 husky 同构的 钩子 shim,pnpm install 时的 prepare: "vp config" 会把 core.hooksPath 设成 frontend/.vite-hooks/_。而 core.hooksPath仓库级设置,所以后端 Go 的提交 同样受这套校验管——一个前端工具链顺手接管了整个仓库的钩子。

几个真踩过的坑

  1. 别把安装命令抄成钩子内容。 husky 的文档教你写 npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'—— 这是要在终端执行的命令。我那份文档结尾原样留着这行,后来照抄时把它写进了 .husky/commit-msg 文件里,于是那个钩子的全部内容变成 echo "..." > .husky/commit-msg:每次提交它只是把自己重写一遍然后退出 0。 文件在、可执行位在、git 也确实调用了它,唯独它什么都没做。这种最难发现。
  2. core.hooksPath 必须指向真实存在的目录。 指到一个不存在的路径,git 不报错, 只是静默地一个钩子都不跑。工具链换代时特别容易撞上:老目录删了、新工具的接管守卫 又因为老值「看起来还像自己人」而选择跳过,core.hooksPath 就留在了半空中。
  3. pnpm exec 不要加 --no pnpm 11 已经不认这个 exec 参数,会报 Command "--no" not found,等于把校验变成永远失败(而 commit --no-verify 一旦成为肌肉记忆,等于没校验)。
  4. rules: {} 且没有 extends 是零规则,不是默认规则。配置文件存在不代表有约束。

这四条曾经同时成立,结果是校验从搭起来到被发现,九个月里一次都没生效过, 而仓库 README 一直写着「已配置提交信息校验」。

所以真正的规矩只有一条:装完立刻用一条故意写错的消息验证它真的拦得住, 再用一条正确的验证它不是「什么都拦」。

git commit --allow-empty -m "wip: 随便写点"              # 必须失败
git commit --allow-empty -m "feat: :bug: 走错 emoji"     # 必须失败
git commit --allow-empty -m "feat: :sparkles: 正确的"     # 必须成功
pnpm exec commitlint --from HEAD~10 --to HEAD           # 回放既有提交

静默失效的钩子比没有钩子更危险——它给了一种虚假的安全感,文档还会跟着一起说谎。

修订记录

2026-08-02 按 gitmoji 官方语义重新归类,修掉约 20 处错误。较大的几处:

原分类emoji问题现分类
perf:ambulance:官方语义是「关键热修复」,与性能无关fix
perf:art:官方语义是「改进代码结构与格式」,不是性能refactor / style
perf:recycle:重构不改变运行时开销;且与 refactor 段重复refactor
perf:coffin: :truck: :bulb: :alien: :passport_control: :technologist:删死代码 / 移动资源 / 写注释 / 跟外部 API / 权限代码 / 开发体验,都不是性能优化refactor、docs、fix、chore
perf:poop:含义写反了——官方是「写下需要改进的糟糕代码」,不是「改进垃圾代码」chore
perf:arrow_down:与 build 段重复;降级依赖是构建变动build
fix:necktie:写成「添加业务逻辑」——添加业务逻辑是 featfeat / fix / refactor
fix:fire:「删除代码」不是修 bugrefactor / chore
build:tada:官方是「初始化项目」,不是「发布项目」chore
build:rocket:部署不是构建组件的变动ci
chore:construction_worker:同一 emoji 重复列了两行;且属于 CIci
chore:stethoscope:写成「添加测试成功的代码」——官方是「健康检查」feat / chore
chore:alembic:「完成实验」→ 官方是「进行实验」chore / feat
test:white_check_mark: :test_tube:措辞不准,官方分别是「添加/更新/让测试通过」和「添加一个失败的测试」test
整个 ci 类型缺失,Angular 十一类里少了一类已补
feat/style:dizzy: :iphone:跨段重复且含义分裂(「JS 响应式」vs「CSS 响应式」)style 为主,feat 兼容

参考

  1. commitlint
  2. gitmoji
  3. Conventional Commits