Bird
Raised Fist0
Gitdevops~10 mins

Client-side vs server-side hooks in Git - Visual Side-by-Side Comparison

Choose your learning style10 modes available
Process Flow - Client-side vs server-side hooks
Start: Git Action Triggered
↓
Run Client-side Hook Script
↓
Hook Passes?
↓
Run Server-side Hook Script
↓
Hook Passes?
↓
Action Proceeds
↓
Reject Action
When a Git action happens, client-side hooks run first on your computer. If they pass, server-side hooks run on the server. If all hooks pass, the action completes.
Execution Sample
Git
# Client-side pre-commit hook
#!/bin/sh
# Check for TODO comments
if git diff --cached | grep TODO; then
  echo "Remove TODOs before commit"
  exit 1
fi

# Server-side pre-receive hook
#!/bin/sh
while read oldrev newrev refname; do
  if [ "$refname" = "refs/heads/main" ]; then
    # Reject force pushes
    if [ "$oldrev" != "0000000000000000000000000000000000000000" ] && ! git merge-base --is-ancestor "$oldrev" "$newrev"; then
      echo "Force pushes to main are not allowed"
      exit 1
    fi
  fi
done
exit 0
This example shows a client-side pre-commit hook that blocks commits with TODO comments, and a server-side pre-receive hook that rejects force pushes to main branch.
Process Table
StepHook TypeAction TriggeredHook Script Runs?Hook ResultNext Step
1Client-sidegit commitYesNo TODO found, passRun server-side hooks
2Server-sideReceive pushYesNo force push detected, passAction proceeds
3Client-sidegit commitYesTODO found, failReject commit
4Client-sidegit commitYesNo TODO found, passRun server-side hooks
5Server-sideReceive pushYesForce push detected, failReject push
💡 Execution stops when a hook fails or all hooks pass allowing the action.
Status Tracker
VariableStartAfter Step 1After Step 2After Step 3After Step 4After Step 5
Commit ContentInitialNo TODONo TODOHas TODONo TODONo TODO
Push TypeInitialN/ANormal pushN/AN/AForce push
Hook Pass StatusN/APassPassFailPassFail
Key Moments - 3 Insights
Why does the commit get rejected even before reaching the server?
Because the client-side pre-commit hook found TODO comments and failed, as shown in execution_table row 3.
What happens if the client-side hook passes but the server-side hook fails?
The push is rejected by the server-side hook, as shown in execution_table row 5, stopping the action on the server.
Are server-side hooks run for local commits?
No, server-side hooks run only on the server during push or receive actions, not on local commits (see execution_table rows 1 and 3).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the hook result at step 3?
ANo TODO found, pass
BTODO found, fail
CForce push detected, fail
DNo force push detected, pass
💡 Hint
Check the 'Hook Result' column in execution_table row 3.
At which step does the server-side hook reject the action?
AStep 2
BStep 3
CStep 5
DStep 1
💡 Hint
Look for 'Force push detected, fail' in the 'Hook Result' column.
If the client-side hook finds no TODOs, what is the next step?
ARun server-side hooks
BReject commit immediately
CSkip server-side hooks
DAbort the git action
💡 Hint
See execution_table row 1 'Next Step' column.
Concept Snapshot
Client-side hooks run on your computer before actions like commit.
Server-side hooks run on the server during push or receive.
Client-side hooks can block bad commits early.
Server-side hooks enforce rules centrally.
If any hook fails, the action is stopped.
Hooks run in order: client-side first, then server-side.
Full Transcript
When you perform a Git action like commit or push, Git checks for hooks to run. First, client-side hooks run on your local machine. For example, a pre-commit hook can check your code for TODO comments and stop the commit if any are found. If the client-side hooks pass, and you push to a remote repository, server-side hooks run on the server. For example, a pre-receive hook can reject force pushes to the main branch. If any hook fails, Git stops the action and shows an error. This process helps catch problems early on your computer and enforce rules on the server. The execution table shows steps where hooks run and their results, helping you understand when and why actions proceed or stop.

Practice

(1/5)
1. Which of the following best describes a client-side Git hook?
easy
A. A Git command to clone repositories.
B. A script that runs on the Git server to control repository access.
C. A tool to merge branches automatically on the server.
D. A script that runs on your local machine before or after Git actions like commit or push.

Solution

  1. Step 1: Understand client-side hooks context

    Client-side hooks run on your local computer and trigger before or after Git commands like commit or push.
  2. Step 2: Differentiate from server-side hooks

    Server-side hooks run on the Git server to enforce rules for all users, unlike client-side hooks which are local.
  3. Final Answer:

    A script that runs on your local machine before or after Git actions like commit or push. -> Option D
  4. Quick Check:

    Client-side hook = local script [OK]
Hint: Client-side hooks run locally before/after Git commands [OK]
Common Mistakes:
  • Confusing client-side hooks with server-side hooks
  • Thinking hooks run only on the server
  • Assuming hooks are Git commands
2. Which of the following is the correct location to place a client-side pre-commit hook script in a Git repository?
easy
A. /usr/local/git/hooks/pre-commit
B. .git/hooks/server-pre-commit
C. .git/hooks/pre-commit
D. .git/pre-commit

Solution

  1. Step 1: Identify the standard hooks directory

    Git client-side hooks are stored inside the .git/hooks directory of the local repository.
  2. Step 2: Confirm the correct hook filename

    The pre-commit hook script must be named exactly 'pre-commit' inside .git/hooks.
  3. Final Answer:

    .git/hooks/pre-commit -> Option C
  4. Quick Check:

    Client-side hooks live in .git/hooks [OK]
Hint: Client-side hooks go in .git/hooks folder [OK]
Common Mistakes:
  • Placing hooks outside the .git directory
  • Using wrong filenames for hooks
  • Confusing server-side hook locations
3. Given this server-side hook script named pre-receive on the Git server:
#!/bin/sh
while read oldrev newrev refname
 do
   if [ "$refname" = "refs/heads/main" ]; then
     echo "Pushes to main branch are not allowed."
     exit 1
   fi
 done
exit 0
What will happen if a user tries to push commits to the main branch?
medium
A. The push will be rejected with the message 'Pushes to main branch are not allowed.'
B. The push will succeed without any message.
C. The push will be accepted but with a warning.
D. The server will crash due to a syntax error.

Solution

  1. Step 1: Analyze the pre-receive hook logic

    The script reads each ref being pushed. If the ref is 'refs/heads/main', it prints a message and exits with status 1, which rejects the push.
  2. Step 2: Understand Git hook exit codes

    Exiting with 1 means failure, so Git rejects the push and shows the message to the user.
  3. Final Answer:

    The push will be rejected with the message 'Pushes to main branch are not allowed.' -> Option A
  4. Quick Check:

    Exit 1 in server hook rejects push [OK]
Hint: Exit code 1 in server hook blocks push [OK]
Common Mistakes:
  • Assuming push succeeds despite exit 1
  • Confusing client-side and server-side hook effects
  • Ignoring the printed message
4. You wrote a client-side pre-commit hook script but it does not run when you commit. What is the most likely reason?
medium
A. The script is placed in the wrong directory on the server.
B. The script file is not executable.
C. Git does not support pre-commit hooks.
D. You forgot to push the hook to the remote repository.

Solution

  1. Step 1: Check script permissions

    Client-side hooks must be executable files. If not, Git will ignore them silently.
  2. Step 2: Verify hook location and Git support

    The hook must be in .git/hooks locally. Git supports pre-commit hooks, and pushing hooks to remote does not affect local hooks.
  3. Final Answer:

    The script file is not executable. -> Option B
  4. Quick Check:

    Hooks must be executable to run [OK]
Hint: Make hook scripts executable with chmod +x [OK]
Common Mistakes:
  • Placing hooks on the server for client-side use
  • Thinking Git lacks pre-commit hooks
  • Expecting hooks to transfer via git push
5. You want to enforce that all commits pushed to the shared repository have a signed commit message. Which hook setup is best to ensure this rule is always checked regardless of the user's local setup?
hard
A. Implement a server-side pre-receive hook that rejects unsigned commits.
B. Ask each developer to add a client-side commit-msg hook to check signatures.
C. Use a client-side pre-push hook to warn about unsigned commits.
D. Rely on GitHub or GitLab UI to manually check commit signatures.

Solution

  1. Step 1: Understand enforcement scope

    Client-side hooks depend on each user's setup and can be bypassed or missing.
  2. Step 2: Use server-side hooks for mandatory checks

    Server-side hooks run on the shared repository and can reject pushes that don't meet rules, ensuring enforcement for all users.
  3. Final Answer:

    Implement a server-side pre-receive hook that rejects unsigned commits. -> Option A
  4. Quick Check:

    Server hooks enforce rules for all pushes [OK]
Hint: Use server-side hooks to enforce rules for all users [OK]
Common Mistakes:
  • Relying only on client-side hooks for enforcement
  • Assuming UI checks block pushes automatically
  • Ignoring that client hooks can be disabled
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard