Chapter 8.1 — What are Git Hooks☕ 12 min read

What are Git Hooks

Hooks = tumhare repo mein tripwires. Step karo, script trigger ho. Quality automatic, manual nahi.

01Git Hooks: Automation at Trigger Points

Git hooks are scripts that run automatically when certain Git events occur.

They let you enforce rules, automate checks, and trigger actions without manual intervention.

Think of them as tripwires: when a developer runs git commit, the pre-commit hook fires BEFORE the commit is created.

If the hook script exits with code 0, the Git operation proceeds. If exit code is non-zero, the operation is BLOCKED.

Hooks live in .git/hooks/ directory. Git creates sample hooks there when you run git init.

Sample hooks end with .sample extension — they are disabled by default. Remove .sample to activate.

Hooks must be executable: chmod +x .git/hooks/pre-commit. Without execute permission, Git ignores them.

Hooks can be written in ANY language: bash, Python, Node.js, Ruby — as long as the file is executable.

# See sample hooks in any Git repository
ls .git/hooks/
# applypatch-msg.sample  pre-commit.sample  pre-push.sample  ...
# These are INACTIVE (end with .sample)

# Activate a hook by removing .sample extension
mv .git/hooks/pre-commit.sample .git/hooks/pre-commit

# Make it executable (required!)
chmod +x .git/hooks/pre-commit

# Now every `git commit` will run this script first
# If script exits 0 → commit proceeds
# If script exits 1 → commit is BLOCKED

# Test it — create a hook that blocks all commits
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
echo "🚫 Commits are blocked on this machine!"
exit 1
EOF
chmod +x .git/hooks/pre-commit

# Try to commit
git commit -m "test"
# 🚫 Commits are blocked on this machine!
# Commit FAILED — hook blocked it
02Client-Side vs Server-Side Hooks

Client-side hooks: run on the DEVELOPER'S machine. Developer controls them (can bypass with --no-verify).

Server-side hooks: run on the GIT SERVER (GitHub, GitLab, self-hosted). CANNOT be bypassed by developers.

Client-side hooks are for PERSONAL automation and team conventions (linting, formatting).

Server-side hooks are for ENFORCED rules (no force push to main, commit message format, access control).

Client-side hooks: pre-commit, prepare-commit-msg, commit-msg, post-commit, pre-push, post-merge, pre-rebase.

Server-side hooks: pre-receive, update, post-receive.

GitHub.com doesn't allow custom server hooks — use GitHub Actions instead. Self-hosted Git servers do.

The key insight: client hooks are GUIDELINES, server hooks are LAWS.

# Client-side hooks (run on your machine)
# .git/hooks/pre-commit    → runs before git commit
# .git/hooks/pre-push      → runs before git push
# .git/hooks/commit-msg    → runs after message is written

# Developer can bypass ALL client hooks:
git commit --no-verify   # skips pre-commit, commit-msg hooks
git push --no-verify     # skips pre-push hook

# Server-side hooks (run on GitHub/GitLab server)
# custom_hooks/pre-receive → runs when server receives push
# custom_hooks/update      → runs once per branch being updated
# custom_hooks/post-receive → runs after push is accepted

# Developer CANNOT bypass server hooks
# Even with --no-verify, server hooks still run
git push --no-verify origin main
# Server hook still checks and can REJECT the push

# That's why server hooks are for ENFORCEMENT
# Client hooks are for CONVENIENCE and QUALITY
03The Complete Hook Timeline

Git operations have a specific sequence, and hooks fire at exact points in that sequence.

Commit sequence: pre-commit → prepare-commit-msg → commit-msg → post-commit

Push sequence: pre-push → (server: pre-receive → update → post-receive)

Merge sequence: pre-merge-commit → post-merge

Rebase sequence: pre-rebase → post-rewrite

Checkout sequence: post-checkout

Each hook has a specific purpose and receives different arguments.

  • pre-commit: no arguments. Runs BEFORE the commit editor opens. Use for linting, validation.
  • prepare-commit-msg: receives message file path, message source, and commit SHA. Use for auto-populating messages.
  • commit-msg: receives message file path. Use for validating the message format.
  • pre-push: receives remote name and URL. Use for running tests before push.
💡 Pro Tip: Don't try to memorize all hooks. The 4 you'll use 95% of the time: pre-commit (validate code), commit-msg (validate message), pre-push (run tests), post-merge (auto-setup). Learn these four deeply, and look up the others when needed.
04The Sharing Problem: Why Hooks Don't Travel

.git/ directory is NOT tracked by Git. It's local to each clone.

This means hooks in .git/hooks/ are NOT shared with your team. Every developer must set them up manually.

This is a MAJOR problem: if you rely on pre-commit for code quality, but your teammate doesn't have it, bad code gets committed.

Solutions:

  • Husky: stores hooks in your project directory (tracked by Git), sets up .git/hooks/ automatically on npm install.
  • Put hook scripts in a scripts/ directory and tell developers to copy them manually (error-prone).
  • Use server-side hooks or CI for ENFORCEMENT — don't rely solely on client hooks.

Husky is the industry standard for JavaScript/TypeScript projects. We'll cover it in Chapter 8.5.

# The problem: .git/ is not tracked
git status .git/hooks/
# fatal: not a git repository: .git/

# You can't commit hooks to .git/hooks/
cd .git/hooks/
git add pre-commit
# fatal: not a git repository: .git/

# Your carefully crafted pre-commit hook is LOCAL ONLY
# When teammate clones the repo:
git clone https://github.com/team/project.git
ls project/.git/hooks/
# Only .sample files exist — NO custom hooks!

# Manual sharing (bad — nobody does this consistently):
# 1. Store hook in repo
mkdir -p scripts/git-hooks
cp .git/hooks/pre-commit scripts/git-hooks/pre-commit
git add scripts/git-hooks/
git commit -m "add pre-commit hook"

# 2. Teammate must manually copy:
cp scripts/git-hooks/pre-commit .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
# They WILL forget to do this. Every time.

# 3. Better: Husky (Chapter 8.5)
# Hooks stored in repo, installed automatically on npm install
# Everyone gets hooks, no manual steps
05When to Use Hooks vs CI vs GitHub Actions

Hooks: run LOCALLY, instant feedback, can block the operation. Best for: fast checks (lint, format, message format).

CI/CD (GitHub Actions): run on SERVER after push. Can't block the push, but can block merge. Best for: full test suite, build verification, security scans.

The strategy: hooks catch problems FAST before they're committed. CI catches problems that hooks missed.

Don't put slow operations in hooks. pre-commit that takes 30 seconds makes developers hate commits and use --no-verify.

Keep pre-commit under 5 seconds. Use pre-push for slower checks (30-60 seconds). Use CI for everything else.

Hook + CI layered defense: hook catches it instantly on your machine. If you bypass with --no-verify, CI catches it before merge.

The best teams use hooks AND CI together. Hooks provide instant feedback during development. CI provides the enforcement safety net. If a developer uses --no-verify to bypass hooks, CI still catches the problem before it reaches main. Never rely on client hooks alone for code quality enforcement — always have server-side verification too.

Lo kar liya — Key Points:

  • ✅ Git hooks are scripts that run automatically at specific Git events — commit, push, merge, etc.
  • ✅ Client-side hooks run locally and can be bypassed with --no-verify; server-side hooks cannot be bypassed
  • ✅ Hooks live in .git/hooks/ — activate samples by removing the .sample extension and making them executable
  • ✅ Exit code 0 allows the Git operation to proceed; non-zero exit code BLOCKS the operation
  • ✅ The 4 most important hooks: pre-commit (validate code), commit-msg (validate message), pre-push (run tests), post-merge (auto-setup)
  • ✅ .git/hooks/ is NOT tracked by Git — custom hooks do not travel with clones. Use Husky to share hooks with your team
  • ✅ Keep pre-commit hooks under 5 seconds — slow hooks make developers use --no-verify, defeating the purpose
Course Search
Search across all chapters & stages
📖

Search the course

Type any topic — branching, stash, rebase, hooks — and jump straight to that chapter.

merge branchesgit stashundo commitrebase