logo
banner
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 NamePurpose & When It Runs
applypatch-msgBefore applying a patch with git am. Validate commit messages in patches.
pre-applypatchBefore a patch is applied. Often used for prep steps.
post-applypatchAfter a patch is applied. Good for notifications or rebuilds.
prepare-commit-msgModify auto-generated commit messages (e.g., squash, merge templates).
post-commitAfter a commit completes. Log events or trigger notifications.
pre-rebaseBefore a rebase starts. Block protected branches or warn users.
pre-merge-commitBefore a merge commit is created. Validate merge intentions.
pre-auto-gcBefore Git performs automatic garbage collection.
post-rewriteAfter 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

2. Lefthook


πŸ’‘ Final Thoughts

Git Hooks won't write better code for you β€” but they will:

Start simple:

And watch how your workflow instantly levels up.