Last Updated: May 1, 2025
Common Client Hooks
| Hook | When It Runs | Common Use |
|---|---|---|
| pre-commit | Before commit message editor | Lint, format, run unit tests |
| prepare-commit-msg | After editor, before commit | Auto-generate message template |
| commit-msg | After message is written | Validate commit message format |
| post-commit | After commit completes | Notification, update issue tracker |
| pre-rebase | Before rebase starts | Prevent rebase of protected branches |
| post-checkout | After checkout/switch | Set up project-specific config |
| post-merge | After a successful merge | Run migrations, update dependencies |
| pre-push | Before push to remote | Run full test suite, security scan |
Hook Examples
#!/bin/shEvery hook starts with a shebang line
npm run lintPre-commit: run linter, reject on failure
npm testPre-push: run full test suite before allowing push
grep -qE '^(feat|fix|docs)' $1Commit-msg: enforce conventional commit format
branch=$(git rev-parse --abbrev-ref HEAD)Post-checkout: detect current branch
npm installPost-merge: auto-install new dependencies
git diff --cached --name-onlyPre-commit: list files about to be committed
exec < /dev/ttyPre-commit: enable interactive prompts in hooks
Setting Up Hooks
chmod +x .git/hooks/pre-commitMake a hook executable (required!)
cp hooks/pre-commit .git/hooks/Copy a custom hook into place
nano .git/hooks/commit-msgCreate or edit a hook with any editor
git config core.hooksPath hooks/Redirect Git to look for hooks in hooks/ dir
ls -la .git/hooks/List all hooks (sample hooks end in .sample)
cp -r hooks/ .git/hooks/ && chmod +x .git/hooks/*Bulk install shared hooks
Server-Side Hooks
| Item | Description |
|---|---|
pre-receive | Runs on remote before refs are updated — gatekeeper for pushes |
update | Runs once per branch being pushed; can reject per-branch |
post-receive | Runs after push completes — trigger CI, deploy, notifications |
Bare Repositories | Server hooks only work in bare repos (git init --bare) |
Protected Branches | Use pre-receive to block force-push to main/master |
Deploy on Push | post-receive: checkout to web root for simple deployments |
Email Notifications | post-receive: send email to team on push |
Audit Logging | update: log who pushed what to which branch |
Pro Tip: Share hooks with your team using a script in the repo that symlinks .git/hooks/ to a tracked hooks/ directory.