Git Hooks是一種非常強大的改進開發工作流的方法,不需要記住運行額外的腳本或執行額外的任務。本文介紹如何在項目倉庫中自定義git Hooks實現對Go代碼的格式化。
這個例子可以讓你知道如何在自己的的項目中使用git Hooks。
實際案例
這方面的一個例子來自我當前的一個項目,在這個項目中,團隊必須在將密匙文件推入項目倉庫之前對它們進行加密。加密文件本身就一行代碼的事,但由于我們項目中密匙文件的數量大了,要記住每個修改過的密匙文件,變成了一個挑戰,我們會為沒有重新加密密匙文件而抓狂。
解決方案
當我們試圖解決這個問題時,我們能夠使用的工具相當有限,并且我們不希望使用那些可能對部分有自己開發習慣的團隊成員造成影響。這就是Git Hooks發揮作用的地方了。有了Git Hooks,可以定義一個簡單的“pre-commit” hook腳本,它將自動執行對未加密的密匙文件的加密,并添加到commit任務中去。可以通過在hooks/目錄中創建這些hooks,讓它成為團隊開發流程中的可選插件,這樣如果想把這些hooks添加到他們自己的開發流程中的話,可以通過一個簡單的命令(git config core.hooksPath hooks)配置即可。
創建Git Hook
Hooks實際上創建起來非常簡單,因為它們只是在特定目錄中具有特定名稱的bash腳本。當您下次執行給定的git命令時,它將自動執行這個bash腳本,前提是該腳本是對應特定命令的正確命名文件。
先進入到項目的代碼倉庫進入.git隱藏目錄,可以看到如下目錄和文件:
root@CloudEdge1:/home/zjlab/goRestAPI-docker/.git# ls -l
total 48
drwxr-xr-x 2 root root 4096 Feb 24 09:37 branches
-rw-r--r-- 1 root root 261 Feb 24 10:51 COMMIT_EDITMSG
-rw-r--r-- 1 root root 275 Feb 24 09:37 config
-rw-r--r-- 1 root root 73 Feb 24 09:37 description
-rw-r--r-- 1 root root 21 Feb 24 09:37 HEAD
drwxr-xr-x 2 root root 4096 Feb 24 09:37 hooks
-rw-r--r-- 1 root root 642 Feb 24 10:45 index
drwxr-xr-x 2 root root 4096 Feb 24 09:37 info
drwxr-xr-x 3 root root 4096 Feb 24 09:37 logs
drwxr-xr-x 19 root root 4096 Feb 24 10:45 objects
-rw-r--r-- 1 root root 112 Feb 24 09:37 packed-refs
drwxr-xr-x 5 root root 4096 Feb 24 09:37 refs
上面有個hooks目錄,就是存放我們將要定義的Git hooks腳本的目錄:
root@CloudEdge1:/home/zjlab/goRestAPI-docker/.git/hooks# ls -l
total 48
-rwxr-xr-x 1 root root 478 Feb 24 09:37 applypatch-msg.sample
-rwxr-xr-x 1 root root 896 Feb 24 09:37 commit-msg.sample
-rwxr-xr-x 1 root root 3327 Feb 24 09:37 fsmonitor-watchman.sample
-rwxr-xr-x 1 root root 189 Feb 24 09:37 post-update.sample
-rwxr-xr-x 1 root root 424 Feb 24 09:37 pre-applypatch.sample
-rwxr-xr-x 1 root root 1642 Feb 24 09:37 pre-commit.sample
-rwxr-xr-x 1 root root 1492 Feb 24 09:37 prepare-commit-msg.sample
-rwxr-xr-x 1 root root 1348 Feb 24 09:37 pre-push.sample
-rwxr-xr-x 1 root root 4898 Feb 24 09:37 pre-rebase.sample
-rwxr-xr-x 1 root root 544 Feb 24 09:37 pre-receive.sample
-rwxr-xr-x 1 root root 3610 Feb 24 09:37 update.sample
下面我們創建格式化Go代碼的bash腳本,并命名為pre-commit,因為我們是針對git commit命令創建的hooks,也就是在提交代碼前,對Go文件進行格式化。
.git/hooks/pre-commit
#!/bin/bash
echo "Test Hook"
## this will retrieve all of the .go files that have been
## changed since the last commit
STAGED_GO_FILES=$(git diff --cached --name-only -- '*.go')
## we can check to see if this is empty
if [[ $STAGED_GO_FILES == "" ]]; then
echo "No Go Files to Update"
## otherwise we can do stuff with these changed go files
else
for file in $STAGED_GO_FILES; do
## format our file
go fmt $file
## add any potential changes from our formatting to the
## commit
git add $file
done
fi
現在我們保存任何go代碼文件并執行add和commit提交命令,都會自動將使用go fmt命令對go文件進行格式化,然后再提交。
在團隊中分發Git Hooks
因為我們的Git Hook保存在hooks/目錄中,并不能自動分發到其他的開發者。需要在項目中創建一個.githooks/目錄,然后將前面的pre-commit腳本保存到這個目錄。這樣就可以同其他文件一樣提交并跟蹤這個腳本,如果要讓這個hooks腳本在其他開發者的環境中生效,還需要執行如下命令:
$ git config core.hooksPath .githooks