Git Hooks

Back

Loading concept...

Git Hooks: Your Code’s Security Guards 🛡️

Imagine your code repository is a fancy building. Every time someone tries to enter (commit code), exit (push code), or receive deliveries (receive code from others), there are security guards at the doors who can check, approve, or reject what’s happening.

These guards are Git Hooks!


What Are Git Hooks?

Git hooks are small programs that run automatically when certain events happen in your Git repository. They’re like automatic helpers who spring into action at just the right moment.

Think of it like this:

  • You have a robot at your front door
  • Every time someone rings the bell, the robot checks if they’re allowed in
  • If yes, the door opens. If no, the door stays locked!
graph TD A["You do something in Git"] --> B{Hook exists?} B -->|Yes| C["Hook runs automatically"] B -->|No| D["Git continues normally"] C --> E{Hook says OK?} E -->|Yes| D E -->|No| F["Action blocked!"]

Where Do Hooks Live?

All hooks live in a special folder:

your-project/
  └── .git/
      └── hooks/
          ├── pre-commit
          ├── pre-push
          └── ...more hooks

Fun fact: Git gives you sample hooks when you create a repository! They end with .sample so they don’t run. Remove .sample to activate them!


Client-Side Hooks

Client-side hooks run on YOUR computer. They’re like your personal helpers that check your work before you share it with others.

Pre-Commit Hook

The pre-commit hook runs right before you make a commit. It’s like a spell-checker that runs before you send an email!

What can it do?

  • Check for spelling mistakes
  • Run code linters
  • Look for debug statements you forgot to remove

Example: Block commits with “TODO” comments

#!/bin/bash
# .git/hooks/pre-commit

# Search for TODO in staged files
if git diff --cached | grep -i "TODO"; then
    echo "Oops! Remove TODOs first!"
    exit 1  # Block the commit
fi
exit 0  # Allow the commit

How it works:

  1. You type git commit
  2. Hook checks your changes
  3. Found “TODO”? Commit blocked!
  4. No “TODO”? Commit goes through!

Commit-Msg Hook

This hook checks your commit message. It’s like a teacher checking if your essay title makes sense!

Example: Require ticket number

#!/bin/bash
# .git/hooks/commit-msg

# $1 is the file with commit message
if ! grep -qE "^TICKET-[0-9]+" "$1"; then
    echo "Add ticket number!"
    echo "Example: TICKET-123 Fix bug"
    exit 1
fi
exit 0

Pre-Push Hook

Runs before your code goes to the shared repository. It’s the last checkpoint!

Example: Run tests before pushing

#!/bin/bash
# .git/hooks/pre-push

echo "Running tests..."
npm test

if [ $? -ne 0 ]; then
    echo "Tests failed! Fix first!"
    exit 1
fi
exit 0

Other Client-Side Hooks

Hook When It Runs
prepare-commit-msg Before commit editor opens
post-commit After commit completes
pre-rebase Before rebase starts
post-checkout After checkout completes
post-merge After merge completes

Server-Side Hooks

Server-side hooks run on the Git server (like GitHub or your company’s server). They protect the whole team’s code!

graph TD A["Developer pushes code"] --> B["Server receives code"] B --> C{pre-receive hook} C -->|Approved| D{update hook} D -->|Approved| E["Code accepted!"] C -->|Rejected| F["Push blocked!"] D -->|Rejected| F E --> G["post-receive hook"] G --> H["Notifications sent!"]

Pre-Receive Hook

This is the main gatekeeper. It can reject ALL changes in a push!

Example: Block force pushes to main

#!/bin/bash
# hooks/pre-receive (on server)

while read old new ref; do
    if [[ "$ref" == "refs/heads/main" ]]; then
        # Check if force push
        if [[ "$old" != "0000..." ]]; then
            echo "No force push to main!"
            exit 1
        fi
    fi
done
exit 0

Update Hook

Runs once for EACH branch being updated. More precise control!

Example: Only admins can push to release

#!/bin/bash
# hooks/update

ref=$1
ADMINS="alice bob charlie"

if [[ "$ref" == "refs/heads/release" ]]; then
    if [[ ! " $ADMINS " =~ " $USER " ]]; then
        echo "Only admins push to release!"
        exit 1
    fi
fi
exit 0

Post-Receive Hook

Runs AFTER changes are accepted. Perfect for:

  • Sending notifications
  • Triggering deployments
  • Updating dashboards

Example: Notify team on Slack

#!/bin/bash
# hooks/post-receive

while read old new ref; do
    branch=$(basename $ref)
    curl -X POST \
        -d "New push to $branch!" \
        https://slack-webhook-url
done

Bypassing Hooks

Sometimes you NEED to skip a hook. Maybe it’s an emergency fix, or the hook has a bug!

Skip Client-Side Hooks

Use the --no-verify flag:

# Skip pre-commit and commit-msg
git commit --no-verify -m "Emergency fix"

# Skip pre-push
git push --no-verify

Short version:

git commit -n -m "Quick fix"

When to Bypass?

graph TD A["Need to bypass?"] --> B{Emergency?} B -->|Yes| C["Document why!"] B -->|No| D{Hook broken?} D -->|Yes| E["Fix hook first!"] D -->|No| F[Don't bypass!] C --> G["Use --no-verify"]

Good reasons:

  • Emergency production fix
  • Hook script has a bug
  • One-time special commit

Bad reasons:

  • Too lazy to fix code
  • Want to skip tests
  • Commit message doesn’t match rules

Server Hooks Can’t Be Bypassed!

Important: The --no-verify flag only skips LOCAL hooks. Server-side hooks ALWAYS run!

This is a safety feature:

  • Developers can’t bypass team rules
  • Protected branches stay protected
  • Code quality is enforced

Server admin options:

  • Temporarily disable the hook
  • Add exceptions to hook logic
  • Grant special permissions

Summary: Your Hook Toolkit

Need Hook Type Location
Check my own code Client-side .git/hooks/
Protect team’s code Server-side Server’s hooks folder
Skip local checks Bypass --no-verify

Remember:

  • Client hooks = Personal helpers
  • Server hooks = Team guardians
  • Bypass with care!

Quick Setup Guide

  1. Find hooks folder:

    ls .git/hooks/
    
  2. Create a hook:

    touch .git/hooks/pre-commit
    chmod +x .git/hooks/pre-commit
    
  3. Edit with your rules:

    nano .git/hooks/pre-commit
    
  4. Test it:

    git commit -m "Test hook"
    

You’re now ready to be a Git Hooks master! 🎉

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.