Categories
野人獻曝

Git hooks 的執行腳本管理

Git hooks 是 git 在開發流程上很有用的機制,以其中的 pre-commit 來說,最為人熟知的用途就是在 commit 前自動執行測試,以檢查新增的內容是否有缺失。此外還有其它促進團隊協作的用法,例如檢查 commit message 是否合乎規定的格式,或是禁止直接 commit 到 master branch 等等。

像我的話,就因為常常忘記把新增的檔案 commit 進去,撇開之後又要補上去的麻煩不說,也會給協同開發的其他人帶來困擾,所以就簡單地檢查一下是不是有 Untracked files 出現:

#!/bin/sh
status="$(git ls-files -o --directory --exclude-standard | wc -l)"
if [ $status -gt 0 ]; then
  echo "You have untracked files, use --no-verify option to continue committing anyway."
  git ls-files -o --directory --exclude-standard | while read line; do echo -e "  \e[01;31m$line\e[0m"; done
  exit 1
else  
  exit 0
fi

把以上內容存成 repository 底下的 .git/hooks/pre-commit 並且加上執行權限就可以了。

雖然有設定 init.templatedir 指定模板檔案資料夾的方式讓開新專案執行 git init 的時候可以自動套上自己使用的 hooks 腳本,但是在團隊協作時要讓大家都能執行到同樣一套 hooks 腳本就是個要好好處理的課題了。

由於 git 並沒有其它設定 hooks 的方式,一般的作法是在 repository 中放置一個 .githooks 之類的資料夾來擺放這些腳本,然後再自行複製或被連結到 .git/hooks 底下。

當然能夠自動化並確保所有人都有安裝上是最好的,例如 npm 有提供設定 postinstall 的機制,寫在 package.json 的 scripts 區塊裡就能讓複製的動作在 npm install 完成後執行。

不過專案使用的 hooks 腳本總是會隨著開發進展有所更新改動,可以借助 grunt-githooks 這類的工具來更新並達成更加完善的管理。

至於 Rails 專案方面,由於 bundler 目前沒有提供 postinstall 處理,我想只能透過自己寫一個 rubygem 的方式來解決。

最後提醒一個要考慮的重點是 Windows 平台上無法執行 bash script,所以最好用專案本身使用的語言來撰寫指令腳本以方便執行。