在Windows上使用Python script git hook

之前在工作上其實就有碰到需要使用 git hook 的時候,那時候有發現,在 Linux 和 MacOS 上執行順暢的 hook,到了 Windows 上卻完全不管用。當時因為在 Windows 上執行的需求不強,就暫時擱置到現在,有需要了,就開始認真研究。

研究後發現 Windows 的不僅要繞一個彎,還有很多奇怪的小問題,不過目前實作起來還好,就順手記錄下提供給有需要的人參考。

前置作業

本文不講解 git hook 是做什麼用途或是可以幹嘛的,假定你已經寫好一個 hook 了,那麼就可以繼續往下看;還沒的話,後面的步驟就只能先備而不用了。

本文使用 Python 寫成的 commit-msg hook 做示範,檔案就是直接複製 sample 出來寫的 commit-msg

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/env python3


import re
import sys


sys.stdout.reconfigure(encoding='utf-8')


with open(sys.argv[1], encoding = "utf-8") as cm: # commit message
lines = cm.readlines()
if not re.search(r'^([a-z].{1,}:) .{1,}', lines[0]):
print("Fail!")
exit(1)

實作

以下都以剛剛提到的規格講解,請自己代換成自己的規格。

有兩步驟,做好就完成了:

  1. 原本的 hook 改名(但不可和 hook 規範衝突)
  2. 複製出新的 hook 來執行實際邏輯所在的檔案

下面是詳細說明。

hook改名

將原本的 Python commit-msg hook 從 commit-msg 改名為 commit-msg.py。例如你是用 Node 寫的,那可能就是改成 commit-msg.js 這樣的感覺。

總之就是要和原本的 hook 名稱不一樣或是不和規定好的 hook 命名規範衝突即可。

複製新hook

把原本的 commit-msg.sample 複製出來成新的 hook,除了 shebang 外的東西都可刪除(shebang 不用變更),然後看要怎麼執行你剛剛改名好的檢查邏輯所在的檔案。以本文範例是 Python 來說:

1
2
3
4
5
6
7
8
9
10
11
#!/bin/sh

# 不同作業系統的 Python 名稱或別名不同
if [ "$OSTYPE" == "msys" ]; then
python='py'
else
python='python3'
fi

# 因為 commit-msg hook 需要一個參數讓提交訊息傳入,所以給他第一個變數作為參數傳進去
${python} .git/hooks/commit-msg.py $1

如果不是從 sample 複製出來的話,要注意下面幾件事(推薦使用台灣之光 Notepad++ 查看):

  1. shebang 要是 #!/bin/sh(或 bash 應該也可以,但我走 git 範本檔案)
  2. 換行符號格式請一定要維持 Unix(LF) 實測 CR LF 也是可以動
  3. 如果 hook 有需要額外的參數,請在這邊一併加上

新 hook 檔案範例

結語

其實就是這麼簡單,如果要的話可以歸納成一句話:

做一個新的 hook ,裡面寫要執行的 hook 指令

不知道是 Windows 不認識 shebang 還是怎樣,反正就是要繞個彎來做。有點像是當 sudo 被限制的時候,就用 sudo bash <script> 來突破看看的感覺XD

今天簡單教學就到這邊,網路上有另外一位大大的中文教學是直接寫 shell 的就不用這麼麻煩,此篇是給使用 Python、Node 等使用除了 shell 外的使用者看的。希望大家都能順利完成,我們下次見。

參考資料