提醒 21

Use the Power of Command Shells

利用命令shell的力量

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

写在后面

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

全局Hooks和自定义Hooks

我的项目构造

├── 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

#!/bin/bashHOOK_DIR=$(dirname "$0")GLOBAL_HOOK="$HOOK_DIR/global/$HOOK_NAME"CUSTOM_HOOK="$HOOK_DIR/customized/$HOOK_NAME"if [ -f "$GLOBAL_HOOK" ]; then    source $GLOBAL_HOOKfiif [ -f  "$CUSTOM_HOOK" ]; then    source $CUSTOM_HOOKfi

git hook执行文件

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

hook name

#!/bin/bashHOOK_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

REPO := $(PWD)REPO_GIT := $(REPO)/.gitinstall-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)/hooksendifupdate-git-hooks: install-git-hooks    cd $(REPO_GIT)/gromithooks && git pull

执行如下指令能够实现我的项目的配置。

# 装置make install-git-hooks# 更新make update-git-hooks

参考

  • 本文章源码 Donespeak/Gromithooks
  • 8.3 自定义 Git - Git 钩子 @git-scm