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.

Quellinformationen

Repository
the-perfect-developer/the-perfect-opencode
Letzte Quellaktivität
19. Februar 2026 um 08:38
Erkannte Sprache von SKILL.md
Englisch
Sterne
12
Forks
2

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
12 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
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
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen