SuperAPI AI Directory

git-hooks-setup

Coding & development

View repository

Updated 10-14 05:41

About this skill

Git Hooks Setup

One-click configure Git Hooks to standardize the team development workflow.

Overview

Automatically generate pre-commit / commit-msg / pre-push hook configurations, including code formatting, commit message validation, and sensitive information checks. Supports both husky and native git hooks approaches.

When to Use

  • User wants to set up git hooks
  • User mentions pre-commit or commit message conventions
  • User wants to automate lint/format checks
  • User inputs /git-hooks-setup
  • User wants to enforce pre-push checks (tests, lint)
  • User wants to prevent pushing broken code
  • User wants to standardize team commit message format
  • User wants to add secret scanning before commit
  • User wants to auto-format code on every commit

When NOT to Use:

  • User only wants to view current git hooks configuration
  • User wants CI-based checks (no local hooks needed)
  • User's project already has a complete hooks setup
  • User wants to run hooks on specific files only (use lint-staged directly)
  • User wants to hook into Git events other than pre-commit/commit-msg/push

Core Pattern

Step 1: Detect the project environment

# 检测包管理器(按 lock 文件判断)
if [ -f "package-lock.json" ]; then PACKAGE_MANAGER="npm"
elif [ -f "yarn.lock" ]; then PACKAGE_MANAGER="yarn"
elif [ -f "pnpm-lock.yaml" ]; then PACKAGE_MANAGER="pnpm"

# 检测已有 hooks 配置
test -d ".husky" && echo "husky 已配置"
test -f ".git/hooks/pre-commit" && echo "原生 hooks 已配置"

# 从 package.json 检测已安装的 lint 工具(eslint/prettier/lint 相关)

Step 2: Choose an approach

Approach Use case Advantages
husky Node.js projects Team collaboration friendly, configuration as code
Native git hooks Non-Node.js projects No dependencies

Step 3: Generate configuration

Approach A: Husky

# 根据 $PACKAGE_MANAGER 选择: pnpm dlx / yarn dlx / npx
husky init    # 初始化 husky

Generate .husky/pre-commit(executes lint-staged) and .husky/commit-msg(executes commitlint), note that commitlint requires adding the --no prefix to avoid interactive installation.

Generate lint-staged configuration (written to package.json):

{
  "lint-staged": {
    "*.{ts,tsx,js,jsx}": ["eslint --fix", "prettier --write"],
    "*.{json,md,yml}": ["prettier --write"]
  }
}

Generate .husky/pre-push(optional, run tests before push):

# 根据包管理器选择命令
if [ "$PACKAGE_MANAGER" = "pnpm" ]; then
  pnpm test
elif [ "$PACKAGE_MANAGER" = "yarn" ]; then
  yarn test
else
  npm test
fi

Approach B: Native git hooks

cat > .git/hooks/pre-commit << 'EOF'
#!/bin/sh
# 自动 lint + format(按项目实际替换命令;示例为 Node 项目)
if [ -f "package.json" ] && [ -x "$(command -v npm)" ]; then
  npm run lint -- --fix 2>/dev/null || true
  npm run format 2>/dev/null || true
fi
# 注意:不要执行 git add -u —— 那会把用户未暂存的改动也一并提交。
# 若需把 lint 修复的结果纳入提交,请使用 lint-staged(只处理暂存文件)。
EOF
chmod +x .git/hooks/pre-commit

# pre-push hook(可选,push 前跑测试;按项目实际替换)
cat > .git/hooks/pre-push << 'EOF'
#!/bin/sh
if [ -f "package.json" ] && [ -x "$(command -v npm)" ]; then
  npm test || exit 1
fi
EOF
chmod +x .git/hooks/pre-push

Step 4: Configure the Commit Message convention

Copy templates/commitlint.config.js to the project root directory (commitlint.config.js). This configuration is based on @commitlint/config-conventional, and validates the commit message format:

type(scope): subject

# type: feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert
# scope: 可选,影响范围
# subject: 简短描述(header-max-length 限制 100 字符)

Install the commitlint dependency at the same time:

npm install -D @commitlint/cli @commitlint/config-conventional

Step 5: Add sensitive information checks

⚠️ Do not use keyword scanning like grep "password|secret|token" — it is normal for the words "token"/"secret" to appear in business code, and this will cause widespread false positives that frequently block commits.

It is recommended to use gitleaks(specifically for secret scanning, with built-in entropy detection + allowlist, and a low false positive rate):

# 生成 gitleaks pre-commit hook
npx gitleaks git-config 2>/dev/null || brew install gitleaks && gitleaks git-config
# 或手动在 .git/hooks/pre-commit 中加入:
# gitleaks protect --staged --verbose 2>&1
# 若 gitleaks 不可用,宁可跳过也不要退化成关键字 grep

If gitleaks really cannot be installed, as a fallback you should still avoid whole-word false positives — only matchhigh-confidence patterns(such as private key blocks and AWS key formats), and do not match commonly used business words like token/secret/password :

# 低误报替代方案:只扫私钥和云厂商密钥格式(示例)
if git diff --cached --diff-filter=ACM --name-only -z | xargs -0 grep -IlE "BEGIN (RSA |EC |OPENSSH )?PRIVATE KEY|AKIA[0-9A-Z]{16}|ghp_[A-Za-z0-9]{36}" 2>/dev/null | grep -q .; then
  echo "警告: 检测到可能的密钥泄露,请检查后重新提交"
  exit 1
fi

Quick Reference

/git-hooks-setup                    # 交互式选择方案和 hooks
/git-hooks-setup --husky            # 直接用 husky
/git-hooks-setup --native           # 直接用原生 git hooks
Parameter Description Default value
--husky Use husky Auto-detect
--native Use native git hooks false
--commitlint Add commit message validation true

Common Mistakes

Mistake Correct practice Reason
The hook script does not have execute permission chmod +x .git/hooks/* The hook will not run
lint-staged is configured with too many rules Only check staged files Reduce commit waiting time
Commit message validation is too strict Start lenient, then tighten Avoid team resistance
Do not check for sensitive information Add secret scanning Prevent leaks
.git/hooks is not committed Manage with husky/lefthook The team needs to share configuration
The pre-push hook runs too long Run only quick checks, put full tests in CI Push being blocked affects efficiency
Use relative paths in hooks Use absolute paths or the project root directory Path resolution fails when executed from different directories
Skip the prepare script Ensure that package.json's prepare runs husky(v9+) CI environment hook does not take effect
commitlint rules are inconsistent with the team Use commitlint.config.js unified configuration Verbal agreements are easily violated
Do not configure a --no-verify whitelist Allow --no-verify but log it Emergency fixes must not be completely blocked