Git 進階使用 - Git Hook
What Is Git Hook
在開發過程當中,我們常常會遇到需要手動進行測試以及 format 程式碼等等的事情,那就會讓我思考
有沒有一種自動化的工具可以執行這些任務呢?
Git - 一個幾乎可以說每個軟體工程師都會使用的工具,提供了一個解方
git hook 簡單來說就是一個在 commit, push, receive 之前或之後跑的 script
,可以讓開發者自定義需要執行的 script
這個 script 不限定使用何種語言撰寫皆可(e.g. python, perl, ruby 或 shell script … etc.)
而 git hook 通常分為兩大類
client-side
: 透過 commit 或者是 merge 觸發server-side
: 多半是透過網路,當接收到 commit 時觸發
How to setup Git Hook
git hook 是內建的功能之一,我們可以在 ./git/hooks
底下找到許多範例檔案
1
2
3
4
5
6
ambersun@station:~/ambersun1234.github.io/.git/hooks$ ls
applypatch-msg.sample pre-applypatch.sample pre-rebase.sample
commit-msg.sample pre-commit.sample pre-receive.sample
fsmonitor-watchman.sample pre-merge-commit.sample prepare-commit-msg.sample
post-update.sample pre-push.sample update.sample
ambersun@station:~/ambersun1234.github.io/.git/hooks$
使用 git hook 需要符合以下
- 將檔案置於
./git/hooks
資料夾底下 - 客製化 git hook 不能 有任何副檔名
- 更改 file mode 成可執行
1
$ chmod +x my-hook
- 檔案名稱需要完全符合預設 hook 種類的名字(詳細可以參考 Git - githooks documentation) 不然有可能會無法 trigger
- 如果在 commit 的當下想要 pass 掉 hook 可以使用
1
$ git commit --no-verify
除了放在 ./git/hooks
底下之外,你也可以透過 git config 去設定
1
$ git config core.hooksPath MYPATH
Example
以我自己來說,安裝 git hook 這件事情我會寫成 Makefile 執行,然後呼叫安裝的 script 自動安裝
考慮以下安裝 script
1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/sh
if ! test -d .git; then
echo "Execute scripts/install-git-hooks in the top-level directory"
exit 1
fi
ln -sf ../../scripts/pre-commit.hook .git/hooks/pre-commit || exit 1
chmod +x ./scripts/pre-commit.hook
echo
echo "Git hooks are installed successfully"
可以看到以上做的事情相對單純,首先先檢查 .git 資料夾是否存在,之後再將 pre-commit.hook 檔案以 symbolic link 的方式安裝進 ./git/hook 中
注意到不可直接將 scripts/pre-commit.hook
安裝進去,會無法正確 trigger
最後在加上 execute 的權限即可
而 pre-commit.hook 的內容如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
RED='\033[0;31m'
NC='\033[0m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
echo -e "${YELLOW}Auto CI for all data structures${NC}"
bash ./ci.sh
if [ "$?" -eq 0 ]; then
echo -e "${GREEN}CI check done${NC}"
else
echo -e "${RED}CI check failed${NC}"
fi
這個例子是針對所有子專案進行 compile 看說有沒有 compiler error 而已
在安裝了 pre-commit hook 之後每次執行 git commit
之前就會先跑一遍 local build 了
除此之外你也可以做比如說像是 format code 之類的事情
Leave a comment