git-hooks | Skill Performance & Reviews | TopRankSkills

TopRank Skills

Home / Skills / tools / git-hooks

git-hooks

maintained by bitsoex

star 35 account_tree 30 verified_user MIT License
bolt View GitHub

name: git-hooks description: > Set up, validate, and maintain Git hooks (pre-commit, pre-push, etc.) following best practices. Ensures hooks are version-controlled, automatically installed, and follow consistent patterns across the team. Use when creating new hooks, debugging hook issues, or ensuring hook compliance. compatibility: Requires Node.js 20+; works with any Git repository metadata: version: "2.0" targeting: include: - repo: "bitsoex/ai-code-instructions"

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

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: pnpm 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 local hook in .pre-commit-config.yaml
  • lefthook: Add to lefthook.yml commands

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?

  1. Version-controlled: Hooks live in .git-hooks/, tracked by Git
  2. Automatic installation: npm install configures hooks via prepare script
  3. Team consistency: Everyone gets the same hooks automatically
  4. Implementation separation: Actual logic in .scripts/, symlinks in .git-hooks/
  5. 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:

  1. Add tests to increase coverage (preferred)
  2. Use --no-verify as a temporary emergency bypass if absolutely necessary
  3. 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, see:

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

  1. Verify hooks are installed:

    git config --get core.hooksPath
    # Should output: .git-hooks
    
  2. Check symlinks are valid:

    ls -la .git-hooks/
    # Should show symlinks pointing to .scripts/*-hook.sh
    
  3. Verify execute permissions:

    chmod +x .git-hooks/*
    chmod +x .scripts/*-hook.sh
    

Hooks running but failing

  1. Run hooks manually to see full output:

    ./.scripts/pre-commit-hook.sh
    
  2. Check for missing dependencies:

    npm install
    
  3. Run with DEBUG mode:

    DEBUG=1 ./.scripts/pre-commit-hook.sh
    

Hooks too slow

  1. Profile each check:

    time npm run lint
    time npm test
    
  2. Move slow checks to pre-push

  3. Use incremental/cached operations

  4. Consider staged-files-only validation

Different behavior locally vs CI

  1. CI should skip hooks (set CI=true)
  2. CI runs validations directly, not via hooks
  3. Ensure setup-hooks.js checks for CI environment

chat Comments (0)

chat_bubble_outline

No comments yet. Be the first to share your thoughts!

Skill Details

GitHub Stars 35
GitHub Forks 30
Created Jan 2026
Last Updated 4 months ago
tools tools automation tools

Related Skills

specs-gen
chevron_right
pr

pr

MoonshotAI
star 6.1k
chevron_right
glm-coding-agent
chevron_right
feature-dev
chevron_right
writing-skills
chevron_right

Build your own?

Join 12,000+ developers contributing to the Claude ecosystem.