git-hooks-setup
About
This Claude Skill helps developers set up Git hooks using Husky, pre-commit, and custom scripts to enforce code quality standards. It automates checks for linting, testing, and formatting before commits and pushes, preventing problematic code from reaching shared repositories. Use it to implement team-wide standards and ensure code quality throughout the development workflow.
Documentation
Git Hooks Setup
Overview
Configure Git hooks to enforce code quality standards, run automated checks, and prevent problematic commits from being pushed to shared repositories.
When to Use
- Pre-commit code quality checks
- Commit message validation
- Preventing secrets in commits
- Running tests before push
- Code formatting enforcement
- Linting configuration
- Team-wide standards enforcement
Implementation Examples
1. Husky Installation and Configuration
#!/bin/bash
# setup-husky.sh
# Install Husky
npm install husky --save-dev
# Initialize Husky
npx husky install
# Create pre-commit hook
npx husky add .husky/pre-commit "npm run lint"
# Create commit-msg hook
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'
# Create pre-push hook
npx husky add .husky/pre-push "npm run test"
# Create post-merge hook
npx husky add .husky/post-merge "npm install"
2. Pre-commit Hook (Node.js)
#!/usr/bin/env node
# .husky/pre-commit
const { execSync } = require('child_process');
const fs = require('fs');
console.log('π Running pre-commit checks...\n');
try {
// Get staged files
const stagedFiles = execSync('git diff --cached --name-only', { encoding: 'utf-8' })
.split('\n')
.filter(file => file && (file.endsWith('.js') || file.endsWith('.ts')))
.join(' ');
if (!stagedFiles) {
console.log('β
No JavaScript/TypeScript files to check');
process.exit(0);
}
// Run linter on staged files
console.log('π Running ESLint...');
execSync(`npx eslint ${stagedFiles} --fix`, { stdio: 'inherit' });
// Run Prettier
console.log('β¨ Running Prettier...');
execSync(`npx prettier --write ${stagedFiles}`, { stdio: 'inherit' });
// Stage the fixed files
console.log('π¦ Staging fixed files...');
execSync(`git add ${stagedFiles}`);
console.log('\nβ
Pre-commit checks passed!');
} catch (error) {
console.error('β Pre-commit checks failed!');
process.exit(1);
}
3. Commit Message Validation
#!/bin/bash
# .husky/commit-msg
# Validate commit message format
COMMIT_MSG=$(<"$1")
# Pattern: type(scope): description
PATTERN="^(feat|fix|docs|style|refactor|test|chore|perf)(\([a-z\-]+\))?: .{1,50}"
if ! [[ $COMMIT_MSG =~ $PATTERN ]]; then
echo "β Invalid commit message format"
echo "Format: type(scope): description"
echo "Types: feat, fix, docs, style, refactor, test, chore, perf"
echo ""
echo "Examples:"
echo " feat: add new feature"
echo " fix(auth): resolve login bug"
echo " docs: update README"
exit 1
fi
# Check message length
FIRST_LINE=$(echo "$COMMIT_MSG" | head -n1)
if [ ${#FIRST_LINE} -gt 72 ]; then
echo "β Commit message too long (max 72 characters)"
exit 1
fi
echo "β
Commit message is valid"
4. Commitlint Configuration
// commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [2, 'always', ['feat', 'fix', 'docs', 'style', 'refactor', 'test', 'chore']],
'subject-case': [2, 'never', ['start-case', 'pascal-case', 'upper-case']],
'type-empty': [2, 'never']
}
};
5. Pre-push Hook (Comprehensive)
#!/usr/bin/env bash
# .husky/pre-push
BRANCH=$(git rev-parse --abbrev-ref HEAD)
# Prevent direct pushes to main
if [[ "$BRANCH" =~ ^(main|master)$ ]]; then
echo "β Direct push to $BRANCH not allowed"
exit 1
fi
npm test && npm run lint && npm run build
6. Pre-commit Framework (Python)
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
args: ['--maxkb=1000']
- id: detect-private-key
- id: check-merge-conflict
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
language_version: python3.11
- repo: https://github.com/PyCQA/flake8
rev: 6.0.0
hooks:
- id: flake8
args: ['--max-line-length=88', '--extend-ignore=E203,W503']
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort
args: ['--profile', 'black']
- repo: https://github.com/Yelp/detect-secrets
rev: v1.4.0
hooks:
- id: detect-secrets
args: ['--baseline', '.secrets.baseline']
- repo: https://github.com/commitizen-tools/commitizen
rev: 3.5.2
hooks:
- id: commitizen
stages: [commit-msg]
7. Secret Detection Hook
#!/bin/bash
# .husky/pre-commit-secrets
git diff --cached | grep -E 'password|api_key|secret|token' && exit 1
echo "β
No secrets detected"
8. Husky in package.json
{
"scripts": { "prepare": "husky install" },
"devDependencies": {
"husky": "^8.0.0",
"@commitlint/cli": "^17.0.0"
},
"lint-staged": {
"*.{js,ts}": "eslint --fix"
}
}
Best Practices
β DO
- Enforce pre-commit linting and formatting
- Validate commit message format
- Scan for secrets before commit
- Run tests on pre-push
- Skip hooks only with
--no-verify(rarely) - Document hook requirements in README
- Use consistent hook configuration
- Make hooks fast (< 5 seconds)
- Provide helpful error messages
- Allow developers to bypass with clear warnings
β DON'T
- Skip checks with
--no-verify - Store secrets in committed files
- Use inconsistent implementations
- Ignore hook errors
- Run full test suite on pre-commit
Resources
Quick Install
/plugin add https://github.com/aj-geddes/useful-ai-prompts/tree/main/git-hooks-setupCopy and paste this command in Claude Code to install this skill
GitHub δ»εΊ
Related Skills
evaluating-llms-harness
TestingThis Claude Skill runs the lm-evaluation-harness to benchmark LLMs across 60+ standardized academic tasks like MMLU and GSM8K. It's designed for developers to compare model quality, track training progress, or report academic results. The tool supports various backends including HuggingFace and vLLM models.
webapp-testing
TestingThis Claude Skill provides a Playwright-based toolkit for testing local web applications through Python scripts. It enables frontend verification, UI debugging, screenshot capture, and log viewing while managing server lifecycles. Use it for browser automation tasks but run scripts directly rather than reading their source code to avoid context pollution.
finishing-a-development-branch
TestingThis skill helps developers complete finished work by verifying tests pass and then presenting structured integration options. It guides the workflow for merging, creating PRs, or cleaning up branches after implementation is done. Use it when your code is ready and tested to systematically finalize the development process.
go-test
MetaThe go-test skill provides expertise in Go's standard testing package and best practices. It helps developers implement table-driven tests, subtests, benchmarks, and coverage strategies while following Go conventions. Use it when writing test files, creating mocks, detecting race conditions, or organizing integration tests in Go projects.
