
Photo by Kasia Derenda on Unsplash
Git Hooks β The Developer's Silent Sidekick
You know that gut-punch feeling when you push broken code, forget to run tests, or write a commit message so vague it could be the title of a Christopher Nolan film?
Yep. Been there, done that.
But what if I told you Git can automate that slap-on-the-wrist your tech lead usually gives you during code review?
Meet Git Hooks β your silent sidekick for clean commits, consistent messages, and fewer "oops" moments.
π‘ What Are Git Hooks?
Git hooks are executable scripts that Git runs before or after certain events like commits, pushes, merges, rebases, and more. Think of them as little robot assistants standing guard over your version control flow.
They live in this path (by default):
.git/hooks/
...and are disabled until you make them executable and give them real jobs.
π¦ΈββοΈ Why Should You Care?
Letβs be honest: we're all human.
We forget to run tests.
We commit debug.log
.
We write commit messages like fix stuff
.
Git hooks automate the "are-you-sure" part of development β catching mistakes before they hit the repo.
Now, let me show you the ones you're actually likely to use in real life β the ones that save developers from daily embarrassment.
π‘ pre-commit
β Stop Bad Code Before It Happens
When it runs: Before a commit is finalized.
Why it's useful: Block broken, unformatted, or careless code from entering your repo. Consider this your first line of defense.
Example: Lint your code before committing
#!/bin/sh echo "Linting your code..." npm run lint if [ $? -ne 0 ]; then echo "β Linting failed! Fix errors before committing." exit 1 fi
π Save this in .git/hooks/pre-commit
and make it executable:
chmod +x .git/hooks/pre-commit
π‘ commit-msg
β Enforce Commit Message Discipline
When it runs: After you write your commit message, before the commit is saved.
Why it's useful: Protects your repo from cryptic, non-informative commit messages like:
misc changes
Example: Enforce Conventional Commits
#!/bin/sh message=$(cat "$1") pattern="^(feat|fix|chore|docs|style|refactor|test|perf|ci|build|revert)(\(.+\))?: .{1,50}" if ! echo "$message" | grep -qE "$pattern"; then echo "β Invalid commit message!" echo "β Format should be: feat(scope): description" exit 1 fi
π‘ pre-push
β The Final Defense Line
When it runs: Before your code is pushed to the remote.
Why it's useful: Ensure tests pass or builds are successful before anyone else gets your code.
Example: Run tests before push
#!/bin/sh echo "Running tests before push..." npm test if [ $? -ne 0 ]; then echo "β Tests failed! Push aborted." exit 1 fi
π‘ post-merge
β Sync After Merging
When it runs: After a git merge
completes.
Why it's useful: Prevent those "works on my machine" moments after pulling changes that added new dependencies.
Example: Auto-install dependencies if package.json
changed
#!/bin/sh if git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD | grep -q "package.json"; then echo "package.json changed β running npm install..." npm install fi
π‘ post-checkout
β Welcome to Your New Branch
When it runs: Every time you checkout a branch or commit.
Why it's useful: Automatically reset environment configs or remind yourself which branch you're on.
Example: Notify current branch
#!/bin/sh branch=$(git rev-parse --abbrev-ref HEAD) echo "β You're now on branch: $branch"
π Other Git Hooks You Should Know (But Use When Needed)
Hook Name | Purpose & When It Runs |
---|---|
applypatch-msg | Before applying a patch with git am . Validate commit messages in patches. |
pre-applypatch | Before a patch is applied. Often used for prep steps. |
post-applypatch | After a patch is applied. Good for notifications or rebuilds. |
prepare-commit-msg | Modify auto-generated commit messages (e.g., squash, merge templates). |
post-commit | After a commit completes. Log events or trigger notifications. |
pre-rebase | Before a rebase starts. Block protected branches or warn users. |
pre-merge-commit | Before a merge commit is created. Validate merge intentions. |
pre-auto-gc | Before Git performs automatic garbage collection. |
post-rewrite | After rewriting commits via rebase or amend. Useful for cleanup. |
π How to Share Hooks Across Teams?
Git doesnβt track .git/hooks
(by design) β so if you want team-wide consistency, you have two main solutions:
1. Husky
-
Perfect for JavaScript/TypeScript projects.
-
Hooks are stored inside your version-controlled codebase.
-
Easy to set up with npx husky install.
2. Lefthook
-
Language-agnostic.
-
Great for teams working across different stacks.
-
Centralizes hooks under version control.
π‘ Final Thoughts
Git Hooks won't write better code for you β but they will:
-
Save you from human error.
-
Make you look like the professional you pretend to be on LinkedIn.
-
Keep your team's history clean and consistent.
Start simple:
pre-commit
for code quality.commit-msg
for consistent commit messages.pre-push
for last-minute sanity checks.
And watch how your workflow instantly levels up.