git-hooks
npx skills add https://github.com/bitsoex/bitso-java --skill git-hooks
Agent 安装分布
Skill 文档
Git Hooks
This skill provides guidance for implementing and maintaining Git hooks that enforce code quality standards before commits and pushes reach the repository.
When to use this skill
- Setting up Git hooks in a new repository
- Creating new pre-commit or pre-push hooks
- Debugging hook installation or execution issues
- Ensuring hooks follow team standards
- Migrating from manual hooks to version-controlled hooks
- Integrating with existing hook systems (Husky, pre-commit, lefthook)
Skill Contents
Sections
- When to use this skill (L20-L28)
- Distributed Hooks (Informative Mode) (L64-L125)
- Assets (L126-L136)
- Architecture (L137-L161)
- Instructions (L162-L256)
- Hook Types (L257-L267)
- Best Practices (L268-L396)
- Informative vs Enforcing Mode (L397-L405)
- References (L406-L416)
- Documentation (L417-L424)
- Related Skills (L425-L432)
- Troubleshooting (L433-L495)
Available Resources
ð references/ – Detailed documentation
ð¦ assets/ – Templates and resources
Distributed Hooks (Informative Mode)
For repositories receiving distributed AI rules, we provide informative hooks that:
- Never block commits or pushes (always exit 0)
- Warn about issues with clear fix commands
- Auto-detect Node.js via nvm, fnm, or system PATH (shows setup instructions if not found)
- Coexist with existing hook setups (Husky, pre-commit, lefthook)
How It Works
# Source location: global/skills/git-hooks/assets/
# Deployed to target repo as:
.git-hooks/
âââ pre-commit â Delegates to hooks-bootstrap.sh (same directory)
âââ pre-push â Delegates to hooks-bootstrap.sh (same directory)
âââ ensure-node.sh â Ensures Node.js 20+ is available
âââ hooks-bootstrap.sh â Entry point, loads Node, runs checks
âââ hooks-checks.js â Multi-language quality checks
Enabling Distributed Hooks
# Set Git to use our hooks directory
git config core.hooksPath .git-hooks
# Verify
git config --get core.hooksPath
# Should output: .git-hooks
Output Example
============================================================
Bitso Quality Checks (Informative)
============================================================
Pre-commit checks found some issues:
[!] Linting: ESLint errors detected
Run: mise run lint:fix
[!] TypeScript: Type errors detected
Run: npx tsc --noEmit
These are recommendations. Your commit will proceed.
For AI agents: Please address these issues before completing.
============================================================
Coexistence with Existing Hooks
See assets/hooks-bridge-strategy.md for detailed integration patterns with:
- Husky: Add our checks to
.husky/pre-commit - pre-commit (Python): Add as a
localhook in.pre-commit-config.yaml - lefthook: Add to
lefthook.ymlcommands
Assets
| Asset | Purpose |
|---|---|
assets/ensure-node.sh |
Node.js detection and auto-installation |
assets/hooks-bootstrap.sh |
Hook entry point (ensures Node, runs checks) |
assets/hooks-checks.js |
Multi-language quality checks |
assets/pre-commit |
Pre-commit hook entry point |
assets/pre-push |
Pre-push hook entry point |
assets/hooks-bridge-strategy.md |
Integration patterns for existing setups |
Architecture
Recommended Directory Structure
project/
âââ .git-hooks/ # Version-controlled hooks directory
â âââ pre-commit # Symlink â ../.scripts/pre-commit-hook.sh
â âââ pre-push # Symlink â ../.scripts/pre-push-hook.sh
âââ .scripts/
â âââ setup-hooks.js # Hook installation script (runs on npm install)
â âââ pre-commit-hook.sh # Pre-commit hook implementation
â âââ pre-push-hook.sh # Pre-push hook implementation
â âââ lib/skills/ # Skill modules for hook operations
âââ package.json # Contains "prepare": "node .scripts/setup-hooks.ts"
Why This Architecture?
- Version-controlled: Hooks live in
.git-hooks/, tracked by Git - Automatic installation:
npm installconfigures hooks viapreparescript - Team consistency: Everyone gets the same hooks automatically
- Implementation separation: Actual logic in
.scripts/, symlinks in.git-hooks/ - Skippable in CI: Setup script detects CI environment and skips
Instructions
Step 1: Create the Hooks Directory
mkdir -p .git-hooks
Step 2: Create the Setup Script
Create .scripts/setup-hooks.ts:
#!/usr/bin/env node
/**
* Setup Git Hooks
*
* Runs on `npm install` via the "prepare" script.
* Configures git to use .git-hooks/ for hooks.
*/
if (process.env.CI || process.env.SKIP_HOOKS) {
console.log('âï¸ Skipping hook setup (CI or SKIP_HOOKS=true)');
process.exit(0);
}
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const ROOT_DIR = path.join(__dirname, '..');
const HOOKS_DIR = '.git-hooks';
function setupHooks() {
if (!fs.existsSync(path.join(ROOT_DIR, '.git'))) {
console.log('â ï¸ Not a git repository, skipping hook setup');
return;
}
const githooksPath = path.join(ROOT_DIR, HOOKS_DIR);
if (!fs.existsSync(githooksPath)) {
console.error(`â Hooks directory not found: ${HOOKS_DIR}`);
process.exit(1);
}
// Set core.hooksPath
try {
execSync(`git config core.hooksPath ${HOOKS_DIR}`, { cwd: ROOT_DIR });
console.log(`â
Git hooks configured: core.hooksPath â ${HOOKS_DIR}`);
} catch (error) {
console.error('â Failed to set core.hooksPath:', error.message);
process.exit(1);
}
}
setupHooks();
Step 3: Configure package.json
Add the prepare script to automatically set up hooks on install:
{
"scripts": {
"prepare": "node .scripts/setup-hooks.ts"
}
}
Step 4: Create Hook Implementation
Create hook scripts in .scripts/ following the template in the References section.
Step 5: Create Symlinks
Create symlinks in .git-hooks/ pointing to the implementation:
cd .git-hooks
ln -sf ../.scripts/pre-commit-hook.sh pre-commit
ln -sf ../.scripts/pre-push-hook.sh pre-push
chmod +x pre-commit pre-push
Step 6: Validate Hook Setup
# Run validation
npm run skills:hooks
# Or use CLI directly
node .scripts/skills-cli.ts git-hooks validate
Hook Types
| Hook | When It Runs | Typical Checks |
|---|---|---|
pre-commit |
Before commit is created | Linting, formatting, tests, validation |
pre-push |
Before push to remote | Full test suite, coverage, build verification |
commit-msg |
After commit message written | Message format validation |
prepare-commit-msg |
Before editor opens | Template insertion |
post-checkout |
After checkout completes | Dependency updates, cache clearing |
post-merge |
After merge completes | Dependency updates |
Best Practices
1. Exit Codes Matter
# Exit 0 = success, commit/push proceeds
# Exit non-zero = failure, operation aborted
if ! npm test; then
echo "Tests failed"
exit 1
fi
2. Provide Clear Feedback
# Use colors and emojis for visibility
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
echo -e "${YELLOW}ð Running tests...${NC}"
if npm test --silent; then
echo -e "${GREEN} â Tests passed${NC}"
else
echo -e "${RED} â Tests failed${NC}"
exit 1
fi
3. Keep Hooks Fast
Pre-commit hooks should complete in seconds, not minutes:
- Run only essential checks
- Use incremental/cached operations where possible
- Move heavy checks to pre-push
4. Allow Emergency Bypass
# Document how to skip in emergencies
git commit --no-verify # Skip pre-commit
git push --no-verify # Skip pre-push
5. Fail Early, Fail Fast
Order checks from fastest to slowest:
# 1. Fast checks first
echo "Checking for debug statements..."
if grep -r "console.log" src/; then
echo "Remove debug statements before committing"
exit 1
fi
# 2. Medium checks
echo "Running linter..."
npm run lint
# 3. Slow checks last
echo "Running tests..."
npm test
6. Handle Auto-Fixes
If a hook auto-fixes files, stage them:
if git diff --name-only | grep -q "formatted-file.js"; then
git add formatted-file.js
echo "Auto-formatted file added to commit"
fi
7. Never Add Coverage Exclusions as First Approach
IMPORTANT: When pre-push hooks fail due to coverage thresholds, the correct approach is:
- Add tests to increase coverage (preferred)
- Use
--no-verifyas a temporary emergency bypass if absolutely necessary - Never add exclusions to
.c8rc.json,.nycrc, or coverage config
Why?
- Exclusions hide untested code and accumulate over time
- They defeat the purpose of coverage thresholds
- They make it harder to identify actual coverage gaps
Correct approach when coverage fails:
# 1. Run coverage report to identify gaps
npm run test:coverage:report
# 2. Add tests for uncovered lines
# ... write tests ...
# 3. Verify coverage now passes
npm run test:coverage
# 4. Commit and push normally
git push
Emergency bypass (use sparingly):
# Only when you MUST push immediately and will add tests in follow-up
git push --no-verify
# Document why in commit message or PR
# Create a ticket to add missing tests
Never do this:
// â DON'T add exclusions to avoid writing tests
{
"exclude": [
".scripts/new-module.ts" // â WRONG - write tests instead
]
}
Informative vs Enforcing Mode
| Mode | Exit Code | Use Case |
|---|---|---|
| Informative (default) | Always 0 | Distributed hooks for all repos |
| Enforcing | Non-zero on failure | AI agent hooks, CI validation |
The distributed hooks use informative mode to guide developers and AI agents without blocking workflow. For enforcing mode, see the agent-hooks skill which integrates with Claude Code and Cursor IDE.
References
Technology-specific hook patterns are available in the references/ folder:
| Technology | Reference |
|---|---|
| Java | references/java/hook-patterns.md |
| TypeScript/JavaScript | references/typescript/hook-patterns.md |
| Python | references/python/hook-patterns.md |
| Go | references/go/hook-patterns.md |
Documentation
For comprehensive documentation in the repository’s docs/ directory, see:
docs/ai-ide-management/concepts/git-hooks-architecture.md– System design and flow diagramsdocs/ai-ide-management/how-tos/enable-git-hooks.md– Setup and troubleshootingdocs/ai-ide-management/concepts/conflict-detection.md– How conflicts are detected during distribution
Related Skills
| Skill | Purpose |
|---|---|
agent-hooks |
AI IDE hooks (Claude Code, Cursor) with enforcing mode |
quality-gateway |
Quality gate orchestration |
coding-standards |
Code style enforcement |
Troubleshooting
Hooks not running
-
Verify hooks are installed:
git config --get core.hooksPath # Should output: .git-hooks -
Check symlinks are valid:
ls -la .git-hooks/ # Should show symlinks pointing to .scripts/*-hook.sh -
Verify execute permissions:
chmod +x .git-hooks/* chmod +x .scripts/*-hook.sh
Hooks running but failing
-
Run hooks manually to see full output:
./.scripts/pre-commit-hook.sh -
Check for missing dependencies:
npm install -
Run with DEBUG mode:
DEBUG=1 ./.scripts/pre-commit-hook.sh
Hooks too slow
-
Profile each check:
time npm run lint time npm test -
Move slow checks to pre-push
-
Use incremental/cached operations
-
Consider staged-files-only validation
Different behavior locally vs CI
- CI should skip hooks (set
CI=true) - CI runs validations directly, not via hooks
- Ensure setup-hooks.js checks for CI environment