0%

使用 Git Hooks 进行代码提交检查

为什么要做代码检查?

在代码进行更改后,往往可能会造成预期之外的效果。比如说更改了某个函数的名字,但是进行函数调用的地方有遗漏;或者是修改了简单逻辑,但是未通过单元测试。如果我们在这时候提交了代码,往往会导致分支代码的不正确,甚至可能导致出现生产事故。

为了避免上述情况的发生,我希望每个团队的协作者在代码提交之前,能够检查自己的代码格式、运行单元测试来尽量避免错误的发生。通过「前置」而非「后置」的模式,防患于未然。

怎么做代码检查?

我们知道,代码检查通常有简单的格式检查和单元测试。如果一个程序无法通过格式检查、编译和单元测试,那么无疑是有问题的。

我们无法确保团队的每个成员在提交的时候让他们做手动检查,这样既容易遗忘又麻烦。

既然我们使用 Git,便可以使用 Git 的 Hooks 来完成这项工作。

Git 的 Hooks 可以让你在发布前后做一些工作,具体的原理参考 自定义 Git - Git 钩子

另外,你可以使用 Gerrit 等代码审查软件来完成这项工作。由于复杂性和易接受性方面的原因,我们没有采纳,这里也不进行过多介绍,如感兴趣可以参考 Gerrit 官网的介绍进行配置。

以下以 Git Hooks 方式实现了代码提交检查。

示例(以一个 Golang 项目为例)

1. 编辑 .git/hooks/pre-commit 文件

新建 pre-commit 文件

1
2
touch .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit

编辑 pre-commit 的内容

1
2
3
4
5
6
7
8
9
10
11
work_dir=$(git rev-parse --show-toplevel)

if ! go vet $(go list $work_dir/...); then
echo "Go vet failed, please check your code."
exit 1
fi

if ! go test $(go list $work_dir/...); then
echo "Go test failed, please check your code."
exit 1
fi

2. 构造一个无法通过编译或者无法通过单元测试的场景,提交代码。

image.png
出错时会无法提交代码

3. 将 Hooks 加入版本控制系统

在此之后,我们会遇到一个问题,.git 目录本身作为 Git 的仓库目录是无法添加到版本控制系统中的。

从 Git 2.9 开始,Git 可以手动指定 Git 的 Hooks 目录。

1
2
3
mkdir .githooks
cp .git/hooks/pre-commit .githooks
git config --local core.hooksPath .githooks

这样便可以将 Git Hooks 进行共享。

我们在 Makefile 中加入一段话

1
2
3
.PHONY: init
init:
git config --local core.hooksPath .githooks

项目成员需要执行 make init 来初始化 Git hooks 目录。