The Honor System vs. The Law
Think of a nightclub with a dress code. You could put a sign at the entrance of the parking lot saying "No sneakers allowed" — but anyone can ignore it and walk right past. That's a client-side hook. The actual bouncer at the door who physically checks and turns people away? That's a server-side hook.
Client-Side Hooks (pre-commit, pre-push) live on a developer's local machine. They are excellent for fast feedback — running linters, formatting checks, or unit tests before a commit is created. But they have a fundamental flaw: they are entirely voluntary.
- A developer can bypass them with
git commit --no-verify. - A new team member who clones the repo gets no hooks at all — they live in
.git/hooks/, which is not tracked by version control. - A developer on a different OS or shell environment may have hooks that silently fail.
Server-Side Hooks live on the remote repository — the machine that receives pushes. They are not optional, not bypassable by the client, and not dependent on any local setup. When a server-side hook says "No," the push is rejected unconditionally. The commits never land. The branch never updates.
This makes server-side hooks the correct enforcement point for policies that must be universally applied:
- "Every commit message must reference a Jira ticket."
- "No one may force-push to
mainor rewrite its history." - "No binary files larger than 50MB may be committed."
- "All commits must be GPG-signed."
The key architectural insight: client-side hooks are developer experience tools; server-side hooks are compliance and security controls. They serve different purposes and should both exist in a mature engineering organization.
Interviewers frequently ask: "How do you enforce commit message standards across a team?" A weak answer is "we use a pre-commit hook." The correct answer distinguishes between client-side hooks (voluntary, good for developer feedback) and server-side hooks (mandatory, the actual enforcement layer). Mention that client-side hooks can be skipped with --no-verify and that they aren't version-controlled by default — this immediately signals senior-level awareness.