1. 前言
一直以来,公司app的commit信息都比较随意,导致出了问题,查起来比较麻烦。如果有一个工具能在我们git commit之前,收集到commit信息,并判断是否符合规范,若否,则提示提交失败。幸运的是,git本身就提供了这一功能。
2. 原理
git和许多版本控制系统一样,它也拥有在特定操作之前或之后执行特定脚本代码的能力。当我们执行git init 命令生成.git文件夹的同时,也会自动生成其他文件,如branches、objects、info、hooks等。其中hooks目录保存了对应的脚本,如pre-commit.sample就是代码提交前的hook,commit之前会先执行该脚本。(注意:此处需要把后缀.sample去掉才能生效)
上方列举的都算是client端的git-hooks。其实,git-hooks支持的能力远远不止途中这些,也支持服务端git-gook。
- applypatch-msg
- pre-applypatch
- post-applypatch
- pre-commit
- prepare-commit-msg
- commit-msg
- post-commit
- pre-rebase
- post-checkout
- post-merge
- pre-receive
- update
- post-receive
- post-update
- pre-auto-gc
- post-rewrite
3. 例子
知道了上面的原理,我们就使用Android Studio(其他项目原理一样)在app代码中实现一个规范commit信息的小功能。
3.1 编写脚本
假设我们想要对commit信息做如下规范:
[commitType][module] description
其中:
commitType只能是feature(新功能)、bugfix(修复bug)、refactor(重构)、other(其他)。
module 则为对应的功能模块,如直播、视频、正文、列表等。
description没有限制。
则我们只需要编写如下脚本即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #!/usr/bin/env bash regularExpression="^\s?\[(feature|bugfix|refactor|other)\]\s?\[.+\]\s?.+" error_msg="提交信息首行请按照如下格式书写:\n [commitType][module] description\n 1. commitType只能是feature(新功能)、bugfix(修复bug)、refactor(重构)、other(其他) 2. module 则为对应的功能模块,如直播、视频、正文、列表等 3. description 没有限制 例如: [feature][列表] 新增头图广告 "
firstLine=`head -n1 "$1"` if [[ "$firstLine" =~ $regularExpression ]]; then echo "commit success" exit 0 fi echo "commit fail" echo "$error_msg" >&2 exit 1
|
原理非常简单,就是取出commit信息的第一行,然后正则匹配即可。只要把该脚本拷贝到工程的.git/hooks目录下,并重命名为commit-msg,同时增加可执行权限,便大功告成!
3.2 修改gradle文件
如果你嫌麻烦,找不到.git目录(.git目录是默认隐藏的),可以通过修改gradle文件,配合另一个脚本,便会自动把上述脚本拷贝到.git/hooks/目录下了。这样做的好处是,你自己只需要把当前修改提交上去,全组的同事拉下最新代码,就生效了!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| apply plugin: 'com.android.application' android { compileSdkVersion 25 buildToolsVersion "25.0.2" defaultConfig { applicationId "com.netease.githooksdemo" minSdkVersion 15 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } afterEvaluate { tasks.matching { it.name.equals("preBuild") }.each { it.doFirst { exec { executable 'chmod' args 777, 'githook/installGitHook.sh' } exec { executable ('githook/installGitHook.sh') } } } } }
|
其中,installGitHook.sh脚本代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #!/usr/bin/env bash gitHookPath='.git/hooks/commit-msg'
rootPath=$(cd `dirname $0`;pwd) cd "$rootPath" cd .. cd ..
rootPath=`pwd` if [ ! -d ".git/hooks" ]; then mkdir .git/hooks fi
cp ${rootPath}/app/githook/pre_commit.sh '.git/hooks/commit-msg' chmod a+x '.git/hooks/commit-msg'
exit 0
|
如果我们提交的格式有误,Android Studio 便会提示commit失败:
4. 源码下载
GitHookDemo
5. 参考