如何利用 Git Hooks 来解决 “不会还有用 qq 邮箱来提交公司代码吧” 痛点

如何利用 Git Hooks 来解决 “不会还有用 qq 邮箱来提交公司代码吧” 痛点

没错!那个人就是我(●’◡’●)

不知道有没有人试过,不小心用 Github 的账号,提交 commit 到公司代码仓库中去,那一天突然兴致跑去看提交历史,会有个莫名其妙的东西混进来。这谁谁谁的代码吖,定睛一看,好像是我自己的 🫣,但又双为时已晚了。

01 Git Hooks

​ 从字面意思,大家应该都能像到是用来做什么的了。对对对,就是脑海中想像那个字眼,git 钩子。它的实现非常简单,Git 能在特定的重要动作发生时触发自定义脚本,其中比较常用的有:pre-commitcommit-msgpre-push 等钩子(hooks)。用于编写 git hooks 的脚本语言是没有限制的,你可以用 nodejsshellpythonruby等脚本语言,非常的灵活方便。

我们新建一个文件夹,git init 初始化仓库,进入 .git/hooks 文件夹,可以看到各种各样 sample 结尾的文件。

image-20220617163432439

打开其中一个看看,这些 sample 文件只是样板文件,简单来说,就是打个样。类似这个 pre-commit.sample 文件,从它注释来看,意思说给你打个样看好了,就是说,当提交 git commit 不带参数,可以通过 exit 非零来停止 commit 。说明你可以在这里编写一些校验判断在 commit 之前,类似邮箱校验,代码样式校验都可以在这里实现。通过重命名 pre-commit.sample ====> pre-commit 投入使用。

image-20220617163525655

至于每个钩子的作用,可以参照下面搬运过来的表

PS:完整钩子说明,请参考官网链接

preview

02 解决痛点

为了解决上述痛点,我们分析可得,在 pre-commit 或 common-msg 来进行校验邮箱号,这边以 pre-commit 为例,编写下面的代码,删除最后 sample 结尾。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# pre-commit
#!/usr/bin/sh
# 用 `` 可以将命令的输出结果赋值给变
# 获取用户 email
email=`git config user.email`
email_re="@kkguan\.com"
if [[ ! $email =~ $email_re ]]
then
echo "此用户 $email 没有权限,具有权限的用户为: xxx@kkguan.com"
echo "git config --local user.name \"xxx\""
echo "git config --local user.email \"xxx@kkguan.com\""

# 异常退出
exit 1
fi

检验成果的时候到了!我们新建一个 a.js 文件并提交到暂存区,当输入 git commit -m "add a.js" 命令,哇哦,我们成功了!!!🤪

同时还善意提醒我们可以通过下面两条命令修改项目仓库中的用户名和邮箱号。

image-20220617170213077

03 Husky

上面介绍了如何使用 Git hooks 钩子,但是这个钩子只能我们本地使用,如何礼貌让一起开发的同学一起规范起来呢,难不成,诶诶那个谁,你那个钩子 copy 我一份嘞,都是用 git 的人了,应该优雅点。下面我们介绍 [Husky](Husky - Git hooks (typicode.github.io)) 这个库。帮助我们管理 Git Hooks

官方提供两种方式安装

那我我们就按照,官方推荐自动的方式

1
2
3
4
5
# `husky-init` is a one-time command to quickly initialize a project with husky.
npx husky-init && npm install # npm
npx husky-init && yarn # Yarn 1
yarn dlx husky-init --yarn2 && yarn # Yarn 2+
pnpm dlx husky-init && pnpm install # pnpm

运行完命令后,会同时修改 package.json 和 生成一个简单的例子 pre-commit hook

也可以,通过生成 commit-msg 和其他的钩子

1
npx husky add .husky/commit-msg 'npx --no commitlint --edit "$1"'

见证奇迹

接下来,我们将我们上面写好的邮箱校验放入生成好的 pre-commit 文件中

image-20220617175843860

可以看到,校验成功了。我们再试试 commit-msg

1
npx husky add .husky/commit-msg ''

输入完命令后,生成 .husky/commit-msg 文件,我们可以利用这个文件校验 commit 提交的备注

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
#.husky/commit-msg
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

msg_re="^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|release|revert):"

if [[ ! $commit_msg =~ $msg_re ]]
then
echo -e "\n不合法的 commit 消息提交格式,请使用正确的格式:\
\nfeat: 新功能、新特性\
\nfix: 修改 bug\
\nperf: 更改代码,以提高性能(在不影响代码内部行为的前提下,对程序性能进行优化)\
\nrefactor: 代码重构(重构,在不影响代码内部行为、功能下的代码修改)\
\ndocs: 文档修改\
\nstyle: 代码格式修改, 注意不是 css 修改(例如分号修改)\
\ntest: 测试用例新增、修改\
\nbuild: 影响项目构建或依赖项修改\
\nrevert: 恢复上一次提交\
\nci: 持续集成相关文件修改\
\nchore: 其他修改(不在上述类型中的修改)\
\nrelease: 发布新版本 "

# 异常退出
exit 1
fi

输入 git commit -m "add pre-commit" 命令(同时也修改邮箱配置,以便通过 pre-commit)

image-20220617181617566

**This’s the magic!!!**😮

再也不用担心我提交乱七八糟的 commit 了,最后我们在校验下,git commit -m "feat: add pre-commit"(老老实实备注)

image-20220617182335380

显然,提交成功啦!