图片来自 npm git-commit-msg-linter
本文在 Angular Commit Message Guidelines 的基础上添加了更详细的描述,并微调了在实践中摸索出来的与之不同的规范。原则以该规约为准,未提及的请参考本规范。欢迎讨论!
杂乱无章的现状
“那些年我们写过的 git 提交信息”。以下是某项目的历史提交信息:
- ref:编辑页面改为相对地址
- fix冲突
- style:权益卡区按钮文案换行问题修复
- shortcuts逻辑
- [dev] 查询话费和流量余额前置条件丰富
- 完善开发文档
- close: #14
规范
虽然提交信息林林总总,似乎无章可循,但是总可以将其约束到几大类中,故定此规范。
WHY
明明活得很好,为何要和自己过不去?
- 可读性。代码都要强调可读性,更何况本就给人看的提交信息呢?
- 信息分类,重点突出。按关键字筛选,如过滤掉代码样式的提交。
- 方便快速浏览,提升阅读效率 🚀
- 给 CR 提供更多上下文信息
- 培养原子提交意识,进一步促使模块化思考。一句话都没法描述此次改动,是否改动了多个地方?如果是,不利于回滚。
- 自动生成 CHANGELOG.md
HOW
格式如下:
<type>([scope]): <subject>
空一行
[body]
空一行
[footer]
包含三块:header、body 和 footer,各自用空行隔开;只有 header 是必须的;每个句子不超过 100 字符,目的是让提交信息在 GitHub 以及其他 git 工具上能够一行展示。
Header
<type>(<scope>): <short summary>
│ │ │
│ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
│ │
│ └─⫸ Commit Scope: Optional, can be anything specifying the scope of the commit change.
| For example $location|$browser|$compile|$rootScope|ngHref|ngClick|ngView, etc.
| In App Development, scope can be a page, a module or a component.
│
└─⫸ Commit Type: feat|fix|docs|style|refactor|test|chore|perf|ci|build|temp
格式:<type>([scope]): <subject>
。
header 是我们重点关注的,包含三个关键部分:type、scope(可选)、subject。
type
包含以下八种:
- feat(feature,产品新功能,通常是能够让用户觉察到的变化,小到文案或样式修改)
- fix(bug fix,修复 bug)
- docs(documentation,更新文档或注释)
- style(code formatting, missing semi colons, … 代码格式调整,对逻辑无影响:比如为按照 eslint 或团队风格修改代码格式。注意不是 UI 变更)
- refactor(重构:代码优化但不影响现有功能或添加功能。比如文件、变量重命名、代码抽象为函数,消除魔法数字等)
- test(when adding missing tests 单测相关变更)
- chore(杂项:其他无法归类的变更,比如代码合并)
- perf (性能提升变更)
- ci(持续集成脚本相关变更)
- build(代码构建相关变更:比如修复部署时的构建问题、构建脚本 webpack 或 gulp 相关变更)
- temp(临时代码:不计入 CHANGELOG,比如必须部署到某种环境才能测试的变更。如测试真机上 transparent title 启动参数是否设置成功)
style 类型很容易引起误解,并非指 UI 样式修改,而是指代码格式调整。UI 修改应该归属于 feat 或 fix。
问题 1:合并代码解决冲突归入哪种类型?
答:chore。原因:此次冲突解决并未增加新特性或修复 bug,仅仅是 merge 而已,主分支会记录 merge 过来的提交信息的,针对合并冲突的此次提交,其并未提供新的信息。
问题 2:升级依赖归入哪种类型?
答:看升级依赖的所属,比如是性能提升自然是 perf,构建脚本升级自然是 build,修复 bug 自然是 fix,无法归类则是 chore。
Scope
可选。变更范围细粒度要合适,在一个项目中保持一致最好,比如页面名、模块名、或组件名。
Subject
subject 是此次提交目的的简短描述,仅一行,不超过 100 字符。提交信息要重点描述为何要改,内容反而不重要,因为看代码就知道修改的内容(Focus on Why not What)。其次如果是英语,则用命令式、现在时(imperative, present tense),以及需符合以下规范:
- 现在时非过去式 (“change sth not changed some”);
- 主动态非被动态 (“change sth” not “sth be changed”);
- 一人称非三人称 (“change sth” not “changes sth”);
- 命令式。决定了动词开头,不包含主语;
- 首字母不大写、行末无句号、冒号为英文半角,后面加空格。
body
详细描述请放在 body 中。
💡 Tips: 该部分基本用不到,因为 subject 就可以描述完毕。
- 同样使用命令式、现在时态:“change” not “changed” nor “changes”;
- 请在此描述此次变更的动机和之前的差异。
footer
关闭 aone bug 请在此描述。 修复的 bug 必须要以 "Closes" 为前缀,后面接 aone issue id,这样可以自动将 bug 平台的问题关闭。比如:
Closes #234
或修复了多个 bug:
Closes #123, #245, #992
配套工具
多人合作时为了保证大家都能尊属该规范,可以配套 git-commit-msg-linter 即文章头图所示的规范工具使用。当然,我们可以将改工具定制到最符合我们自己团队的提交规范。
该 linter 的优点是:
- 可视化(低学习成本)
- 零配置(易上手)
- 对错误信息的对症提示(对无提交信息规范习惯的开发者友好)
- 使用模糊匹配自动纠正 type
- 支持 husky
总结
希望沉淀出更多的规范,进一步将规范变为团队共识、最后变为大家的常识。让开发者在多个项目流畅切换,不用增加多余的心智负担。
最后
回到文首“那些年我们写过的 git 提交信息”,对照规范看看有哪些问题
- ref:编辑页面改为相对地址。
归类不规范 :什么是 ref?
- fix冲突。
有关键字但信息不全
- style:权益卡区按钮文案换行问题修复。
信息归类不正确,应该属于 bug fix
- shortcuts逻辑。
无归类,信息不全
- [dev] 查询话费和流量余额前置条件丰富。
dev?有归类意识但格式和归类不规范
- 完善开发文档。
无归类
- close: #14。
无归类且不规范
最后给出正确的提交信息:
-
ref:编辑页面改为相对地址 →
fix: 常用号码编辑页跳转地址改为相对地址
-
fix冲突 →
chore: resolve conflicts when merging with remote
-
style:权益卡区按钮文案换行问题修复 →
fix: 修复权益卡区按钮文案换行问题
-
shortcuts逻辑 →
fix(shortcuts): 根据运营商 code 选择链接
-
[dev] 查询话费和流量余额前置条件丰富 →
feat: 丰富查询话费和流量余额前置条件
-
完善开发文档 →
docs: 完善开发文档
-
close: #14 →
// 1. 关闭 issue 置入 subject
fix: 修复通讯录图表不居中问题。close #14
// 2. 或将 close 置于 body,推荐前者,更简洁
fix: 修复通讯录图表不居中问题
Closes: #14
日常场景提交信息示例
合并分支
1 合并 master 分支
chore: merge with master
2 合并远端迭代分支
chore: merge with remote
3 合并远端分支并解决多个文件冲突
chore: merge with remote and resolve conflicts
4 合并远端分支并解决单个文件冲突
chore: merge with remote and resolve conflicts in src/pages/withdraw/index.js
随堂测验
下面的提交应用什么 type?
1、merge提交
A. feat B. refactor C. chore
D. merge
2、在代码中添加console.log进行调试
A. feat B. fix C. temp
D. test
3、commit时eslint未通过,问题修复好以后
A. fix
B. refactor
C. test
D. style
4、升级下webpack版本
A. feat
B. refactor
C. chore
D. merge
5、更改 readme 文档
A. feat
B. refactor
C. docs
D. merge
6、for in 循环改为 Object.keys 循环
A. perf
B. refactor
C. docs
D. merge
7、优化了样式
A. style
B. refactor
C. docs
D. feat
8、修正写错的文案
A. fix
B. refactor
C. docs
D. merge
9、补充必要的注释说明
A. style
B. refactor
C. docs
D. merge
10、增加埋点
A. chore
B. refactor
C. feat
D. merge
11、替换成线上的展位码
A. style
B. refactor
C. docs
D. feat