如何向husky/git pre-push钩子传参?解决推送循环问题
问题描述
我有一个Node.js项目,为规范提交与版本管理,已安装husky、commitizen、commitlint和standard-version工具,目前通过git-cz可正常规范提交。但每次提交后需手动执行yarn standard-release和git push --follow-tags origin 对应分支,效率较低。
我希望执行git push时,自动触发standard-release并执行带--follow-tags origin 分支名的推送,但将该逻辑写入pre-push钩子后出现循环执行问题,尝试过--no-verify、HUSKY=0均无效。目前无法使用CI/CD,求解决该循环问题的方案。
相关配置文件
package.json
{ "name": "app", "version": "1.0.0", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "node index.js", "prepare": "husky install", "release": "standard-version", "commit": "git-cz" }, "keywords": [], "license": "ISC", "dependencies": { "express": "^4.18.1" }, "devDependencies": { "@commitlint/cli": "^17.0.3", "@commitlint/config-conventional": "^17.0.3", "commitizen": "^4.2.5", "cz-conventional-changelog": "3.3.0", "husky": "^8.0.1", "standard-version": "^9.5.0" }, "commitlint": { "extends": [ "@commitlint/config-conventional" ], "rules": { "subject-case": [ 2, "never", [ "start-case", "pascal-case" ] ] } }, "config": { "commitizen": { "path": "./node_modules/cz-conventional-changelog" } } }
.husky/commit-msg
#!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" yarn commitlint --edit "$@"
.husky/pre-push(当前有问题版本)
#!/usr/bin/env sh #. "$(dirname -- "$0")/_/husky.sh" yarn release git push --follow-tags origin "$(git rev-parse --abbrev-ref HEAD)"
终端操作流程
$ git add . $ yarn commit 选择feat类型提交,返回:feat: add new router $ git push 进入pre-push钩子,执行脚本但出现循环
解决方案
循环的核心原因是:pre-push钩子中执行的git push --follow-tags会再次触发pre-push钩子,形成无限循环。以下是两种可行的解决思路:
方案1:用环境变量标记跳过钩子
修改pre-push脚本,在执行内部git push时设置专属环境变量,让钩子检测到该变量就直接跳过执行:
更新.husky/pre-push内容为:
#!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" # 检测到自动推送标记时,直接跳过钩子逻辑 if [ -n "$SKIP_PRE_PUSH" ]; then exit 0 fi # 执行版本发布 yarn release # 设置环境变量,让下一次git push不触发pre-push钩子 SKIP_PRE_PUSH=1 git push --follow-tags origin "$(git rev-parse --abbrev-ref HEAD)"
方案2:改用post-commit钩子(更合理的时机)
版本发布逻辑更适合放在提交完成后执行,而非推送前。改用post-commit钩子可以从根源避免循环:
- 创建
.husky/post-commit文件并添加内容:
#!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" # 执行版本发布 yarn release # 推送包含标签的提交 git push --follow-tags origin "$(git rev-parse --abbrev-ref HEAD)"
- 移除原pre-push钩子的内容(或直接删除pre-push文件)
这样每次通过yarn commit完成提交后,会自动执行版本发布和推送,无需手动执行git push。
注意事项
- 方案1中环境变量仅对当前git push命令生效,不会影响后续手动推送
- 方案2中,即使手动执行
git commit,也会触发post-commit钩子,符合规范提交的预期 - 两种方案均无需依赖
--no-verify或HUSKY=0,通过逻辑判断或钩子时机避免了循环
内容的提问来源于stack exchange,提问作者nicolas.aigner
相关产品推荐
相关产品推荐

