题记

由于打算把博客从Git Pages同步到自己的服务器上,需要借助Git hooks技术,所以来简单学习一下。

Git hooks是什么

Git Hooks就是那些在Git执行特定事件(如commit、push、receive等)后触发运行的脚本(这个脚本可以是shell、python、Ruby等等)。可以类比成一个触发器,当监听到某种事件时,就会自动触发,并执行脚本。

Git hooks能做什么

Git hooks基本操作

查看Git目录里面的文件结构:

xxx@xxx:~/xxx/xxx.git$ ls -a
.  ..  branches  config  description  HEAD  hooks  info  objects  refs

hooks子目录就是存放hooks的地方。

xxx@xxx:~/xxx/xxx.git/hooks$ ls -a
applypatch-msg.sample  fsmonitor-watchman.sample  pre-applypatch.sample  prepare-commit-msg.sample  pre-rebase.sample   update.sample
commit-msg.sample      post-update.sample         pre-commit.sample      pre-push.sample            pre-receive.sample

看这些样例的文件名我们就能知道这些hooks是在什么时候触发的,以prepare-commit-msg.sample为例,这个hooks就是当执行git commit命令时被触发。实际使用的时候,只需要在hooks目录新建`prepare-commit-msg文件,然后在里面编写你的脚本,记得写上!# 你的解释器的位置

以下列举几个不同hooks所能实现的功能:

pre-commit: 检查每次的commit message是否有拼写错误,或是否符合某种规范。

pre-receive: 统一上传到远程库的代码的编码。

post-receive: 每当有新的提交的时候就通知项目成员(可以使用Email或SMS等方式)。

post-receive: 把代码推送到生产环境。

举一个hooks脚本的例子,例子来源:《git: 提交前强制检查各个项目用户名邮箱设置》

该脚本写在pre-commit文件中, 用途是检查用户名邮箱设置:

#!/bin/sh
#
# A git hook to make sure user.email and user.mail in repository  exists before committing

set -e

global_email=$(git config --global user.email || true)
global_name=$(git config --global user.name || true)

repository_email=$(git config user.email || true)
repository_name=$(git config user.name || true)

if [ -z "$repository_email" ] || [ -z "$repository_name" ] || [ -n "$global_email" ] || [ -n "$global_name" ]; then
    # user.email is empty
    echo "ERROR: [pre-commit hook] Aborting commit because user.email or user.name is missing. Configure them for this repository. Make sure not to configure globally."
    exit 1
fi 

python_file=./git-hooks.py
if [ -f "$python_file" ]; then
    python $python_file pre-commit
fi

参考资料