Git Hooks Manager
Setup automated git hooks for pre-commit and pre-push workflows. Enforce code quality, run tests, format code, and prevent bad commits from reaching your repository.
What This Skill Does
- •Creates pre-commit hooks (lint, format, test)
- •Sets up pre-push hooks (full test suite)
- •Installs commit-msg hooks (enforce conventions)
- •Configures husky or manual hooks
- •Prevents commits with failing checks
- •Auto-formats code before commit
Instructions
Phase 1: Detect Project Type
bash
Use Read to check: - package.json → Node.js (use husky) - pyproject.toml → Python (use pre-commit) - .git/hooks → Manual hooks
Phase 2: Node.js Setup (Husky)
Install husky:
bash
npm install --save-dev husky lint-staged npx husky init
Configure package.json:
json
{
"scripts": {
"prepare": "husky"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{json,md,yml}": [
"prettier --write"
]
}
}
Pre-commit hook (.husky/pre-commit):
bash
#!/bin/sh . "$(dirname "$0")/_/husky.sh" echo "🔍 Running pre-commit checks..." # Run linter npm run lint || exit 1 # Format code npx lint-staged || exit 1 # Run tests on staged files npm test -- --findRelatedTests $(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(js|jsx|ts|tsx)$' | tr '\n' ' ') || exit 1 echo "✅ Pre-commit checks passed!"
Pre-push hook (.husky/pre-push):
bash
#!/bin/sh . "$(dirname "$0")/_/husky.sh" echo "🔍 Running pre-push checks..." # Run full test suite npm test || exit 1 # Check types (if TypeScript) npm run type-check || exit 1 # Build check npm run build || exit 1 echo "✅ Pre-push checks passed!"
Commit-msg hook (.husky/commit-msg):
bash
#!/bin/sh . "$(dirname "$0")/_/husky.sh" # Enforce conventional commits npx --no -- commitlint --edit $1 || exit 1
Phase 3: Python Setup (pre-commit)
.pre-commit-config.yaml:
yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- id: check-json
- id: check-merge-conflict
- id: detect-private-key
- repo: https://github.com/psf/black
rev: 23.12.1
hooks:
- id: black
language_version: python3.11
- repo: https://github.com/pycqa/flake8
rev: 7.0.0
hooks:
- id: flake8
args: ['--max-line-length=88', '--extend-ignore=E203']
- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
- id: isort
args: ['--profile', 'black']
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.8.0
hooks:
- id: mypy
additional_dependencies: [types-all]
- repo: local
hooks:
- id: pytest
name: pytest
entry: pytest
language: system
pass_filenames: false
always_run: true
Install:
bash
pip install pre-commit pre-commit install pre-commit install --hook-type commit-msg
Phase 4: Manual Hooks
For projects without package managers:
.git/hooks/pre-commit:
bash
#!/bin/sh
echo "🔍 Running pre-commit checks..."
# Check for TODOs
if git diff --cached | grep -i "TODO"; then
echo "❌ Found TODO comments. Please remove or track them properly."
exit 1
fi
# Check for console.log
if git diff --cached --name-only | grep -E '\.(js|jsx|ts|tsx)$' | xargs grep -n "console\.log"; then
echo "❌ Found console.log statements. Please remove them."
exit 1
fi
# Check for hardcoded secrets
if git diff --cached | grep -E '(password|secret|api_key|apikey)\s*=\s*["\'][^"\']+["\']'; then
echo "❌ Possible hardcoded secret detected!"
exit 1
fi
# Check file size
for file in $(git diff --cached --name-only); do
if [ -f "$file" ]; then
size=$(wc -c < "$file")
if [ $size -gt 1048576 ]; then # 1MB
echo "❌ File $file is too large (>1MB)"
exit 1
fi
fi
done
echo "✅ Pre-commit checks passed!"
Hook Types
pre-commit
- •Linting (ESLint, Flake8, Pylint)
- •Formatting (Prettier, Black, rustfmt)
- •Type checking (TypeScript, mypy)
- •Unit tests on changed files
- •Secret detection
pre-push
- •Full test suite
- •Build verification
- •Coverage check
- •Integration tests
commit-msg
- •Conventional Commits enforcement
- •Ticket number requirement
- •Message length validation
post-commit
- •Notifications
- •Log generation
- •Cleanup tasks
Advanced Features
Skip Hooks (When Needed)
bash
# Skip pre-commit git commit -n -m "Emergency fix" # Skip pre-push git push --no-verify
Selective Hooks
yaml
# Only run on specific branches
if [ "$(git branch --show-current)" = "main" ]; then
echo "Running extra checks on main branch..."
fi
Performance Optimization
bash
# Cache linter results
if [ ! -f .lint-cache ] || [ "$(git diff --cached | md5sum)" != "$(cat .lint-cache)" ]; then
npm run lint
git diff --cached | md5sum > .lint-cache
fi
Tool Requirements
- •Write: Create hook files
- •Read: Detect project configuration
- •Bash: Make hooks executable
Examples
Example 1: Full Setup
User: "Setup git hooks for my Node.js project"
Output:
- •Installs husky + lint-staged
- •Creates pre-commit hook (lint, format, test)
- •Creates pre-push hook (full tests)
- •Creates commit-msg hook (conventional commits)
Example 2: Python Project
User: "Setup pre-commit hooks for Python"
Output:
- •Installs pre-commit framework
- •Configures black, flake8, isort, mypy
- •Adds pytest hook
- •Installs hooks to .git/hooks/
Best Practices
- •Fast pre-commit: Only run on changed files
- •Comprehensive pre-push: Full test suite before push
- •Allow skip: Provide --no-verify escape hatch
- •Team consistency: Commit hooks config to repo
- •Clear feedback: Show what's running and why it failed
Changelog
Version 1.0.0
- •Husky setup for Node.js
- •pre-commit framework for Python
- •Manual hooks for any project
- •Conventional Commits enforcement
- •Secret detection
Author
GLINCKER Team
- •Repository: claude-code-marketplace