
Git Hooks Setup
- 367 installs
- 305 repo stars
- Updated March 4, 2026
- aj-geddes/useful-ai-prompts
git-hooks-setup is an agent skill that configures Husky, pre-commit, and commitlint Git hooks to enforce linting, formatting, secret scanning, and tests before developers commit or push code.
About
Prompt skill from aj-geddes/useful-ai-prompts for git hooks setup: walks through installing and configuring pre-commit tooling, linking formatters and test runners, and standardizing commit hygiene across a repo.
- Husky or native hook setup
- Lint and test on commit
- Commit message conventions
- Hook performance tuning
- Team onboarding for hooks
Git Hooks Setup by the numbers
- 367 all-time installs (skills.sh)
- +9 installs in the week ending Jun 23, 2026 (Skillselion tracking)
- Ranked #126 of 733 Git & Pull Requests skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/aj-geddes/useful-ai-prompts --skill git-hooks-setupAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 367 |
|---|---|
| repo stars | ★ 305 |
| Last updated | March 4, 2026 |
| Repository | aj-geddes/useful-ai-prompts ↗ |
How do you set up Git pre-commit and pre-push hooks?
Configure pre-commit, pre-push, and commit-msg hooks to enforce linting, tests, formatting, and conventional commits before code merges.
Who is it for?
Developers standardizing lint, conventional commits, and pre-push tests across JavaScript or Python repositories using Husky or pre-commit.
Skip if: Teams that rely solely on server-side CI with no local hook enforcement or repositories that cannot run npm or pre-commit tooling.
When should I use this skill?
A developer needs pre-commit linting, commit message validation, secret scanning, or pre-push test hooks before merging to main.
What you get
.husky hook scripts, commitlint configuration, pre-commit lint and test gates, and documented team hook requirements in README.
- .husky hook scripts
- commitlint config
- secret-scan hook
By the numbers
- Bundles 6 reference guides for Husky, pre-commit, and commitlint
- Quick Start configures 4 Husky hooks: pre-commit, commit-msg, pre-push, post-merge
Files
Git Hooks Setup
Table of Contents
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
Quick Start
Minimal working example:
#!/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"Reference Guides
Detailed implementations in the references/ directory:
| Guide | Contents |
|---|---|
| Husky Installation and Configuration | Husky Installation and Configuration |
| Pre-commit Hook (Node.js) | Pre-commit Hook (Node.js) |
| Commit Message Validation | Commit Message Validation |
| Commitlint Configuration | Commitlint Configuration, Pre-push Hook (Comprehensive) |
| Pre-commit Framework (Python) | Pre-commit Framework (Python) |
| Secret Detection Hook | Secret Detection Hook, Husky in package.json |
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
Commit Message Validation
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"Commitlint Configuration
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"],
},
};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 buildHusky Installation and Configuration
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"Pre-commit Framework (Python)
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]Pre-commit Hook (Node.js)
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);
}Secret Detection Hook
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"Husky in package.json
{
"scripts": { "prepare": "husky install" },
"devDependencies": {
"husky": "^8.0.0",
"@commitlint/cli": "^17.0.0"
},
"lint-staged": {
"*.{js,ts}": "eslint --fix"
}
}#!/bin/bash
# scaffold-tests.sh - Generate test file scaffolding
# Usage: ./scaffold-tests.sh <source_file> [--framework jest|pytest|mocha]
set -euo pipefail
SOURCE_FILE="${{1:?Usage: $0 <source_file> [--framework jest|pytest|mocha]}}"
FRAMEWORK="${{2:-jest}}"
echo "Scaffolding tests for: $SOURCE_FILE (framework: $FRAMEWORK)"
# TODO: Implement test scaffolding logic
# - Parse source file for exported functions/classes
# - Generate test stubs for each export
# - Include setup/teardown boilerplate
# - Add common assertion patterns
echo "Test scaffolding complete."
// Test Template
// TODO: Customize for your testing framework and project
describe('ModuleName', () => {
// Setup
beforeEach(() => {
// TODO: Add test setup
});
afterEach(() => {
// TODO: Add cleanup
});
describe('functionName', () => {
it('should handle the happy path', () => {
// TODO: Add assertion
});
it('should handle edge cases', () => {
// TODO: Add edge case tests
});
it('should handle errors gracefully', () => {
// TODO: Add error handling tests
});
});
});
Related skills
How it compares
Use git-hooks-setup when you want opinionated Husky and commitlint recipes instead of writing raw .git/hooks scripts from scratch.
FAQ
Which hook tools does git-hooks-setup cover?
git-hooks-setup documents Husky for Node projects, the Python pre-commit framework, commitlint for conventional commits, and a secret-detection hook pattern. git-hooks-setup includes six reference guides with full installation and configuration steps.
What hooks does the git-hooks-setup Quick Start create?
git-hooks-setup Quick Start adds Husky pre-commit running npm run lint, commit-msg invoking commitlint, pre-push running npm run test, and post-merge running npm install to refresh dependencies after pulls.