You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何向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钩子可以从根源避免循环:

  1. 创建.husky/post-commit文件并添加内容:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# 执行版本发布
yarn release

# 推送包含标签的提交
git push --follow-tags origin "$(git rev-parse --abbrev-ref HEAD)"
  1. 移除原pre-push钩子的内容(或直接删除pre-push文件)

这样每次通过yarn commit完成提交后,会自动执行版本发布和推送,无需手动执行git push。

注意事项

  • 方案1中环境变量仅对当前git push命令生效,不会影响后续手动推送
  • 方案2中,即使手动执行git commit,也会触发post-commit钩子,符合规范提交的预期
  • 两种方案均无需依赖--no-verify或HUSKY=0,通过逻辑判断或钩子时机避免了循环

内容的提问来源于stack exchange,提问作者nicolas.aigner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 00:57:13