pre-push hook chạy trước khi git push — có thể block push nếu tests fail.
Trade-off chính:
- Bảo vệ remote branch khỏi broken code
- Nhưng full test suite có thể mất 5-10 phút → developers làm theo cách khác (push thẳng không qua hook)
Setup thực tế — chỉ chạy tests liên quan:
# .husky/pre-push:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
# Lấy danh sách files đang thay đổi so với main:
CHANGED=$(git diff --name-only origin/main HEAD | grep -E "\.(ts|tsx)$")
if [ -n "$CHANGED" ]; then
# Chỉ chạy tests của files bị thay đổi:
npx jest --findRelatedTests $CHANGED --passWithNoTests
fiHoặc chạy fast subset:
npm run test:unit # unit tests only (~30s), không integration testsPattern phổ biến: pre-commit → lint/format (fast), pre-push → unit tests (medium), CI → full test suite (slow).
Client hooks vs Server hooks:
- Client hooks: developer có thể bypass (--no-verify)
- Server hooks (GitHub Actions): không thể bypass, bắt buộc
- Recommendation: pre-push là safety net cho developer bản thân, CI là enforcement thực sự
Bypass khi cần:
git push --no-verify # skip pre-push hookpre-push hook runs before git push — it can block the push if tests fail.
Main trade-off:
- Protects remote branches from broken code
- But a full test suite can take 5-10 minutes → developers work around it (push directly bypassing the hook)
Practical setup — only run relevant tests:
# .husky/pre-push:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
# Get files changed vs main:
CHANGED=$(git diff --name-only origin/main HEAD | grep -E "\.(ts|tsx)$")
if [ -n "$CHANGED" ]; then
# Only run tests for changed files:
npx jest --findRelatedTests $CHANGED --passWithNoTests
fiOr run a fast subset:
npm run test:unit # unit tests only (~30s), no integration testsCommon pattern: pre-commit → lint/format (fast), pre-push → unit tests (medium), CI → full test suite (slow).
Client hooks vs Server hooks:
- Client hooks: developers can bypass (--no-verify)
- Server hooks (GitHub Actions): cannot be bypassed, mandatory
- Recommendation: pre-push is a safety net for the developer themselves, CI is the real enforcement
Bypass when needed:
git push --no-verify # skip pre-push hook