正在加载,请稍候…

Git Hooks: Automate Code Quality with Pre-commit and Pre-push

Use Git hooks to automate linting, testing, and code quality checks. Learn pre-commit, commit-msg, and pre-push hooks with Husky and lint-staged.

Git Hooks: Automate Code Quality with Pre-commit and Pre-push

Git hooks run scripts automatically at key points in your Git workflow.

Hook Types

pre-commit     Before each commit (run lint/tests)
prepare-commit-msg  Modify commit message template
commit-msg     Validate commit message format
pre-push       Before pushing (run integration tests)
post-merge     After merge (install dependencies)
pre-rebase     Before rebasing

Manual Hook Setup

# Create pre-commit hook
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
npm run lint
if [ $? -ne 0 ]; then
  echo "Lint failed. Commit aborted."
  exit 1
fi
EOF
chmod +x .git/hooks/pre-commit

Husky - Modern Hook Management

# Install Husky
npm install -D husky
npx husky init

# The init command creates .husky/ directory
# .husky/pre-commit
#!/bin/sh
npx lint-staged
# .husky/commit-msg
#!/bin/sh
npx --no -- commitlint --edit $1
# .husky/pre-push
#!/bin/sh
npm test

lint-staged - Run Linters on Staged Files

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

commitlint - Conventional Commits

npm install -D @commitlint/cli @commitlint/config-conventional
// commitlint.config.js
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [2, 'always', [
      'feat', 'fix', 'docs', 'style',
      'refactor', 'test', 'chore', 'revert'
    ]],
    'subject-max-length': [2, 'always', 72],
  }
};

Post-merge Hook

# .husky/post-merge
#!/bin/sh
# Reinstall if package.json changed
changed_files="$(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD)"
if echo "$changed_files" | grep -q "package.json"; then
  echo "package.json changed, reinstalling dependencies..."
  npm install
fi

Bypassing Hooks

# Skip hooks when needed (use sparingly)
git commit --no-verify -m "WIP: skip hooks"
git push --no-verify

Team-wide Configuration

// package.json
{
  "scripts": {
    "prepare": "husky"
  }
}

The prepare script runs automatically after npm install, ensuring hooks are set up for all team members.

Git hooks enforce code quality before code ever reaches the repository.