Git Hooks: Automate Code Quality with Pre-commit and Pre-push
Git hooks run scripts automatically at key points in your Git workflow.
Hook Types
pre-commit Before each commit (run lint/tests)
prepare-commit-msg Modify commit message template
commit-msg Validate commit message format
pre-push Before pushing (run integration tests)
post-merge After merge (install dependencies)
pre-rebase Before rebasing
Manual Hook Setup
# Create pre-commit hook
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
npm run lint
if [ $? -ne 0 ]; then
echo "Lint failed. Commit aborted."
exit 1
fi
EOF
chmod +x .git/hooks/pre-commit
Husky - Modern Hook Management
# Install Husky
npm install -D husky
npx husky init
# The init command creates .husky/ directory
# .husky/pre-commit
#!/bin/sh
npx lint-staged
# .husky/commit-msg
#!/bin/sh
npx --no -- commitlint --edit $1
# .husky/pre-push
#!/bin/sh
npm test
lint-staged - Run Linters on Staged Files
// package.json
{
"lint-staged": {
"*.{ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{js,jsx}": "eslint --fix",
"*.{css,scss}": "prettier --write",
"*.{md,json}": "prettier --write"
}
}
commitlint - Conventional Commits
npm install -D @commitlint/cli @commitlint/config-conventional
// commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [2, 'always', [
'feat', 'fix', 'docs', 'style',
'refactor', 'test', 'chore', 'revert'
]],
'subject-max-length': [2, 'always', 72],
}
};
Post-merge Hook
# .husky/post-merge
#!/bin/sh
# Reinstall if package.json changed
changed_files="$(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD)"
if echo "$changed_files" | grep -q "package.json"; then
echo "package.json changed, reinstalling dependencies..."
npm install
fi
Bypassing Hooks
# Skip hooks when needed (use sparingly)
git commit --no-verify -m "WIP: skip hooks"
git push --no-verify
Team-wide Configuration
// package.json
{
"scripts": {
"prepare": "husky"
}
}
The prepare script runs automatically after npm install, ensuring hooks are set up for all team members.
Git hooks enforce code quality before code ever reaches the repository.