关于提交日志规范
良好的 Commit Message 有利于代码审查,能更快速查找变更记录,并且可以直接生成 Change log。
规范代码提交有很多种,这里介绍一种 angular 的规范写法:
Commit Message 的写法规范:conventional-changelog
<type>(<scope>): <subject>
<空行>
<body>
<空行>
<footer>
日志第一行要求必须填写,body 和 footer 可选填。
Header填写
Type
type 填写 commit 的类别。
允许填写以下几种类型:
注:这里我认为可以根据团队需要增加一些类型,整个团队遵循一个约定即可
feat:新功能(feature)
fix:修补bug
docs:文档(documentation)
style: 格式(不影响代码运行的变动)
refactor:重构(即不是新增功能,也不是修改bug的代码变动)
test:增加测试用例等
chore:构建过程或辅助工具的变动
modify:非功能性的小的改动
debug:提交了一些测试用的代码
Scope
commit的影响范围,比如会影响到哪个模块/性能/哪一层(业务层,持久层,缓存,rpc),如果是特性代码,可以写特性名称
Subject
commit的简短描述,不超过50个字符
- 使用现在式,祈使句
- 第一个字母无需大写
- 结尾不用加句号
- 可以使用中文描述
Body
跟 subject 一样,使用现在式,祈使句。应该说明提交代码的动机,以及跟前一个版本的对比。
Footer
可填写:
- 描述重大变更的信息
- 关闭某个项目任务/关闭 Issue
特殊情况
-
fixup 以
fixup!开头的日志跳过上述规则检查,!号后面需要接一个空格。 当我们一个分支上面有多个提交,且部分提交是为了弥补之前的提交所做的细微改动。这个时候可以使用fixup将这些细微的提交合并(被合并掉的提交的message将被删除),这样我们主分支的git log graph看起来就更加干净 -
squash 以
squash!开头的日志跳过上述规则检查,!号后面需要接一个空格。 将多个commit合并为一个commit进行提交时,日志以squash!开头。 -
revert 以
revert:开头的日志跳过上述规则检查,:号后面需要接一个空格。 撤销某项commit时,日志要求以revert开头
检测方式
以下是一段 python 检测的参考代码,可以通过添加到 gitlab 中的 hooks 目录进行 commit 预检测
/opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive.d/
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys,os,re
# 检查正则表达式
def checkVaild(commit_str):
type_list = ['fix','feat','modify','refactor','docs','style','test','chore','debug']
# 这几种提交跳过检查
# const FIXUP_PREFIX_RE = /^fixup! /i;
# const SQUASH_PREFIX_RE = /^squash! /i;
# const REVERT_PREFIX_RE = /^revert:? /i;
if re.search(r'^fixup! ', commit_str, re.I) :
return True
if re.search(r'^squash! ', commit_str, re.I) :
return True
if re.search(r'^revert:? ', commit_str, re.I) :
return True
preg_rule = re.compile(r'^(?:fixup!\s*)?(\w+)(?:\(([^)]+)\))?\: (.+)$')
match_rs = re.findall(preg_rule, commit_str)
if len(match_rs)<1 :
return False
if match_rs[0][0] not in type_list :
return False
return True
# 读取git日志内容
def getGitLog(sign1,sign2):
commit_message = os.popen('git log ' + sign1 + '..' + sign2 + ' --pretty=format:%s').read()
return commit_message
# 运行主题
def mainRun():
line = sys.stdin.readline().strip('\n')
line_input = line.split()
if len(line_input)<2 :
sys.exit(0);
# 删除分支时正常退出
if (line_input[0] == "0000000000000000000000000000000000000000" \
or line_input[1] == "0000000000000000000000000000000000000000") :
sys.exit(0);
commit_message = getGitLog(line_input[0], line_input[1])
if commit_message=='' :
print('can not find any commit message!')
commit_g = commit_message.split('\n')
for commit in commit_g :
if not(checkVaild(commit)) :
print('your commit message is invaild!' + '[' + commit + ']')
else :
print('well format ' + '[' + commit + ']')
warning_info = '''##############################################################
## ##
## Commit message style check ! ##
## ##
## Commit message style must satisfy this regular: ##
## ^(?:fixup!\s*)?(\w+)(?:\(([^)]+)\))?\: (.+)$ ##
## ##
## Example: ##
## feat(test): test commit style check. ##
## ##
## You should use follow type: ##
## fix,feat,modify,refactor,docs,style,test,chore,debug ##
## ##
##############################################################
规则文档:XXX'''
print(warning_info)
mainRun()