规范设计之代码提交规范

Git Commit Message

Posted by Brian on Tuesday, November 7, 2023

写在前面的话

不管你使用什么语言来开发,代码提交一定是工作中的高频操作。我们经常会写出一些连自己都看不懂的 commit message ,或者压根就不重视这块的东西。比如以下的非规范示例:

image-20231107103044132

通过这张图上的commit 信息你能知道做了那些操作了吗。就算是开发人员我相信他自己也得去翻一翻代码。甚至他自己都不知道改了那些东西。甚至还有的开发写的Commit Message 完全是为了应对 commit 代码时必须写注释的约束。随便写个1或者什么的大有人在。下面在来感受下有规范Commit Message的提交:

image-20231107103736472

这里我们能清楚的知道。每一个提交都是做了什么操作。影响到了那些模块。比如 ci 是自动化流程,docs 是文档改动等等。看到这里也许你会说我英文不好,没法写出这么漂亮的注释。我想说的是。规范是你遵循了一定的规则后,其实commit 的信息你完全可以使用中文来描述。毕竟能把你所做的事情描述清楚,比选用什么语言来书写更重要。

规范的好处

  • 可以很好的告诉你的小伙伴你本次的commit都做了那些改变,快速浏览变更历史。

  • 可以基于这些Commit Message进行过滤查找,比如我们只想要找特定版本新增的功能:

    git log --oneline --grep "^feat|^fix|^perf"
    
  • 可以基于规范化的 Commit Message 生成 ChangeLog 。

  • 可以根据某些类型的Commit Message 触发构建流程或者发布流程。比如type为 feat 、fix时我们才去触发构建流程。

  • 语义化版本号。比如 fix 我们可以映射为修订版本(PATCH),feat 可以映射为次版本(MINOR)。带有 BREAKING CHANGE的commit映射为主版本(MAJOR)

Angular 规范

在Angular 规范中,Commit Message 分为三个部分,分别是 Header,Body,Footer,格式如下:

<type>[optional scope]: <description>
#空行
[optional body]
#空行
[optional footer(s)]

其中 Header 是必需的,Body 与 Footer是可以省略的。在些规范中 scope 必需使用括号()括起来,<type>[<sope>]后必需紧跟两个冒号,冒号后必须跟空格。2 个空行也是必须的。

在我们实际开发中我们会限制Commit Message的字符长度。一般为50/72/100 个字符。我工作中经常使用的是72个字符。这样做的好处是在仓库或者使用Git工具时更加的易读。

Header 由以下三个字段组成:

  • type: 必须。描述了 commit 的类型。主要分为 Development 与 Production 两大类。
    • Development:这类修改一般是项目管理类的变更,不会影响最终用户和生产环境的代码。比如 ci、docs等的改动,遇到这些改动,通常也意味着可以免测发布。
    • Production: 这类的修改会影响最终用户和生产环境的代码。遇到这些改动,需要提前做好测试在提交。
  • scope: 可选
  • subject: 必须

type

在 Angular规范中 type 常用选项值,以及它的所属类别

类型类别说明
featProduction新增功能
fixProduction修复Bug
perfProduction提高代码性能
refactorProduction其它代码的类的变更,这些变更不属于 feat fix perf 和 style,例如简化代码,重命名变量、删除冗余代码等
styleDevelopment代码格式化
testDevelopment新增测试用例或者更新现有测试用例
ciDevelopment持续集成和部署的相关改动,比如修改,GitlabCi 的配置文件等
docsDevelopment文档类更新
choreDevelopment其他类型,比如构建流程,依赖管理或者辅助工具的变动等

scope

Scope 是用来描述 commit 的影响范围。这个值是自己定义的。建议一个项目不要设置过多的值,太多了记不住,也容易放错分类。没啥意义,最好的做法就是按组件名来划分。或者按功能模块来划分。然后做一个表入到开发文档中描述下每个scope管理的范围。请不要把scope的值设置成controller,view之前很具体的值,除非你项目中本来就有类似的功能模块。例如:

scope描述
apiApi 服务相关
websocketWebsocket
customservice客服

subject

以动词开始,使用现在进行时间,首字母小写。如: add , update , change 等,subject 结尾不能有句号或点。subject 有点相当于我们写作文中的作文标题一样。只是高度概括了大概的意思。

Body

body 是可选的, 在body里可以对commit做更加详细的描述。

Footer 同样也是可选的。通常用来说明不兼容的改动和关闭Issue列表。格式如下:

BREAKING CHANGE: <breaking change summary>
// 空行
<breaking change description + migration instructions>
// 空行
// 空行
Fixes #<issue number>

提交频率

通过测试就提交,修复完成一个Bug提交,开发完一个小功能或写完一个不函数也提交。或者在每天规定的时间内定期提交。

君子协定与自动化

看到这里你会发现这一切都是需要我们开发人员自动去遵守,我相信很少有人能真的去认真遵守吧。所以为了规范,我们还需要在项目中使用类似于语法检测的工具来检测我们commit时提交的 message 是符合规范的。以下是我常用的自动化工具推荐。

  • 根据提示写出符合规范的 commit message 工具 commitizen-go
  • go-gitlint:检查提交的 Commit Message 是否符合 Angular 规范,主要应用在 CI 流程中。
  • gsemver:语义化版本自动生成工具。
  • git-chglog:根据规范 Commit Message 生成 CHANGELOG。