什麼是 Git Hooks?為什麼它這麼萬能?
前幾天在工作上看到別的組用了一個叫做 git hooks 的東西,在這之前我完全沒有聽過這個工具。
所以我就花一點時間查了一下 git hooks 可以做什麼,才發現原來他的功能這麼強大!
那今天我們就來看看這工具到底是什麼吧!
什麼是 Git Hooks
第一件事當然就是要來了解什麼是 git hooks 啦!
簡單來說,它就是一個自動化腳本,每當特定的事件發生時,git 就會執行這些腳本。我們則可以藉由編輯這些腳本做到幾乎各種事情!
比如說,我們可以用這些腳本執行重複的任務、提升程式碼品質、自動測試等等。
我們可以在 .git/hooks
這個資料夾中找到這些腳本。
基本上,git hooks 分為兩種:
- local 本地端
- server 私服器端
本地端的 hooks 著重於和使用者互動,基本上在做 git commit 和 git merge 時會進行。
server 私服器端私服器端的 hooks 則著重於網路操作上的互動,基本上是在收到使用者推送的 git push 時會進行。
使用 Git Hooks
那麼我們該如何開始使用 git hooks 呢?
前面說到,這些 hooks 儲存在 .git/hooks
的資料夾底下,這個資料夾是每個 git repository 都會有的。
在一開始做 git init
時,git 就會自動幫我們創建好這個資料夾,並連到創建一系列 hooks 作為範例。
我們可以在這個資料夾底下看到類似這樣的文件:
pre-push.sample pre-rebase.sample commit-msg.sample post-update.sample prepare-commit-msg.sample pre-commit.sample
這些 .sample
結尾的文件,都是一個 git hook,並會在特定事件發生時才會執行。
比如說,pre-commit
的 hook 就會在使用者執行 git commit
之前被執行。
想要讓這些 hook 發揮功能,我們就必須先移掉 .sample
,由 pre-commit.sample
變成 pre-commit
,這樣這個 hook 才會發揮功能。
接下來,我們來講一些常被使用到的 git hooks!
常見的 git hooks
這邊我們主要來講本地端的 hooks,因為這和作為開發者的我們最為相關。
我們會來介紹三個常見的 hooks,分別是:
pre-commit
commit-msg
pre-push
pre-commit
這是一個非常常用的 hook,因為這類的 hook 可以在使用者在 commit 時做一些檢查。
這些檢查包括自動格式化程式碼、自動測試等等。
接下來我們來看一個超級簡單的例子,這個例子讓我們在 commit 的時候輸出一則訊息。
編寫 pre-commit首先,我們要來編寫 pre-commit
這個檔案
cd .git/hooks vim pre-commit
接著,我們複製貼上以下程式碼:
#!/bin/bash echo "This is a pre-commit hook!"轉為執行檔
讓這個 pre-commit
hook 成為可以被執行的執行檔
chmod +x pre-commit
這樣就完成啦!我們接著可以自己試著做出一個 commit,並看看是否有訊息印出。
當然,我們可以看到類似這樣的訊息。
This is a pre-commit hook! On branch main nothing to commit, working tree clean
commit-msg
這個 hook 常常被用來統一 commit message 的格式。
如果公司或是團隊對於每個人提交的 commit 訊息有特定的要求,比如說字數、大小寫開頭等等,那就可以使用這個 hook。
編寫 commit-msg一樣,我們需要編寫一個叫 commit-msg
的 hook。
cd .git/hooks vim commit-msg
接著,我們來做一個 hook,這個 hook 會要求 commit message 都是大寫開頭,並且至少有 10 個字母。
#!/bin/bash commit_message=$(cat "$1") # Check if commit message starts with a capital letter and is at least 10 characters long if ! [[ $commit_message =~ ^[A-Z] ]] || [[ ${#commit_message} -lt 10 ]]; then echo "Error: Commit message must start with a capital letter and be at least 10 characters long." exit 1 fi轉為執行檔
讓這個 commit-msg
hook 成為可以被執行的執行檔
chmod +x commit-msg
而當我們給予的 commit message 不符合規範時,比如說:
git commit -m "test"
這樣這個 commit 就不會通過,而會出現以下的錯誤訊息:
Error: Commit message must start with a capital letter and be at least 10 characters long.
pre-push
第三個也是一個常用的 hook,這個 hook 是在我們做 push 時被執行的。
常用的情況比如說,在 push 前進行某些測試,如果測試通過就推送到遠端私服器,否則就取消執行。
編寫 pre-push這邊我們就直接給上範例的檔案啦!
#!/bin/bash # Run the test suite echo "Running tests..." if ! ./run-tests.sh; then echo "Tests failed. Push aborted." exit 1 fi echo "Tests passed. Proceeding with push."
這裡我們看到,它會執行一個叫做 run-tests.sh
的執行檔。
在這個檔案中,我們可以定義測試,或是可以再另外呼叫其他檔案。
唯有這個測試通過了,我們的 push 才會被執行。
git hooks 的作用域
理解了 git hooks 的功能後,我們還要來了解一個重要的觀念。
前面講到的那些 git hooks 的作用域啊,都只是在本地端而已!
一般來說,儲存在 .git/
資料夾下的檔案,git 都不會推送到遠端的私服器,而因為 git hooks 存放在 .git/
資料夾,因此你所做的 hooks 只會在你的電腦上運行。
那麼問題來了,如果我們想要在團隊中,強制每個人在做 git commit
之前,都遵守某個特定規則的話,該怎麼辦呢?
這裡有兩個方法:
- 統一 git hook
- 分享 git hook
我們可以要求每個人的電腦上的 git hook 文件都長的一樣,這樣一來就可以讓每個人都遵守一樣的規則了。
但這樣的缺點也顯而易見,當某天某個 git hook 需要更改時,每個人的電腦都要進行手動更改。這相當耗時而且容易出錯。
那有沒有更好的方法呢?
分享 git hook我們可以建立一個 hooks/
的檔案夾,並讓所有人共用!具體步驟如下:
1. 建立 hooks/
檔案夾,並將位於 .git/hooks
中的 hooks 拖移到其中。
mkdir hooks mv .git/hooks/pre-commit hooks/ mv .git/hooks/commit-msg hooks/ mv .git/hooks/post-commit hooks/
2. 設定 git 查看 hooks 的路徑
git config core.hooksPath hooks
如此一來,當其他人在使用這個專案時,就會自動使用位於 hooks/
檔案夾中的 hooks 執行檔!
是不是比第一種方法既有效率又保險的多!
結尾
這樣我們就介紹完基本的 git hooks 啦!
簡單來說,它就是一個自動化腳本,每當特定的事件發生時,git 就會執行這些腳本。
我們則可以藉由編輯這些腳本做到幾乎各種事情!
但其實,這篇文章指介紹了一半的 hooks,還有另一半作用於 server 端的 hooks 我們沒有介紹。
如果有興趣的人可以去看這篇更詳細的 Atlassian Git hooks 教學文章!
那這篇文章就到這裡啦~
以後我們還會再繼續介紹更多和 git 有關的知識和技術!
有學到東西的話歡迎給五星評價喔!