Mastering Git – Part 7: Git Hooks and Automation¶
Git isn’t just about tracking code—it can also automate tasks, enforce best practices, and prevent mistakes using Git Hooks.
Imagine automatically:
- ✅ Running tests before committing 🚀
- ✅ Preventing bad commit messages ❌
- ✅ Formatting code before pushing 🎨
- ✅ Blocking commits with secrets 🔒
Git hooks let you do all this and more!
In this post, we’ll cover:
- ✅ What Git hooks are and how they work
- ✅ Setting up pre-commit and pre-push hooks
- ✅ Automating Git with Husky
- ✅ Best practices for Git hook usage
By the end, you'll know how to use Git hooks to improve code quality, automate workflows, and prevent common mistakes.
1. What Are Git Hooks?¶
Git hooks are scripts that run automatically at different points in the Git workflow.
There are two types of hooks:
- 🔹 Client-side hooks – Run on your local machine (before committing, pushing, or merging).
- 🔹 Server-side hooks – Run on the remote repository (before accepting pushes).
2. Commonly Used Git Hooks¶
| Hook | When it Runs | Common Use Cases |
|---|---|---|
pre-commit |
Before committing | Run linters, formatters, security checks |
commit-msg |
Before commit is saved | Enforce commit message rules |
pre-push |
Before pushing | Run tests, prevent bad code from being pushed |
pre-receive |
Before remote repo accepts push | Reject bad commits on server |
post-merge |
After merging a branch | Auto-install dependencies |
3. Setting Up Git Hooks Manually¶
A. Creating a Pre-Commit Hook¶
1️⃣ Navigate to the Git hooks directory in your repo:
cd .git/hooks
2️⃣ Create a new pre-commit file:
touch pre-commit
chmod +x pre-commit # Make it executable
3️⃣ Open it in an editor and add a simple script (e.g., prevent commits with TODOs):
#!/bin/bash
if grep -r 'TODO' *; then
echo "🚨 Commit blocked: Remove TODOs before committing!"
exit 1
fi
4️⃣ Save and try committing a file with TODO—it will block the commit.
✅ Use Case: Prevent committing unfinished work.
B. Creating a Pre-Push Hook¶
1️⃣ Create the hook:
touch .git/hooks/pre-push
chmod +x .git/hooks/pre-push
2️⃣ Add a script to run tests before pushing:
#!/bin/bash
echo "🔍 Running tests before push..."
if ! ./run-tests.sh; then
echo "🚨 Tests failed! Push aborted."
exit 1
fi
✅ Use Case: Ensure broken code isn’t pushed.
C. Enforcing Commit Message Format (commit-msg Hook)¶
1️⃣ Create the hook:
touch .git/hooks/commit-msg
chmod +x .git/hooks/commit-msg
2️⃣ Add a script to enforce a conventional commit format:
#!/bin/bash
COMMIT_MSG=$(cat "$1")
if ! [[ "$COMMIT_MSG" =~ ^(feat|fix|docs|refactor|test|chore)\(.*\): ]]; then
echo "🚨 Commit message must follow format: type(scope): description"
echo "Example: feat(auth): add login support"
exit 1
fi
✅ Use Case: Ensure clean and structured commit messages.
4. Automating Git Hooks with Husky (Recommended)¶
Manually setting up hooks per user is painful. Husky solves this by managing hooks as part of the repository.
A. Installing Husky¶
npm install husky --save-dev
B. Setting Up Husky in Your Repo¶
npx husky install
Then enable it in package.json:
"scripts": {
"prepare": "husky install"
}
C. Adding a Pre-Commit Hook with Husky¶
npx husky add .husky/pre-commit "npm run lint"
git add .husky/pre-commit
✅ Now, every commit will run npm run lint automatically!
5. Best Practices for Git Hooks¶
- ✅ Keep hooks fast – Hooks should not slow down development.
- ✅ Use Husky for easier management – Avoid manually setting up hooks per user.
- ✅ Version control your hooks – Keep them in the repo (
.husky/for Husky or share.githooks/). - ✅ Allow skipping hooks when necessary – Use
git commit --no-verifyto bypass if needed. - ✅ Use server-side hooks for critical checks – Prevent bad commits from reaching production.
6. Summary of Key Commands¶
| Action | Command |
|---|---|
| List available Git hooks | ls .git/hooks/ |
| Create a pre-commit hook | touch .git/hooks/pre-commit |
| Make a hook executable | chmod +x .git/hooks/pre-commit |
| Install Husky | npm install husky --save-dev |
| Add a Husky pre-commit hook | npx husky add .husky/pre-commit "npm run lint" |
| Skip hooks when committing | git commit --no-verify |
What’s Next?¶
Now you know how to automate Git workflows and enforce best practices using hooks. But what about handling advanced Git scenarios like stashing, cherry-picking, and submodules?
In Part 8: Advanced Git – Stashing, Cherry-Picking, and Submodules, we’ll cover:
- ✅ Stashing changes for later
- ✅ Applying specific commits with cherry-picking
- ✅ Managing submodules for large projects