
A Git hook is a program that Git runs automatically before or after an event such as a commit, push, or merge. Hooks let you enforce checks like linting, tests, and commit-message rules without anyone remembering to run them. This guide shows the most useful hooks with working examples.
This article is part of our complete Git and GitHub Actions workflow guide.
In this guide, we’ll explain:
- What Git Hooks are
- Why they’re important
- Common Git Hooks with examples
- How to set them up
- Best practices for teams
1. What Are Git Hooks?
Git Hooks are scripts that Git executes before or after specific events in your workflow.
They live inside the .git/hooks/ directory of your repository.
For example:
- Run linting before committing code
- Run tests before pushing changes
- Enforce commit message format
- Trigger CI/CD pipelines
By automating repetitive tasks, Git Hooks reduce human error and improve consistency.
2. Types of Git Hooks
Git Hooks are divided into client-side and server-side:
- Client-side hooks: Run on your machine during operations like committing, merging, or pushing.
- Server-side hooks: Run on a Git server (e.g., GitHub Enterprise, GitLab) during operations like receiving a push.
3. Common Git Hooks with Examples
🔹 Pre-commit Hook
Runs before a commit is created. Great for linting, formatting, or running quick tests.
Example: Run ESLint before commit
#!/bin/sh
# .git/hooks/pre-commit
npm run lint
if [ $? -ne 0 ]; then
echo "Linting failed! Fix errors before committing."
exit 1
fi
🔹 Commit-msg Hook
Validates the commit message format (helps enforce conventional commits).
Example: Enforce “feat/fix/docs” style messages
#!/bin/sh
commit_msg_file=$1
commit_msg=$(cat "$commit_msg_file")
if ! echo "$commit_msg" | grep -qE "^(feat|fix|docs|chore|test):"; then
echo "Commit message must start with feat|fix|docs|chore|test"
exit 1
fi
🔹 Pre-push Hook
Runs before pushing commits. Perfect for running tests.
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 Hook
Runs after a git merge. Useful for re-installing dependencies.
Example: Install dependencies after merge
#!/bin/sh
if [ -f package.json ]; then
echo "Installing dependencies..."
npm install
fi
4. Setting Up Git Hooks
- Navigate to
.git/hooks/in your repository. - Each hook has a sample file (e.g.,
pre-commit.sample). - Remove
.sampleand edit the script. - Make it executable:
chmod +x .git/hooks/pre-commit - Test by running a commit or push.
5. Sharing Git Hooks with Teams
By default, hooks inside .git/hooks/ aren’t versioned. To share them:
- Store hooks in a custom directory, e.g.,
.githooks/ - Configure Git:
git config core.hooksPath .githooks - Commit the hooks so all teammates use the same automation.
6. Best Practices for Git Hooks
✅ Keep hooks fast (avoid heavy scripts in pre-commit)
✅ Share hooks across teams with core.hooksPath
✅ Use hooks for validation, not deployment logic
✅ Combine with tools like Husky (for JavaScript) or pre-commit framework (for Python) to manage hooks easily
✅ Document hook usage in CONTRIBUTING.md
7. Conclusion
Git Hooks are a powerful way to automate workflows, enforce standards, and catch issues early. By setting up pre-commit checks, commit message validation, and pre-push tests, you can ensure higher-quality contributions with less manual effort.
Start small with a pre-commit hook for linting, then expand as your project grows.
Frequently Asked Questions
A Git hook is a program that Git runs automatically before or after an event such as a commit, push, or merge. Hooks live inside each repository and let you enforce checks without anyone remembering to run them.
In the .git/hooks directory of your repository. Git ships sample files there with a .sample extension; remove that extension to activate one.
No. The .git/hooks directory is not version-controlled. Teams share hooks by committing them to a tracked folder and pointing core.hooksPath at it, or by using a manager like pre-commit or Husky.
Yes. If a pre-commit, commit-msg, or pre-push hook exits with a non-zero status, Git aborts the operation.
You Might Also Like
- 👉 Day 1: Git Fundamentals
- 👉 Day 2: Basic Git Workflow
- 👉 Day 3: Branching and Merging
- 👉 Day 4: Remote Repositories
- 👉 Day 5: Advanced Git Operations
- 👉 Day 6: Git Workflows and Best Practices
- 👉 Day 7: Troubleshooting and Expert Techniques
- 👉 Advanced Git Commands You Need to Master (With Examples)
- 👉 Git Best Practices for Branching and Approvals
- 👉 GitHub CODEOWNERS & Permissions: Best Practices with Teams
- 👉 GitHub Templates: PR, Issue & Discussion Best Practices