git commit 规范以及校验方案
前言
在使用 Git 作为版本控制工具时,每次文件发生修改的时候提交都需要 git commit
命令去记录本次的修改,否则就不允许提交,显然 git commit
是一个重要的环节,因此制定一个 Git Commit 规范是有必要的,否则就会出现混乱的提交信息,这里腾讯某团队的规范作为例子,然后通过一定的手段去帮助我们把这个规范落到实处。
目的:
- 统一团队
Git commit
日志标准,便于后续代码 review,版本发布以及日志自动化生成等等。 - 统一团队的 Git 工作流,包括分支使用、tag 规范、issue 等
Git commit 日志参考案例
总体方案
Git commit日志基本规范
1 | <type>(<scope>): <subject> |
type 类型
type代表某次提交的类型,比如是修复一个bug还是增加一个新的feature
- feat: 新增 feature
- fix: 修复 bug
- docs: 仅仅修改了文档,比如 README, CHANGELOG, CONTRIBUTE等等
- style: 仅仅修改了空格、格式缩进、逗号等等,不改变代码逻辑
- refactor: 代码重构,没有加新功能或者修复 bug
- perf: 优化相关,比如提升性能、体验
- test: 测试用例,包括单元测试、集成测试等
- chore: 改变构建流程、或者增加依赖库、工具等
- revert: 回滚到上一个版本
格式要求
1 | # 标题行:50个字符以内,描述主要变更内容 |
校验方案
node 项目已经有比较成熟的方案,这里以 Python 项目为例,考虑实际使用的便利性,希望可以可以实现以下的目的:
- 成员在本地执行 git commit 的命令时就完成校验,通过则允许执行
git push
否则则需要重新提交 commit 的信息。 - 提交到 gitlab,由服务端完成再次校验
本地校验
git hooks
Git 在执行 git init
进行初始化的时候,会在 .git/hooks
目录下生成一系列 hooks 脚本:
从上图可以看到每个脚本的后缀都是以 .sample
结尾的,在这个时候,脚本是不会自动执行的。我们需要把后缀去掉之后才会生效,即将 pre-commit.sample
变成 pre-commit
才会起作用。由于只是对 commit msg 做校验,所以只需要使用 commit-msg
脚本即可。
commit-msg 脚本
在 commit-msg
hooks 中完成对 commit 消息校验
1 | #!/bin/sh |
将上述脚本保持在项目所在对 .git/hooks
目录下命名为 commit-msg
,然后执行 chmod
命令:
1 | chmod +x .git/hooks/commit-msg |
验证结果
- 不符合规法的 commit msg
- 符合规范的 commit-msg
服务端校验
Git 在服务端也同样有一些 hooks:
pre-receive
update
post-receive
每个 hooks 的具体功能可以参考 Server-Side Hooks ,其中 pre-receive
和 update
均符合使用场景,唯一区别是用户同时推送到多个分支时, update 针对每个分支都会被触发执行,而 pre-receive
只执行一次。
pre-receive
说明
在任何文件被更新时,如果$GIT_DIR/hooks/pre-receive
存在并且是可执行的文件,则 pre-receive 会被无参数触发执行一次,正常 pre-receive 触发执行的时候会接收如下的参数:
1 | sha1-old SP sha1-new SP refname LF |
其中 sha1-old 为多次 commit 的最早一次的 commit 的 id,而 sha1-new 则是最新一次的 id。除此之外,git push 的时候还会传递其他的信息,可以参考 pre-receive-hooks 。
校验方法
通过 git log old-commit-ID new-commit-ID -pretty=format:%s
提取出俩个 commit 之间的所有 commit-msg 然后逐一校验。
考虑易用性,用 golang 构建校验脚本
1 | package main |
同时支持添加配置文件
1 | { |
服务器配置 pre-receive
参考 Server Hooks 需要将编译后 pre-receive
放到制定的 repository 的钩子目录即可,具体步骤如下:
- 找到对应 repository 的
.git
目录 - 在该目录下创建
custom_hooks
的目录 - 将编译后的
pre-receive
放到该目录下(如果有配置文件也上传到该目录下) - 通过
chmod +x pre-receive
让该文件可执行,同时将该文件的用户组切换为git:git
- 推送代码验证结果