Skip to content

Git Hooks Configuration

This repository uses Husky to manage Git hooks that enforce code quality and security standards.

Installed Hooks

Pre-Commit Hook

Runs before a commit is created. Validates 17 different checks:

1. Merge Conflict Markers (BLOCKING)

  • Detects <<<<<<<, =======, >>>>>>> markers
  • Prevents accidentally committing unresolved conflicts
  • Blocks commit until resolved

2. Trailing Whitespace (WARNING)

  • Detects trailing spaces at end of lines
  • Suggests using linters to auto-fix
  • Non-blocking - shows warning only

3. Non-ASCII Filenames (BLOCKING)

  • Ensures all filenames use ASCII characters only
  • Prevents cross-platform compatibility issues
  • Blocks commit if non-ASCII characters found

4. Executable Script Shebang (BLOCKING)

  • Checks that executable scripts (.sh, .py, .rb, etc.) have shebang lines
  • Example: #!/bin/bash, #!/usr/bin/env python3
  • Blocks commit if missing

5. Hardcoded Localhost/IPs (WARNING)

  • Detects http://localhost, https://127.0.0.1 in production code
  • Suggests using environment variables instead
  • Excludes test files and .env.example
  • Bypass: Add // OK: comment
  • Non-blocking - shows warning only

6. Large Commented Code Blocks (WARNING)

  • Detects files with >30% commented code
  • Suggests removing dead code or using version control
  • Non-blocking - shows warning only

7. Empty Catch Blocks (WARNING)

  • Detects catch() {} with no error handling
  • Suggests proper error handling or logging
  • Bypass: Add // OK: comment
  • Non-blocking - shows warning only

8. process.exit() in Library Code (WARNING)

  • Detects process.exit() outside of CLI/scripts
  • Suggests throwing errors instead
  • Excludes cli/, scripts/, bin/ directories
  • Bypass: Add // OK: comment
  • Non-blocking - shows warning only

9. TypeScript 'any' Type (WARNING)

  • Detects : any type annotations
  • Suggests using specific types or unknown
  • Bypass: Add // OK: or eslint-disable comment
  • Non-blocking - shows warning only

10. console.error/warn in Production (WARNING)

  • Detects console.error() and console.warn() in production code
  • Suggests using proper logger instead
  • Excludes test files
  • Bypass: Add // OK: comment
  • Non-blocking - shows warning only

11. Package.json Validation (BLOCKING)

  • All package.json files must be valid JSON
  • Prevents broken package configurations
  • Blocks commit if invalid JSON

12. Secret Detection (BLOCKING)

  • Scans staged files for API keys, tokens, passwords
  • Blocks commits containing patterns like:
    • api_key = "sk_live_..."
    • secret: "abc123..."
    • AWS keys (AKIA...)
    • Google API keys (AIza...)
  • Bypass: .env.example files are excluded

13. .env File Protection (BLOCKING)

  • Blocks any .env file from being committed
  • Allows .env.example files
  • Prevents accidental credential exposure

14. Large File Detection (BLOCKING)

  • Blocks files larger than 10MB
  • Suggests using Git LFS or external storage

15. Sensitive File Patterns (BLOCKING)

Blocks files matching:

  • credentials.json
  • service_account.json
  • *.pem, *.key, *.p12, *.pfx
  • auth.json
  • secrets.yaml, secrets.yml

16. Debug Code Detection (WARNING)

  • Warns about console.log, debugger, TODO:, FIXME:, XXX:
  • Does not block commit (warning only)
  • Bypass: Add // OK: comment to line

Example:

typescript
console.log("Important debug info") // OK: needed for production logging

17. TypeScript Type Checking (WARNING)

  • Runs tsc --noEmit if tsconfig.json exists
  • Shows type errors but doesn't block commit

Commit-Msg Hook

Runs after commit message is written but before commit is finalized. Validates 12 checks:

1. Commit Subject Length (BLOCKING)

  • Subject line must be ≤100 characters
  • Longer subjects should move details to body
  • Blocks commit if too long

2. WIP Commits (BLOCKING)

  • Blocks commits starting with "WIP", "wip", or "work in progress"
  • These should not be pushed to main/master branches
  • Blocks commit - finish work or use feature branch
  • Bypass: Use --no-verify flag

3. All Caps Subject (WARNING)

  • Warns if subject line is in ALL CAPS (>20 chars)
  • Suggests sentence case for readability
  • Non-blocking - shows warning only

4. Period at End of Subject (WARNING)

  • Warns if subject line ends with a period
  • Convention: subjects should not end with punctuation
  • Non-blocking - shows warning only

5. Empty Scope Check (WARNING)

  • Warns if conventional commit has empty scope: feat(): message
  • Either provide scope or remove parentheses
  • Non-blocking - shows warning only

6. Merge Commit on Feature Branch (WARNING)

  • Warns if merge commit detected on non-main branch
  • Suggests rebasing to keep history clean
  • Non-blocking - shows warning only

7. Profanity/Inappropriate Language (BLOCKING)

  • Blocks commit messages with unprofessional language
  • Patterns: fuck, shit, damn, ass, bastard, bitch, wtf, etc.
  • Helps maintain respectful codebase
  • Blocks commit until language is professional

8. Fixup/Squash on Main (BLOCKING)

  • Blocks fixup! or squash! commits on main/master
  • These should be auto-squashed before merging
  • Use git rebase -i --autosquash first
  • Blocks commit on protected branches

9. Empty Body on Substantial Commits (WARNING)

  • Warns if feat, refactor, or perf commits have no body
  • Suggests adding details about what changed and why
  • Non-blocking - shows warning only

10. Claude Code Attribution Block (BLOCKING)

Blocks commit messages containing:

🤖 Generated with [Claude Code](...)
Co-Authored-By: Claude <noreply@anthropic.com>

These lines should NEVER be included per CLAUDE.md guidelines.

11. Secret Detection in Messages (BLOCKING)

  • Blocks commit messages containing actual API keys/secrets
  • Pattern: api_key=abc123...
  • Allows: References to environment variables ("Add API_KEY variable")

12. Conventional Commits Format (BLOCKING)

Enforces Conventional Commits format:

<type>(<scope>): <subject>

<body>

<footer>

Valid types:

  • feat - New feature
  • fix - Bug fix
  • docs - Documentation only
  • style - Code style (formatting, semicolons, etc)
  • refactor - Code restructuring
  • perf - Performance improvement
  • test - Adding tests
  • chore - Maintenance tasks
  • ci - CI/CD changes
  • build - Build system changes
  • revert - Revert previous commit
  • release - Release version
  • pet - Pet-specific changes

Valid scopes:

  • core, sdk, cli, web, desktop, ci, deps, scripts, docs
  • Or any pet name: jira, notion, github, etc.

Examples:

bash
feat(jira): add bulk issue creation tool
fix(core): resolve type export conflicts
docs: update README with new examples
chore(deps): update dependencies
pet(hotels): add new booking provider

Pre-Push Hook

Runs before pushing to remote. Validates 10 checks to ensure quality:

1. Force Push to Protected Branches (BLOCKING)

  • Prevents force pushing to main, master, or develop
  • Could destroy commit history for other developers
  • Blocks push to protected branches
  • Bypass: Use --no-verify (dangerous!)

2. Branch Naming Convention (WARNING)

  • Checks branch follows standard patterns:
    • feature/description - New features
    • fix/description - Bug fixes
    • hotfix/description - Critical production fixes
    • chore/description - Maintenance
    • docs/description - Documentation
    • release/v1.2.3 - Releases
  • Non-blocking - shows suggestion only

3. Test Execution (WARNING)

  • Runs tests before pushing (if test script exists)
  • Uses bun test command from package.json
  • Non-blocking - shows warning if tests fail
  • Encourages fixing tests before push

4. Untracked Files Check (WARNING)

  • Lists untracked files that might need committing
  • Excludes node_modules, .cache, dist, build
  • Suggests adding to .gitignore if intentional
  • Non-blocking - informational only

5. Uncommitted Changes Check (WARNING)

  • Warns if uncommitted changes exist
  • Shows git status output
  • Suggests committing or stashing before push
  • Non-blocking - informational only

6. Commit Count Check (WARNING)

  • Warns if >10 commits ahead of remote
  • Suggests pushing more frequently or squashing
  • Non-blocking - informational only

7. Large Commit Detection (WARNING)

  • Detects commits >5MB in size
  • Suggests using Git LFS for large files
  • Non-blocking - shows warning only

8. Direct Push to Main Warning (WARNING)

  • Warns when pushing directly to main/master
  • Suggests using feature branches and pull requests
  • Helps maintain code review process
  • Non-blocking - informational only

9. TODO/FIXME Count (WARNING)

  • Counts new TODO/FIXME comments in push
  • Warns if >5 new TODOs added
  • Suggests creating issues for tracking
  • Non-blocking - shows warning only

10. Merge Conflict Mentions (WARNING)

  • Checks commit messages for "conflict" mentions
  • Verifies merge conflicts are actually resolved
  • Non-blocking - shows warning only

Testing Hooks Locally

Test Pre-Commit Hook

bash
# Manually run the hook
.husky/pre-commit

# Stage a file with secrets to test
echo 'const API_KEY = "sk_live_abc123..."' > test.ts
git add test.ts
git commit -m "test"  # Should be blocked
rm test.ts

Test Commit-Msg Hook

bash
# Test with invalid message
echo "bad commit message" | .husky/commit-msg /dev/stdin

# Test with Claude attribution
echo "feat: add feature

Co-Authored-By: Claude <noreply@anthropic.com>" | .husky/commit-msg /dev/stdin
# Should be blocked

In rare cases where you need to bypass hooks:

bash
# Skip pre-commit hook
git commit --no-verify -m "message"

# Skip all hooks
git commit -n -m "message"

Warning: Only use --no-verify when absolutely necessary and you understand the risks.

Disabling Hooks

To temporarily disable hooks:

bash
# Remove execute permissions
chmod -x .husky/pre-commit
chmod -x .husky/commit-msg

# Re-enable
chmod +x .husky/pre-commit
chmod +x .husky/commit-msg

To permanently disable:

bash
rm -rf .husky
npm uninstall husky

Hook Maintenance

Adding New Checks

Edit .husky/pre-commit or .husky/commit-msg:

bash
# Add new pre-commit check
vim .husky/pre-commit

# Add new commit message validation
vim .husky/commit-msg

# Make sure hooks are executable
chmod +x .husky/*

Common Issues

"command not found: bunx"

Install bun or modify hooks to use npm/npx:

bash
# In .husky/commit-msg, replace:
bunx --bun commitlint
# With:
npx commitlint

"jq: command not found"

Install jq for JSON validation:

bash
# macOS
brew install jq

# Ubuntu/Debian
sudo apt-get install jq

# Or comment out the package.json validation in pre-commit

Hooks Not Running

bash
# Reinstall hooks
npm run prepare

# Or manually
bunx husky install

CI/CD Integration

These same checks run in CI/CD pipelines. Local hooks ensure you catch issues before pushing.

References