Hook اسکریپتی است که Git در لحظههای مشخص (مثلاً قبل از commit) اجرا میکند. اگر اسکریپت با خطا خارج شود، آن commit یا push انجام نمیشود.
🎯 اهداف یادگیری
- hook محلی را از hook سمت سرور جدا کنی
- بدانی
.git/hooksپوشیدنی نیست - Husky / pre-commit framework را برای تیم بچینی
- محدودیت hook را بشناسی (قابل دور زدن است)
🪝 Git hooks کجایند؟
.git/hooks/ نمونههای *.sample دارد. فعالسازی = حذف پسوند و اجرایی کردن.
cat > .git/hooks/pre-commit << 'EOF' #!/usr/bin/env bash set -euo pipefail files=$(git diff --cached --name-only || true) if printf '%s\n' "$files" | grep -Eq '(^|/)\.env$'; then echo "do not commit .env" >&2 exit 1 fi exit 0 EOF chmod +x .git/hooks/pre-commit
اگر بنویسی echo "$files" | grep ... && exit 1 بدون if، وقتی .env در stage نیست grep کد ۱ برمیگرداند و set -e کل هوک را شکست میدهد — یعنی هیچ کامیتی رد نمیشود. الگوی if grep; then exit 1; fi را استفاده کن.
مشکل: این فایل در مخزن نیست. همکار تو hook ندارد.
📦 راهحل تیمی ۲۰۲۶
| ابزار | مناسب |
|---|---|
| Husky + lint-staged | اکوسیستم JS |
| pre-commit (Python framework) | چندزبانه، YAML |
| lefthook | سریع، Go، موازی |
| GitHub Rulesets | اجبار سمت سرور — دورزدنی نیست |
{ "scripts": { "prepare": "husky" } }
npx --no -- commitlint --edit "$1"
export default { extends: ["@commitlint/config-conventional"] };
npx lint-staged
lint-staged فقط روی فایلهای staged اجرا میشود — سریع.
🛡️ سمت سرور
Hook محلی با --no-verify دور زده میشود. برای قانون واقعی:
- Ruleset: Conventional؟ خیر — پیام را GitHub اجباری نمیکند مگر Status Check
- Status Check: job
commitlintروی PR - Push rules: جلوگیری از
--forceروی main - CodeQL / secret scanning
برای hotfix وسوسهانگیز است. اگر لازم شد، در PR توضیح بده و CI را اجباری بگذار تا دروازهٔ دوم کار کند.
🔌 VS Code
وظایف lint-staged هنگام Commit از UI هم اجرا میشوند چون همان git commit را صدا میزنند. اگر hook شکست بخورد، VS Code خطا را در Git Output نشان میدهد.
Junior — hook را چطور به GitHub میفرستم؟ نمیفرستی؛ نسخه را در ابزار تیمی (Husky) داخل ریپو میگذاری.
Senior — server-side hook در GitHub؟ GitHub.com hook سفارشی Git ندارد؛ از webhooks، Actions و Rulesets استفاده کن. GitHub Enterprise Server گاهی pre-receive دارد.
✅ چکلیست فهم
- میدانی hook محلی قابل دور زدن است
- commitlint روی پیام Conventional است
- CI همان قانون را تکرار میکند
فصل بعد: امضا، 2FA، passkey و رازها.