Add hooks to version control
git add .githooks/ git commit -m "feat: add shared Git hooks for code quality"
### Hook Configuration
```bash
# Create hook configuration file
cat > .githooks/config.json << 'EOF'
{
"hooks": {
"pre-commit": {
"enabled": true,
"checks": {
"syntax": true,
"linting": true,
"formatting": true,
"tests": true,
"security": true
},
"maxFileSize": "1MB",
"allowedBranches": ["feature/*", "bugfix/*", "hotfix/*"]
},
"commit-msg": {
"enabled": true,
"format": "conventional",
"maxLength": 72,
"requireIssueReference": false
},
"pre-push": {
"enabled": true,
"protectedBranches": ["main", "master", "develop"],
"allowForceWithLease": true,
"runTests": true,
"runBuild": true
}
},
"notifications": {
"slack": {
"enabled": false,
"webhook": ""
},
"email": {
"enabled": false,
"recipients": []
}
}
}
EOF
Hook Best Practices
1. Keep Hooks Fast
bash
# Optimize hook performance
cat > .githooks/performance-tips.md << 'EOF'
# Hook Performance Tips
## Pre-commit Optimization
- Only check staged files, not entire repository
- Use parallel processing for multiple files
- Cache results when possible
- Skip checks for certain file types
## Example: Parallel linting
```bash
# Instead of:
for file in $js_files; do
eslint "$file"
done
# Use:
echo "$js_files" | xargs -P 4 eslint
Pre-push Optimization
- Only run full test suite, not individual tests
- Use test result caching
- Skip redundant checks if CI will run them EOF
### 2. Provide Clear Error Messages
```bash
# Example of good error messaging
cat > .githooks/error-example.sh << 'EOF'
#!/bin/bash
# BAD: Unclear error
if ! eslint .; then
echo "ESLint failed"
exit 1
fi
# GOOD: Clear, actionable error
if ! eslint .; then
echo "❌ ESLint found code quality issues"
echo ""
echo "To fix automatically:"
echo " npm run lint:fix"
echo ""
echo "To see detailed errors:"
echo " npm run lint"
echo ""
echo "To bypass this check (not recommended):"
echo " git commit --no-verify"
exit 1
fi
EOF
3. Make Hooks Configurable
bash
# Create configurable hook
cat > .githooks/configurable-pre-commit << 'EOF'
#!/bin/bash
# Load configuration
CONFIG_FILE=".githooks/config.json"
if [ -f "$CONFIG_FILE" ]; then
# Parse JSON config (requires jq)
LINT_ENABLED=$(jq -r '.hooks."pre-commit".checks.linting' "$CONFIG_FILE")
TEST_ENABLED=$(jq -r '.hooks."pre-commit".checks.tests' "$CONFIG_FILE")
else
# Default values
LINT_ENABLED="true"
TEST_ENABLED="true"
fi
# Conditional checks
if [ "$LINT_ENABLED" = "true" ]; then
echo "Running linter..."
npm run lint
fi
if [ "$TEST_ENABLED" = "true" ]; then
echo "Running tests..."
npm test
fi
EOF
4. Document Hook Behavior
bash
# Create comprehensive documentation
cat > .githooks/HOOKS_GUIDE.md << 'EOF'
# Git Hooks Guide
## Overview
This project uses Git hooks to maintain code quality and consistency.
## Hook Descriptions
### pre-commit
**When**: Before each commit is created
**Purpose**: Ensure code quality and prevent common issues
**Checks**:
- Syntax validation for JavaScript/TypeScript files
- ESLint code quality checks
- Prettier code formatting
- Unit tests execution
- File size limits (max 1MB)
- Sensitive information detection
- JSON syntax validation
**Bypass**: `git commit --no-verify`
### commit-msg
**When**: After commit message is entered
**Purpose**: Enforce consistent commit message format
**Format**: Conventional Commits (type(scope): description)
**Examples**:
- `feat(auth): add OAuth2 integration`
- `fix: resolve memory leak in calculator`
- `docs: update API documentation`
**Bypass**: `git commit --no-verify`
### pre-push
**When**: Before pushing to remote repository
**Purpose**: Final quality gate before sharing code
**Checks**:
- Prevent direct push to protected branches
- Validate all commit messages in push
- Run full test suite
- Build verification
- Security audit
- Large file detection
**Bypass**: `git push --no-verify`
## Troubleshooting
### Common Issues
1. **Hook not executing**
- Check if hook file is executable: `chmod +x .git/hooks/hook-name`
- Verify hook file exists in `.git/hooks/`
2. **Permission denied**
- Make hook executable: `chmod +x .git/hooks/hook-name`
3. **Hook fails unexpectedly**
- Check hook logs
- Run hook manually: `.git/hooks/hook-name`
- Verify dependencies are installed
### Getting Help
- Check hook output for specific error messages
- Review this documentation
- Ask team members for assistance
- Use `--no-verify` flag only in emergencies
EOF
Quick Reference
bash
# Hook locations
.git/hooks/ # Local hooks (not version controlled)
.githooks/ # Shared hooks (version controlled)
# Common hooks
pre-commit # Before commit creation
commit-msg # Validate commit message
pre-push # Before push to remote
post-commit # After commit creation
post-checkout # After checkout
post-merge # After merge
# Hook management
chmod +x .git/hooks/hook-name # Make hook executable
git config core.hooksPath .githooks # Use custom hooks directory
# Bypass hooks (use sparingly)
git commit --no-verify # Skip pre-commit and commit-msg
git push --no-verify # Skip pre-push
# Hook installation
./.githooks/install.sh # Install shared hooks
cp .githooks/* .git/hooks/ # Manual installation
# Testing hooks
.git/hooks/pre-commit # Run hook manually
echo "test" | .git/hooks/commit-msg /dev/stdin # Test commit-msg
Previous: Git Tags
Next: Conventional Commits