多分支推送问题:Husky的prepush Git Hooks无法检测失败脚本
解决Husky prepush钩子多分支推送时未检测其他分支问题的方案
这个问题我之前也碰到过,核心原因很明确:Husky的prepush钩子默认只针对你当前工作目录所在的分支执行检查,当你推送多个分支时,钩子不会自动切换到其他要推送的分支去跑lint和test,自然就检测不到其他分支的问题了。
下面给你两个可行的解决方案,按需选择:
方案一:自定义Shell脚本遍历所有要推送的分支检查
我们可以写一个Shell脚本,代替原来的npm-run-all命令,让它自动获取所有要推送的分支,逐个切换并执行检查,一旦有分支失败就终止推送。
步骤1:创建检查脚本
在项目根目录新建prepush-check-all-branches.sh文件,内容如下:
#!/bin/bash # 保存当前所在分支,检查完后切回来 current_branch=$(git rev-parse --abbrev-ref HEAD) # 通过git push dry-run获取要推送的分支列表(解析输出提取分支名) push_branches=$(git push --dry-run 2>&1 | grep -E '->' | awk '{print $1}' | sed 's/^refs\/heads\///') # 如果没有要推送的分支,直接放行 if [ -z "$push_branches" ]; then echo "No branches to push, proceeding." exit 0 fi # 遍历每个要推送的分支进行检查 for branch in $push_branches; do echo "🔍 Starting checks for branch: $branch" # 切换到目标分支,如果有未提交修改会失败,提前提示用户 if ! git checkout "$branch"; then echo "❌ Failed to switch to branch $branch - make sure your working directory is clean!" git checkout "$current_branch" exit 1 fi # 执行lint检查 echo "Running lint on $branch..." npm run lint if [ $? -ne 0 ]; then echo "❌ Lint failed on branch $branch" git checkout "$current_branch" exit 1 fi # 执行测试 echo "Running tests on $branch..." npm run test if [ $? -ne 0 ]; then echo "❌ Tests failed on branch $branch" git checkout "$current_branch" exit 1 fi echo "✅ Branch $branch passed all checks" done # 切回原来的分支 git checkout "$current_branch" echo "🎉 All branches passed checks - pushing now!" exit 0
步骤2:给脚本添加执行权限
在终端运行:
chmod +x prepush-check-all-branches.sh
步骤3:修改package.json的prepush钩子
把原来的prepush配置替换为:
"prepush": "bash prepush-check-all-branches.sh"
这样以后推送多个分支时,脚本会自动逐个检查所有要推送的分支,只要有一个分支lint或test失败,推送就会被终止。
方案二:配合Git原子推送(可选补充)
如果你希望推送要么全部成功要么全部失败(避免部分分支推送成功、部分失败的情况),可以在推送时加上--atomic参数:
git push --atomic origin feature/branch-1 feature/branch-2
这个命令会确保所有分支都推送成功才会生效,否则全部回滚。不过它不能替代前面的分支检查,只是作为推送阶段的保障。
注意事项
- 执行多分支推送前,确保工作目录是干净的(没有未提交的修改),否则脚本切换分支时会失败。
- 如果你的项目用的是Windows系统,可能需要调整Shell脚本(比如用Git Bash执行,或者改成Node.js脚本)。
内容的提问来源于stack exchange,提问作者G. Frx




