提示 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
|
参考