首页
/ 项目Git钩子使用指南

项目Git钩子使用指南

2026-04-02 09:17:30作者:史锋燃Gardner

可用钩子

  • commit-msg: 验证提交信息格式
  • pre-push: 推送前运行测试和代码检查

临时跳过钩子

# 跳过所有钩子
HUSKY=0 git commit -m "WIP: 临时提交"

# 仅跳过提交信息验证
git commit --no-verify -m "临时提交信息"

添加新钩子

npx husky add .husky/pre-commit "npm run lint"

### 钩子脚本模块化设计

将复杂的钩子逻辑拆分为独立脚本,提高可维护性:

.husky/ ├── commit-msg # 钩子入口 └── scripts/ ├── validate-commit-msg.js # 验证逻辑实现 └── common-utils.sh # 共享工具函数


示例:使用Node.js实现更复杂的提交信息验证:

```javascript
// .husky/scripts/validate-commit-msg.js
const fs = require('fs');
const path = require('path');

const commitMsgFile = process.argv[2];
const commitMsg = fs.readFileSync(commitMsgFile, 'utf-8').trim();

const types = ['feat', 'fix', 'docs', 'style', 'refactor', 'test', 'chore'];
const typeRegex = new RegExp(`^(${types.join('|')})(\\([^)]+\\))?: .{1,50}$`);

if (!typeRegex.test(commitMsg)) {
  console.error('❌ 提交信息格式不符合规范');
  console.error(`✅ 正确格式示例: feat(auth): 添加用户登录功能`);
  console.error(`📝 支持的类型: ${types.join(', ')}`);
  process.exit(1);
}

process.exit(0);

修改commit-msg钩子调用此脚本:

#!/usr/bin/env sh
. "$(dirname "$0")/h"

node "$(dirname "$0")/scripts/validate-commit-msg.js" "$1"

钩子性能优化:从"等待焦虑"到"无感执行"

常见性能问题分析

钩子执行缓慢是影响开发体验的主要问题,常见原因包括:

  1. 全量检查:对所有文件执行检查,而非仅检查变更文件
  2. 资源重复加载:每个钩子单独启动Node.js进程,重复加载依赖
  3. 不必要的检查:在不相关的文件变更时执行检查

优化方案1:只检查变更文件

使用Git命令获取变更文件列表,针对性执行检查:

#!/usr/bin/env sh
. "$(dirname "$0")/h"

# 获取暂存区的JavaScript/TypeScript文件
changed_files=$(git diff --cached --name-only --diff-filter=ACMR | grep -E '\.(js|ts|jsx|tsx)$')

if [ -n "$changed_files" ]; then
  echo "🔍 检查变更的JavaScript/TypeScript文件..."
  echo "$changed_files" | xargs eslint --fix
  git add "$changed_files"  # 添加修复后的文件
fi

优化方案2:使用钩子缓存机制

创建缓存目录存储检查结果,避免重复检查未变更文件:

#!/usr/bin/env sh
. "$(dirname "$0")/h"

CACHE_DIR=".husky/cache"
mkdir -p "$CACHE_DIR"

# 生成文件哈希作为缓存键
hash_file="$CACHE_DIR/files.hash"
current_hash=$(find src/ -type f -print0 | sort -z | xargs -0 sha1sum | sha1sum)

if [ -f "$hash_file" ] && [ "$(cat "$hash_file")" = "$current_hash" ]; then
  echo "✅ 代码检查结果缓存有效,跳过检查"
  exit 0
fi

# 执行实际检查
npm run lint
if [ $? -eq 0 ]; then
  echo "$current_hash" > "$hash_file"
  exit 0
else
  exit 1
fi

优化方案3:并行执行钩子任务

使用GNU Parallel或npm-run-all等工具并行执行耗时任务:

#!/usr/bin/env sh
. "$(dirname "$0")/h"

# 并行执行lint和test命令
npx npm-run-all --parallel lint test

故障排除:钩子不工作?从这六个方面排查

1. 检查Git钩子路径配置

git config core.hooksPath

预期结果:应输出.husky/_。如不是,重新设置:

git config core.hooksPath .husky/_

2. 验证钩子文件权限

ls -la .husky/

预期结果:所有钩子文件(如commit-msg、pre-push)应具有执行权限(x)。如没有,添加权限:

chmod +x .husky/*

3. 检查钩子脚本语法

使用shellcheck检查Bash脚本语法:

npx shellcheck .husky/commit-msg

4. 调试钩子执行过程

在钩子脚本开头添加调试信息:

#!/usr/bin/env sh
set -x  # 启用调试输出
. "$(dirname "$0")/h"
# 钩子逻辑...

5. 检查环境变量和路径

在钩子中输出环境信息进行诊断:

#!/usr/bin/env sh
. "$(dirname "$0")/h"

echo "当前目录: $(pwd)"
echo "PATH: $PATH"
echo "Node版本: $(node --version 2>&1)"
登录后查看全文
热门项目推荐
相关项目推荐