執行 Git 勾點

已完成

在開發流程中優先考量程式碼品質應從本機程式碼開發開始。 請務必針對此做法找出機會,甚至在開始提起要求以偵測並修正潛在程式碼品質問題之前就進行。

Git 勾點提供絕佳的機會。 其可作為執行自訂指令碼的機制,以回應 Git 生命週期內的重大事件,例如認可、合併和推送。 指令碼位於存放庫的 .git\hooks 目錄,在自動化軟體開發工作和強制執行開發標準方面提供幾乎無限制的彈性。

如何實作 Git 勾點

首先,我們得探索用戶端的 Git 勾點。 瀏覽至存放庫 .git\hooks 目錄,您可在這裡找到許多副檔名為 sample 的檔案。 此副檔名不僅表示其用途,而也可有效防止執行。 檔案名稱指定在移除 sample 副檔名後觸發執行的 Git 動作。

適用於自動化的 Git 勾點檔案螢幕擷取畫面。

將 pre-commit sample 檔案重新命名為 pre-commit。 如檔案名稱所示,每當您叫用 git commit 動作時,便會執行檔案名稱所包含的指令碼。 僅當 pre-commit 指令碼以 0 傳回值結束時,才會遵循認可。

然而,請務必注意,依預設,這在任何 Windows 作業系統中都無法如預期運作。 此行為常被忽略的原因是其位於指令碼的第一行:

#!/bin/sh

Linux 作業系統為 #! 前置詞向程式載入器指示檔案其餘部分包含要解譯的指令碼,而 /bin/sh 是應使用解譯器的完整路徑。

即使 Git for Windows 支援 Bash 命令和殼層指令碼,但指定檔案系統路徑時不會遵循相同慣例。 相反地,您必須提供 sh.exe 檔案的完整路徑,以磁碟機代號為開頭。

但有額外的注意事項,這將造成 Git for Windows 預設安裝在 C:\Program 檔案目錄中。 由於此目錄的名稱包含空格,因此 sh.exe 檔案的產生路徑會解譯為兩個不同的路徑,進而導致失敗。 若要避免,您必須在空格前面新增單反斜線 (\) 作為逸出字元。 實際上,使用 64 位元版本的 Git for Windows 時,指令碼的第一行應有下列格式:

#!C:/Program\ Files/Git/usr/bin/sh.exe

如何執行此動作

如何使用新探索的 Git pre-commit 指令碼功能? 如何防止不小心將祕密洩露至 GitHub?

讓我們使用 Git 勾點來掃描本機存放庫中認可的程式碼,取得特定關鍵字。 請以下列程式碼取代 pre-commit 殼層檔案中的內容:

#!C:/Program\ Files/Git/usr/bin/sh.exe
matches=$(git diff-index --patch HEAD | grep '^+' | grep -Pi 'password|secret')
if [ ! -z "$matches" ]
then
  cat <<\EOT
Error: Words from the blocked list were present in the diff:
EOT
echo $matches
exit 1
fi

此範例旨在說明概念 (而非完整的解決方案),因此關鍵字清單是刻意簡化。 您可使用規則運算式以大幅延伸其範圍和彈性。 您也可選擇參考外部檔案,如此可大幅簡化進行中的維護。

運作方式

叫用後,pre-commit 勾點指令碼使用 git diff 和 grep 命令來識別所認可程式碼累加變更內的關鍵字或模式。 如果偵測到相符項目,則指令碼會產生錯誤訊息並防止進行認可。

還有更多:

pre-commit 勾點指令碼的其他常見使用案例包含程式碼格式化、Lint 分析或執行自訂測試,以確保認可遵循專案標準。 在啟動認可訊息編輯器前,執行 Prepare-commit-msg。 這可允許動態產生認可訊息以強制執行命名慣例,例如使用指定的前置詞 (例如,feat: 代表功能 (features) 或 fix: 代表錯誤修正 (bug fixes))。

例如,下列 prepare-commit-msg 指令碼會在建立新認可時,自動在認可訊息前面加上最新分支名稱。 透過在檔案開頭新增分支名稱並在後面加上冒號和空格,藉此修改認可訊息檔案 ($1)。

#!C:/Program\ Files/Git/usr/bin/sh.exe
# Get the current branch name
branch_name=$(git branch --show-current)
# Check if the commit message file exists
if [[ -f "$1" ]]; then
  # Prepend the branch name to the commit message
  sed -i "1s/^/$branch_name: /" "$1"
fi

Post-commit 指令碼會在認可完成後執行。 其可用於觸發通知或產生文件。

例如,下列指令碼會在每次認可後將電子郵件通知傳送至指定的收件者。 您可以修改收件者電子郵件地址、SMTP 伺服器和電子郵件的主旨與本文,藉此自訂指令碼。 此外,您可能需要設定系統以使用 Send-MailMessage PowerShell Cmdlet 傳送電子郵件或使用不同的方法傳送通知,視您的環境和需求而定。

#!C:/Program\ Files/Git/usr/bin/sh.exe
# Set the recipient email address
$recipient="your@email.com"
# Set the subject of the email
$subject="Git Commit Notification"
# Set the body of the email
$body="A new commit has been made to the repository."
# Send the email notification
Send-MailMessage -To $recipient -Subject $subject -Body $body -SmtpServer "your.smtp.server"

值得注意的是,未將 repo.git\hooks 資料夾認可至原始檔控制。 您可能想了解是否有方法可與開發小組的其他成員共用所開發的指令碼。 好消息是,自 Git 版本 2.9 開始,您可以將 Git 勾點對應到可被原始檔控制認可的資料夾。 您可以更新 Git 存放庫的全域設定來執行這項作業:

Git config --global core.hooksPath '~/.githooks'

若您需要覆寫您在用戶端設定的 Git 勾點,您可以使用無驗證切換來執行這項作業:

Git commit --no-verify

伺服器端勾點

即使伺服器端 Git 勾點提供強大功能以增強開發工作流程,Azure Repos 也提供伺服器端勾點以進一步增強開發流程,包含支援建立提取要求。 如需詳細資訊,請參閱 Azure Repos 服務掛勾事件參考。