介紹
Git 掛鉤是可執行腳本,在 Git 生命週期中的特定積分處自動執行。雖然許多開發人員僅將它們與程式碼格式化和 linting 聯繫起來,但它們的潛力遠遠超出了工作流程自動化、專案管理和團隊協作。本文探討如何利用 Git hook 來實現全面的自動化策略。
了解 Git Hook
Git 掛鉤駐留在每個儲存庫的 .git/hooks/ 目錄中。它們是用任何語言(bash、Python、Node.js 或 Ruby)編寫的標準可執行腳本。鉤子分為兩類:在開發人員的機器上運行的客戶端鉤子(預提交、預推送、提交訊息),以及在遠端儲存庫上執行的伺服器端鉤子(預接收、更新、後接收)。
鉤子生命週期按時間順序跟隨 Git 操作。在提交期間,掛鉤會依照下列順序執行:pre-commit → commit-msg → post-commit。對於推送,順序為 pre-push(客戶端)→ pre-receive → update → post-receive(伺服器)。
與 Husky 設定 Hook
透過將腳本放置在 .git/hooks/ 中來手動管理掛鉤對於團隊來說是不切實際的,因為 Git 不追蹤該目錄。 Husky 透過允許在儲存庫中配置掛鉤並在團隊中共享來解決這個問題。
Husky v9+ 的安裝非常簡單:
npx husky init
這將建立一個 .husky/ 目錄,其中掛鉤腳本是純文字檔案:
# .husky/pre-commit
npx lint-staged
對於 CI 環境,可以透過設定 HUSKY=0 來跳過鉤子:
HUSKY=0 git push
整合 lint-staged
Lint-staged 僅在暫存檔案上執行 linter,從而保持快速的預提交檢查:
{
"lint-staged": {
"*.{ts,tsx}": ["eslint --fix", "prettier --write"],
"*.{css,scss}": ["stylelint --fix", "prettier --write"]
}
}
預提交掛鉤:第一道防線
預提交掛鉤在每次提交之前執行,非常適合快速、本地化檢查。
| 檢查類型 | 工具 | 目的 |
|---|---|---|
| 絨毛 | ESLint、stylelint | 執行程式碼風格標準 |
| 格式化 | 更漂亮,dprint | 一致地自動格式化程式碼 |
| 類型檢查 | 打字稿 --noEmit | 及早發現類型錯誤 |
| 秘密偵查 | Secretlint,松露Hog | 防止憑證外洩 |
| 檔案驗證 | 自訂腳本 | 封鎖大檔案或 TODO 提交 |
全面的預提交配置:
# .husky/pre-commit
npx lint-staged
npx tsc --noEmit
npx secretlint "**/*"
效能至關重要 - 預提交掛鉤應在五秒鐘內完成,以避免中斷開發流程。
預推掛鉤:CI 安全網
預推送掛鉤在程式碼到達遠端儲存庫之前運行,這使得它們非常適合長時間運行的驗證:
# .husky/pre-push
npm test
npm run build
npm audit
分支命名驗證確保整個團隊的一致性:
#!/bin/sh
branch=$(git rev-parse --abbrev-ref HEAD)
if ! echo "$branch" | grep -qE '^(feature|bugfix|hotfix)/[A-Z]+-[0-9]+-'; then
echo "Error: Branch name must match feature/ABC-123-description"
exit 1
fi
使用 commitlint 進行提交訊息掛鉤
強制執行傳統的提交訊息可確保一致的、可解析的歷史記錄。將 commitlint 與 Husky 一起使用:
# .husky/commit-msg
npx --no -- commitlint --edit $1
在 commitlint.config.js 中配置 commitlint:
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'subject-max-length': [2, 'always', 50],
'body-max-line-length': [2, 'always', 72],
},
};
有效的提交訊息遵循 <type>(<scope>): <description> 格式:
feat(auth): implement OAuth 2.0 refresh token rotation
fix(api): handle null pointer in user deserialization
docs(readme): update installation instructions
提交後和合併後掛鉤
合併後掛鉤對於依賴管理特別有用。當鎖定檔案變更時自動安裝更新的依賴項:
# .husky/post-merge
changed=$(git diff HEAD~1 --name-only)
if echo "$changed" | grep -q "pnpm-lock.yaml"; then
pnpm install
fi
CI 等效策略
最穩健的模式可確保鉤子和 CI 運行相同的檢查。提取兩個環境呼叫的共享腳本:
#!/bin/sh
# scripts/validate.sh - called by both hooks and CI
npm run lint
npm run typecheck
npm test
本地鉤子應該在可能的情況下發出警告或自動修復,而 CI 則嚴格執行。這創建了一個安全網:開發人員在推送之前發現問題,而 CI 捕獲任何漏掉的東西。
結論
Git hooks 是一個強大的自動化層,其功能遠遠超出了程式碼格式化的範圍。將 Husky 與 lint-staged 結合起來為大多數項目提供了建議的基線。預推送鉤子在程式碼到達 CI 之前添加了一個安全網,並且 commitlint 確保了乾淨、可解析的提交歷史記錄。最終目標是提供無縫的開發人員體驗,其中自動化處理重複檢查,使團隊能夠專注於邏輯和設計。

