DoneSpeak

定义全局Git Hooks和自定义Git Hooks

字数: 591时长: 2 min
2021/05/24 Share

提示 21

Use the Power of Command Shells

利用命令shell的力量

–《程序员修炼之道 - 从小工到专家》

写在前面

一个git项目只有一个hooks目录,每个阶段hook文件也只有一个,这样会造成开发人员和公司全局hooks的配置冲突。为了实现全局Git Hooks和开发人员自定义Hooks,特写了该简易项目。

全局Hooks和自定义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
├── Makefile # make 安装指令
├── global #保存全局的hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── fsmonitor-watchman.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── pre-merge-commit.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ ├── pre-receive.sample
│ ├── prepare-commit-msg.sample
│ └── update.sample
├── customized # 开发人员自定义hooks目录
├── applypatch-msg
├── commit-msg
├── fsmonitor-watchman
├── hook-exec # hook 执行核心
├── post-update
├── pre-applypatch
├── pre-commit
├── pre-merge-commit
├── pre-push
├── pre-rebase
├── pre-receive
├── prepare-commit-msg
└── update

核心文件 hook-exec

该文件负责将global/<hook>customized/<hook>绑定到一个<hook>。如果想进行更多目录的拓展,更多同阶段hooks的拓展,可以对该文件进行修改。

hook-exec

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash

HOOK_DIR=$(dirname "$0")
GLOBAL_HOOK="$HOOK_DIR/global/$HOOK_NAME"
CUSTOM_HOOK="$HOOK_DIR/customized/$HOOK_NAME"

if [ -f "$GLOBAL_HOOK" ]; then
source $GLOBAL_HOOK
fi

if [ -f "$CUSTOM_HOOK" ]; then
source $CUSTOM_HOOK
fi

git hook执行文件

根目录下的hook文件都是一样的,目的是为了将hook的文件名HOOK_NAME以及所有参数$@都传入到hook-exec中,从而实现全局和自定义hook的调用,并确保原本的参数可以正常使用。

hook name

1
2
3
4
5
#!/bin/bash

HOOK_NAME=$(echo $0 | sed 's/.*\///')

source $(dirname "$0")/hook-exec $@

Makefile 实现指令安装

fork该文章的项目gromithooks到自己的仓库,并将全局的githooks保存到项目的global/目录下,其中的customized/则可以存放开发人员自己的githooks。

将下方的Makefile文件复制到git项目的根目录下,即可通过make指令完成multi hooks的初始化和更新。(替换 `git@gitlab.com:DoneSpeak/gromithooks.git` 为fork之后的项目地址)

Makefile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
REPO := $(PWD)
REPO_GIT := $(REPO)/.git

install-git-hooks: .git/hooks/hook-exec

.git/hooks/hook-exec:
ifeq ($(wildcard $@),)
cd $(REPO_GIT) && git clone git@gitlab.com:DoneSpeak/gromithooks.git
mv $(REPO_GIT)/hooks/* $(REPO_GIT)/gromithooks/git-hooks/multi-hooks/customized/
rm -rf $(REPO_GIT)/hooks
ln -s $(REPO_GIT)/gromithooks/git-hooks/multi-hooks $(REPO_GIT)/hooks
endif

update-git-hooks: install-git-hooks
cd $(REPO_GIT)/gromithooks && git pull

执行如下指令可以完成项目的配置。

1
2
3
4
5
# 安装
make install-git-hooks

# 更新
make update-git-hooks

参考

CATALOG
  1. 1. 写在前面
  2. 2. 全局Hooks和自定义Hooks
    1. 2.1. 项目结构
    2. 2.2. 核心文件 hook-exec
    3. 2.3. git hook执行文件
  3. 3. Makefile 实现指令安装
  4. 4. 参考