git-hooks

This skill provides guidance for implementing and maintaining Git hooks that enforce code quality standards before commits and pushes reach the repository.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "git-hooks" with this command: npx skills add bitsoex/bitso-java/bitsoex-bitso-java-git-hooks

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

  • Distributed Hooks (Informative Mode)

  • Assets

  • Architecture

  • Instructions

  • Hook Types

  • Best Practices

  • Hook Modes

  • References

  • Documentation

  • Related Skills

  • hk (ai-code-instructions only)

  • Troubleshooting

Available Resources

📚 references/ - Detailed documentation

  • go

  • java

  • python

  • typescript

📦 assets/ - Templates and resources

  • ensure node

  • hooks bootstrap

  • hooks bridge strategy

  • hooks checks

  • pre commit

  • pre push

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 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.ts # 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 install configures hooks via prepare script

  • 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. */

import fs from 'fs'; import path from 'path'; import { execSync } from 'child_process'; import { fileURLToPath } from 'url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

if (process.env.CI || process.env.SKIP_HOOKS) { console.log('⏭️ Skipping hook setup (CI or SKIP_HOOKS=true)'); process.exit(0); }

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) { const err = error as Error; console.error('❌ Failed to set core.hooksPath:', err.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

  1. 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

  1. 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

  1. Allow Emergency Bypass

Document how to skip in emergencies

git commit --no-verify # Skip pre-commit git push --no-verify # Skip pre-push

  1. 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

  1. 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

  1. 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-verify as 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 ] }

Hook Modes

Git hooks support a unified mode system controlled via environment variables.

Mode Values

Mode Description

skip

Completely skip the hook - no execution, no output

info

Show informational messages only; do NOT execute scripts

warn

Execute scripts, show results, but never fail (always exit 0)

full

Execute scripts and fail when the script results in a failure (default)

Environment Variables

Variable Description

BITSO_MISE_MODE

Global mode for all hooks

BITSO_MISE_GIT_HOOKS

Category-level mode for all git hooks

BITSO_MISE_GIT_HOOKS_COMMIT

Hook-specific mode for pre-commit

BITSO_MISE_GIT_HOOKS_PUSH

Hook-specific mode for pre-push

BITSO_MISE_GIT_HOOKS_CI

Hook-specific mode for CI validation

Resolution Order

  • Hook-specific env var (e.g., BITSO_MISE_GIT_HOOKS_COMMIT )

  • Category env var (BITSO_MISE_GIT_HOOKS )

  • Global env var (BITSO_MISE_MODE )

  • Default: full

Example Configuration

In mise.local.toml :

[env]

Run git hooks but don't fail locally

BITSO_MISE_GIT_HOOKS = "warn"

Or: Fine-grained control

BITSO_MISE_GIT_HOOKS_COMMIT = "warn" # Don't block commits BITSO_MISE_GIT_HOOKS_PUSH = "full" # But enforce on push

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 diagrams

  • docs/ai-ide-management/how-tos/enable-git-hooks.md

  • Setup and troubleshooting

  • docs/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-checks

Quality gate orchestration

coding-standards

Code style enforcement

hk (ai-code-instructions only)

Note: This section is specific to the ai-code-instructions repository which uses hk as its git hook manager.

hk provides:

  • Parallel execution: Runs multiple linters simultaneously

  • Smart stashing: Safely stashes unstaged changes during hooks

  • Progress reporting: Clear visual feedback during hook execution

  • Profile-based configuration: Enable/disable checks via profiles

Configuration

hk is configured via hk.pkl in the repository root:

hooks { ["pre-commit"] { stash = "git" steps { ["eslint-staged"] = new Step { check = "node mise-tasks/check.ts eslint-staged" } ["tests-changed"] = new Step { check = "node mise-tasks/check.ts tests-changed" } } } }

Common Commands

Run hooks manually

hk run pre-commit # Run pre-commit checks hk run pre-push # Run pre-push checks hk run ci # Run CI checks

Check and fix

hk check # Run all checks (read-only) hk check --pr # Check only files changed in current PR/branch hk fix # Auto-fix where possible hk fix --pr # Fix only files changed in current PR/branch

Test step definitions

hk test # Run step-defined tests

Validate configuration

hk validate # Validate hk.pkl

Skip hooks

git commit --no-verify # Standard git bypass HK_SKIP_HOOKS=pre-commit git commit # Skip specific hook

Installation

Install via Homebrew

brew install hk

Download pkl packages (required for SSL cert compatibility)

pkl download-package --ca-certificates=/path/to/ca.pem
package://github.com/jdx/hk/releases/download/v1.36.0/hk@1.36.0

Install hooks

hk install

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.ts checks for CI environment

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

coderabbit-interactions

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

coderabbit-workflow

No summary provided by upstream source.

Repository SourceNeeds Review
General

gradle-standards

No summary provided by upstream source.

Repository SourceNeeds Review
General

java-coverage

No summary provided by upstream source.

Repository SourceNeeds Review