一般在多人协同开发项目时,都会做代码检查(如 eslint )以及代码测试(如 jasmine),通常的处理方式使用持续集成( CI 代码提交触发自动构建)来做。 今天介绍在 git 下,使用 git hooks 钩子来实现

Git hooks

钩子是指在特定操作时触发自定义脚本

在 git init 初始化仓库时,git 就会在当前目录下生成 .git 的文件夹,而在这个 .git 文件夹中会有一个 hooks 的目录。

在这个 hooks 目录里,会自动创建一些示例脚本,所有的示例脚本都是 Shell 脚本,以 .sample 作为后缀名

例如 commit-msg.sample

#!/bin/sh
#
# An example hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file
# that has the commit message.  The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit.  The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".

# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"

# This example catches duplicate Signed-off-by lines.

test "" = "$(grep '^Signed-off-by: ' "$1" |
	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
	echo >&2 Duplicate Signed-off-by lines.
	exit 1
}

Git 提供两组钩子:客户端和服务端,相关 Git 提供钩子信息查看 Pro git

那么回归当上面问题,如何使用客户端钩子来完成提交之前代码检查和自测呢

  • 定义钩子触发动作

    这里设计用户 git push 提交到服务器时执行。那么在本地仓库 .git/hooks 目录下创建 pre-push 文本文件

  • 定义钩子脚本内容

    脚本采用 Shell 来写

#!/bin/sh
grunt eslint
ret=$?

if [ $ret -eq 0 ]
then
  exit 0
else
  echo "Runing grunt eslint failed, please fixed the error first."
  exit 1
fi
  • 用户提交,如果 grunt eslint 不过,则会提交失败,给予错误信息,这时只要用户解决了错误信息,就可以提交成功了

这时有同学会问 “你这是在本地仓库里的 .git 目录设置,其他协同人员如何同步这些钩子脚本呢?”

有两种办法,第一种直接把拷贝这些钩子脚本,第二种使用 husky第三方库来支持(有兴趣的同学可以去看看源代码,就是根据 package.json 定义的钩子和钩子执行的命令 npm run 写到对应钩子脚本里)

这样就实现通过 Git hooks 钩子指定代码提交之前做一些代码检查的工作

参考文献

https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks https://github.com/typicode/husky

huang.xinghui

Programmer

huang-x-h huangxinghui


Published