Dev Logs
/Git & GitHub/ Add hooks to version control
Chapters
  • 01Git and GitHub Introduction
  • 02Basic Git Commands
  • 03Remote Repositories and GitHub
  • 04Branching Basics
  • 05Git Merge vs Rebase
  • 06Git Stash
  • 07Git Diff and Log
  • 08Resolving Merge Conflicts
  • 09Pull Requests and Code Review
  • 10Question about implementation
  • 11Positive feedback
  • 12Security concern
  • 13Forking and Upstream Remotes
  • 14Advanced Git Rebase
  • 15Git Cherry-pick
  • 16Git Reset Deep Dive
  • 17Git Reflog Recovery
  • 18Git Bisect Bug Hunting
  • 19Git Tags
  • 20Git Hooks
  • 21Add hooks to version control
    • Hook Best Practices
    • . Keep Hooks Fast
    • Pre-push Optimization
    • . Make Hooks Configurable
    • . Document Hook Behavior
    • Quick Reference
  • 22Conventional Commits
  • 23Update README
  • 24Conventional Commits Demo
  • 25GitHub CLI (gh)
  • 26GitHub Actions Basics
  • 27Maintaining Clean Git History in Teams
  • 28Branching Strategies: Git Flow vs Trunk-Based Development
  • 29Force Push Safety: Using --force-with-lease
All chapters

Add hooks to version control

git add .githooks/ git commit -m "feat: add shared Git hooks for code quality"


### Hook Configuration

```bash
# Create hook configuration file
cat > .githooks/config.json << 'EOF'
{
  "hooks": {
    "pre-commit": {
      "enabled": true,
      "checks": {
        "syntax": true,
        "linting": true,
        "formatting": true,
        "tests": true,
        "security": true
      },
      "maxFileSize": "1MB",
      "allowedBranches": ["feature/*", "bugfix/*", "hotfix/*"]
    },
    "commit-msg": {
      "enabled": true,
      "format": "conventional",
      "maxLength": 72,
      "requireIssueReference": false
    },
    "pre-push": {
      "enabled": true,
      "protectedBranches": ["main", "master", "develop"],
      "allowForceWithLease": true,
      "runTests": true,
      "runBuild": true
    }
  },
  "notifications": {
    "slack": {
      "enabled": false,
      "webhook": ""
    },
    "email": {
      "enabled": false,
      "recipients": []
    }
  }
}
EOF

Hook Best Practices

1. Keep Hooks Fast

bash
# Optimize hook performance
cat > .githooks/performance-tips.md << 'EOF'
# Hook Performance Tips

## Pre-commit Optimization
- Only check staged files, not entire repository
- Use parallel processing for multiple files
- Cache results when possible
- Skip checks for certain file types

## Example: Parallel linting
```bash
# Instead of:
for file in $js_files; do
    eslint "$file"
done

# Use:
echo "$js_files" | xargs -P 4 eslint

Pre-push Optimization

  • Only run full test suite, not individual tests
  • Use test result caching
  • Skip redundant checks if CI will run them EOF

### 2. Provide Clear Error Messages

```bash
# Example of good error messaging
cat > .githooks/error-example.sh << 'EOF'
#!/bin/bash

# BAD: Unclear error
if ! eslint .; then
    echo "ESLint failed"
    exit 1
fi

# GOOD: Clear, actionable error
if ! eslint .; then
    echo "❌ ESLint found code quality issues"
    echo ""
    echo "To fix automatically:"
    echo "  npm run lint:fix"
    echo ""
    echo "To see detailed errors:"
    echo "  npm run lint"
    echo ""
    echo "To bypass this check (not recommended):"
    echo "  git commit --no-verify"
    exit 1
fi
EOF

3. Make Hooks Configurable

bash
# Create configurable hook
cat > .githooks/configurable-pre-commit << 'EOF'
#!/bin/bash

# Load configuration
CONFIG_FILE=".githooks/config.json"
if [ -f "$CONFIG_FILE" ]; then
    # Parse JSON config (requires jq)
    LINT_ENABLED=$(jq -r '.hooks."pre-commit".checks.linting' "$CONFIG_FILE")
    TEST_ENABLED=$(jq -r '.hooks."pre-commit".checks.tests' "$CONFIG_FILE")
else
    # Default values
    LINT_ENABLED="true"
    TEST_ENABLED="true"
fi

# Conditional checks
if [ "$LINT_ENABLED" = "true" ]; then
    echo "Running linter..."
    npm run lint
fi

if [ "$TEST_ENABLED" = "true" ]; then
    echo "Running tests..."
    npm test
fi
EOF

4. Document Hook Behavior

bash
# Create comprehensive documentation
cat > .githooks/HOOKS_GUIDE.md << 'EOF'
# Git Hooks Guide

## Overview

This project uses Git hooks to maintain code quality and consistency.

## Hook Descriptions

### pre-commit
**When**: Before each commit is created
**Purpose**: Ensure code quality and prevent common issues
**Checks**:
- Syntax validation for JavaScript/TypeScript files
- ESLint code quality checks
- Prettier code formatting
- Unit tests execution
- File size limits (max 1MB)
- Sensitive information detection
- JSON syntax validation

**Bypass**: `git commit --no-verify`

### commit-msg
**When**: After commit message is entered
**Purpose**: Enforce consistent commit message format
**Format**: Conventional Commits (type(scope): description)
**Examples**:
- `feat(auth): add OAuth2 integration`
- `fix: resolve memory leak in calculator`
- `docs: update API documentation`

**Bypass**: `git commit --no-verify`

### pre-push
**When**: Before pushing to remote repository
**Purpose**: Final quality gate before sharing code
**Checks**:
- Prevent direct push to protected branches
- Validate all commit messages in push
- Run full test suite
- Build verification
- Security audit
- Large file detection

**Bypass**: `git push --no-verify`

## Troubleshooting

### Common Issues

1. **Hook not executing**
   - Check if hook file is executable: `chmod +x .git/hooks/hook-name`
   - Verify hook file exists in `.git/hooks/`

2. **Permission denied**
   - Make hook executable: `chmod +x .git/hooks/hook-name`

3. **Hook fails unexpectedly**
   - Check hook logs
   - Run hook manually: `.git/hooks/hook-name`
   - Verify dependencies are installed

### Getting Help

- Check hook output for specific error messages
- Review this documentation
- Ask team members for assistance
- Use `--no-verify` flag only in emergencies
EOF

Quick Reference

bash
# Hook locations
.git/hooks/                      # Local hooks (not version controlled)
.githooks/                       # Shared hooks (version controlled)

# Common hooks
pre-commit                       # Before commit creation
commit-msg                       # Validate commit message
pre-push                         # Before push to remote
post-commit                      # After commit creation
post-checkout                    # After checkout
post-merge                       # After merge

# Hook management
chmod +x .git/hooks/hook-name    # Make hook executable
git config core.hooksPath .githooks  # Use custom hooks directory

# Bypass hooks (use sparingly)
git commit --no-verify           # Skip pre-commit and commit-msg
git push --no-verify             # Skip pre-push

# Hook installation
./.githooks/install.sh           # Install shared hooks
cp .githooks/* .git/hooks/       # Manual installation

# Testing hooks
.git/hooks/pre-commit            # Run hook manually
echo "test" | .git/hooks/commit-msg /dev/stdin  # Test commit-msg

Previous: Git Tags
Next: Conventional Commits

PreviousGit HooksNextConventional Commits

Open source, free forever. Built by iammhador.

Contribute on GitHub