Skip to main content

git-hooks

This skill should be used when the user asks to "create git hooks", "set up pre-commit hooks", "configure git hooks", "add commit validation", "implement pre-push hooks", or needs guidance on Git hooks implementation, validation scripts, or hook best practices.

来源信息

仓库
the-perfect-developer/the-perfect-opencode
最近来源活动
2026年2月19日 08:38
检测到的 SKILL.md 语言
英语
星标
12
分支
2

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

文件资源管理器
12 个文件

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
git-hooks
description
This skill should be used when the user asks to "create git hooks", "set up pre-commit hooks", "configure git hooks", "add commit validation", "implement pre-push hooks", or needs guidance on Git hooks implementation, validation scripts, or hook best practices.
# Git Hooks Automate code quality, testing, and validation using Git hooks—scripts that run automatically at key points in the Git workflow. ## What Are Git Hooks Git hooks are executable scripts that Git runs automatically when specific events occur in a repository. They enable you to: - **Enforce code quality** before commits reach the repository - **Run automated tests** to catch issues early - **Validate commit messages** to maintain consistent standards - **Prevent accidental destructive actions** like force pushes - **Trigger CI/CD workflows** on push events - **Automate versioning and tagging** for releases Hooks reside in `.git/hooks/` by default, but can be version-controlled using `core.hooksPath` configuration. ## Core Concepts ### Hook Types **Client-side hooks** (run on developer machines): - `pre-commit` - Before commit is created, validate staged changes - `prepare-commit-msg` - Populate commit message template - `commit-msg` - Validate commit message format - `post-commit` - Notification after successful commit - `pre-push` - Before pushing to remote, run tests - `post-checkout` - After checkout, clean up working directory - `pre-rebase` - Before rebasing, check for conflicts **Server-side hooks** (run on remote repository): - `pre-receive` - Before accepting pushed refs, enforce policies - `update` - Like pre-receive, but runs per branch - `post-receive` - After successful push, trigger CI/CD ### Hook Lifecycle ``` Developer action → Git event → Hook script runs → Exit code determines outcome ``` - **Exit 0**: Continue with Git operation - **Exit non-zero**: Abort Git operation with error message ### Making Hooks Executable Hooks must have execute permissions: ```bash chmod +x .git/hooks/pre-commit ``` ## Essential Workflows ### Setting Up Version-Controlled Hooks Git doesn't version-control `.git/hooks/` by default. Use `core.hooksPath` to enable team-wide hooks: **1. Create hooks directory in repository**: ```bash mkdir .githooks ``` **2. Configure Git to use custom hooks path**: ```bash git config core.hooksPath .githooks ``` **3. Add hooks to version control**: ```bash git add .githooks/ git commit -m "Add version-controlled git hooks" ``` **4. Team members run after cloning**: ```bash git config core.hooksPath .githooks ``` This project follows this pattern. See `.githooks/` directory for working examples. ### Creating a Basic Pre-Commit Hook **Use case**: Validate bash scripts before committing. **1. Create hook file**: ```bash touch .githooks/pre-commit chmod +x .githooks/pre-commit ``` **2. Add validation logic**: ```bash #!/bin/bash set -e echo "🔍 Validating bash scripts..." # Get staged .sh files STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.sh$' || true) if [ -z "$STAGED_FILES" ]; then echo "✅ No bash scripts to validate" exit 0 fi # Validate syntax for file in $STAGED_FILES; do if [ -f "$file" ]; then echo "Checking $file..." bash -n "$file" || exit 1 fi done echo "✅ All bash scripts valid" exit 0 ``` **Key patterns**: - Use `set -e` to fail fast on errors - Check for staged files with `git diff --cached` - Exit early if no relevant files - Provide clear visual feedback with emojis - Exit with non-zero on validation failure ### Modular Hook Architecture **Problem**: Single hook file becomes complex with multiple validations. **Solution**: Orchestrator pattern that discovers and runs modular hook scripts. **1. Create hooks.d/ directory**: ```bash mkdir .githooks/hooks.d ``` **2. Create orchestrator in pre-commit**: ```bash #!/bin/bash set -e HOOKS_DIR="$(dirname "$0")/hooks.d" if [ -d "$HOOKS_DIR" ]; then for hook in "$HOOKS_DIR"/*; do if [ -x "$hook" ]; then echo "Running: $(basename "$hook")" "$hook" || exit 1 fi done fi exit 0 ``` **3. Add individual validation scripts**: ```bash # .githooks/hooks.d/10-validate-bash.sh # .githooks/hooks.d/20-validate-yaml.sh # .githooks/hooks.d/30-run-tests.sh ``` **Naming convention**: Use numbered prefixes (10, 20, 30) to control execution order and allow inserting new hooks between existing ones (e.g., add a hypothetical `15-validate-json.sh` between 10 and 20). This project uses this pattern. See `.githooks/hooks.d/` for examples. ### Validating Commit Messages **Use case**: Enforce conventional commit format. **Create commit-msg hook**: ```bash #!/bin/bash COMMIT_MSG_FILE=$1 COMMIT_MSG=$(cat "$COMMIT_MSG_FILE") # Pattern: type(scope): description PATTERN="^(feat|fix|docs|style|refactor|test|chore)(\(.+\))?: .{10,}$" if ! echo "$COMMIT_MSG" | grep -qE "$PATTERN"; then echo "❌ Invalid commit message format" echo "" echo "Expected format: type(scope): description" echo "Types: feat, fix, docs, style, refactor, test, chore" echo "Example: feat(auth): add OAuth2 login support" exit 1 fi echo "✅ Commit message valid" exit 0 ``` ### Running Tests Before Push **Use case**: Prevent pushing broken code to remote. **Create pre-push hook**: ```bash #!/bin/bash set -e echo "🧪 Running tests before push..." # Run test suite npm test || { echo "❌ Tests failed. Push aborted." exit 1 } echo "✅ All tests passed" exit 0 ``` ### Preventing Force Push to Main **Use case**: Protect production branches from destructive operations. **Create pre-push hook**: ```bash #!/bin/bash PROTECTED_BRANCHES="^(main|master|production)$" while read local_ref local_sha remote_ref remote_sha; do remote_branch=$(echo "$remote_ref" | sed 's/refs\/heads\///') if echo "$remote_branch" | grep -qE "$PROTECTED_BRANCHES"; then # Check if it's a force push if [ "$local_sha" = "0000000000000000000000000000000000000000" ]; then echo "❌ Deleting $remote_branch is not allowed" exit 1 fi # Check for force push if ! git merge-base --is-ancestor "$remote_sha" "$local_sha" 2>/dev/null; then echo "❌ Force push to $remote_branch is not allowed" exit 1 fi fi done exit 0 ``` ## Project-Specific Implementation This repository implements a production-ready Git hooks system. Follow this implementation pattern for your projects. ### Directory Structure ``` .githooks/ ├── pre-commit # Orchestrator script ├── hooks.d/ # Individual validation scripts │ ├── the-perfect-developer-base-collection-10-validate-bash.sh │ └── the-perfect-developer-base-collection-20-validate-skills.sh └── README.md # Documentation ``` ### Installation **Automated setup**: ```bash ./setup-hooks.sh ``` This configures `git config core.hooksPath .githooks` automatically. ### Hook Naming Convention Use this pattern for modular hooks: ``` the-perfect-developer-base-collection-<number>-<description>.sh ``` - **Prefix**: Project/team identifier - **Number**: Execution order (increments of 10: 10, 20, 30...) - **Description**: What the hook validates Increments of 10 allow inserting new hooks between existing ones (e.g., add `15-validate-json.sh` between 10 and 20). ### Testing Individual Hooks Run hooks independently for testing: ```bash # Test single hook .githooks/hooks.d/10-validate-bash.sh # Test orchestrator .githooks/pre-commit # Temporarily disable a hook chmod -x .githooks/hooks.d/20-validate-skills.sh # Or rename with .disabled extension mv .githooks/hooks.d/20-validate-skills.sh{,.disabled} ``` ### Hook Template Use this template for new validation hooks: ```bash #!/bin/bash set -e echo "🔍 Running [VALIDATION NAME]..." # Get staged files matching pattern STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep 'pattern' || true) if [ -z "$STAGED_FILES" ]; then echo "✅ No files to validate" exit 0 fi # Validation logic for file in $STAGED_FILES; do if [ -f "$file" ]; then echo "Validating $file..." # Add validation command here # validation-command "$file" || exit 1 fi done echo "✅ Validation passed" exit 0 ``` ## Hook Parameters and Environment ### Common Parameters Different hooks receive different parameters: **pre-commit**: No parameters ```bash #!/bin/bash # Access staged files via git commands STAGED=$(git diff --cached --name-only) ``` **commit-msg**: Commit message file path ```bash #!/bin/bash COMMIT_MSG_FILE=$1 message=$(cat "$COMMIT_MSG_FILE") ``` **pre-push**: stdin with refs being pushed ```bash #!/bin/bash while read local_ref local_sha remote_ref remote_sha; do # Process each ref done ``` **post-checkout**: prev HEAD, new HEAD, branch flag ```bash #!/bin/bash PREV_HEAD=$1 NEW_HEAD=$2 IS_BRANCH=$3 # 1 for branch checkout, 0 for file checkout ``` ### Environment Variables Git sets environment variables hooks can access: - `GIT_DIR` - Path to .git directory - `GIT_WORK_TREE` - Path to working directory - `GIT_INDEX_FILE` - Path to index file - `GIT_AUTHOR_NAME`, `GIT_AUTHOR_EMAIL` - Commit author - `GIT_COMMITTER_NAME`, `GIT_COMMITTER_EMAIL` - Committer info **Test environment variables**: ```bash #!/bin/bash echo "Running $BASH_SOURCE" set | grep GIT echo "PWD is $PWD" ``` ## Best Practices **DO**: - Make hooks fast—developers run them frequently - Exit early when no relevant files are staged - Provide clear, actionable error messages - Use visual indicators (✅ ❌ 🔍) for quick scanning - Version-control hooks using `core.hooksPath` - Test hooks independently before integration - Document hook behavior in README - Use modular architecture for complex validation - Make hooks easy to temporarily disable **DON'T**: - Perform long-running operations in pre-commit - Block commits without clear explanation - Hardcode file paths—use relative paths - Assume dependencies are installed—check first - Create infinite loops or complex recursion - Mix multiple concerns in one hook script - Skip error handling and validation - Force hooks on team without consensus ## Security Considerations **Validate inputs**: Never trust user input in hooks ```bash # Bad: Command injection risk git diff --cached --name-only | xargs some-command # Good: Proper quoting and validation git diff --cached --name-only | while read file; do if [ -f "$file" ]; then some-command "$file" fi done ``` **Check permissions**: Ensure hooks are executable by intended users only ```bash chmod 755 .githooks/pre-commit # Owner write, others read+execute ``` **Avoid secrets**: Never hardcode credentials in hooks ```bash # Bad: Hardcoded token API_TOKEN="secret123" # Good: Read from environment API_TOKEN="${API_TOKEN:-$(cat ~/.api_token)}" ``` **Review third-party hooks**: Understand what scripts do before using them. ## Troubleshooting **Hook not running**: 1. Check execute permissions: `ls -l .githooks/pre-commit` 2. Verify `core.hooksPath` config: `git config core.hooksPath` 3. Ensure file has no `.sample` extension 4. Check shebang line is correct: `#!/bin/bash` **Hook runs but fails unexpectedly**: 1. Run hook manually to see errors: `.githooks/pre-commit` 2. Check exit codes: `echo $?` after running 3. Verify dependencies are installed 4. Test with minimal staged changes 5. Add debug output: `set -x` at start of script **Cannot commit**: 1. Read hook error message carefully 2. Fix validation issues or unstage problematic files 3. Temporarily disable hook if needed: `git commit --no-verify` 4. Note: `--no-verify` bypasses all hooks—use sparingly **Hooks not version-controlled**: 1. Ensure using `core.hooksPath`, not `.git/hooks/` 2. Verify `.githooks/` is committed: `git ls-files .githooks/` 3. Check team members ran setup: `git config core.hooksPath` ## Additional Resources ### Reference Documentation For detailed information on advanced topics: - **`references/hook-types.md`** - Complete list of all Git hooks with parameters and use cases - **`references/server-side-hooks.md`** - Server-side hooks for CI/CD and policy enforcement - **`references/advanced-patterns.md`** - Complex validation patterns and techniques
在 GitHub 查看
这个 SKILL.md 很大,SkillsMP 这里只预览前一段内容。 在 GitHub 查看