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

在Husky的commit-msg钩子中执行git add为何无法更新提交文件?

问题分析与解决方案

核心原因

你遇到的问题本质是Git钩子的触发时机限制:commit-msg钩子是在Git已经完成暂存区快照、即将生成提交对象时触发的。此时执行git add只能把更新后的version.json放到下一次提交的暂存区,无法修改当前正在创建的提交——这就是为什么提交里是旧版本,提交后新版本才处于暂存状态。

可行解决方案

方案1:改用prepare-commit-msg钩子(推荐)

prepare-commit-msg钩子的触发时机更早:在Git生成提交消息之后、提交最终确认之前(用-m直接提交时,消息已写入COMMIT_EDITMSG;用编辑器输入时,会在编辑器启动前触发模板生成)。此时修改文件并执行git add,能将变更包含到当前提交中。

操作步骤:

  1. 创建.husky/prepare-commit-msg钩子文件:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# $1为提交消息文件路径,与commit-msg钩子参数一致
npm run auto-version $1 && git add version.json
  1. 给钩子添加执行权限:
chmod +x .husky/prepare-commit-msg
  1. 兼容编辑器输入场景(可选):
    如果用户习惯用编辑器输入提交消息,prepare-commit-msg会在编辑器启动前触发,此时COMMIT_EDITMSG是Git生成的模板而非用户最终消息。可以修改auto-version.js开头,只在直接提交(-m参数)或amend提交时执行版本更新:
// 在auto-version.js顶部添加
const commitType = process.argv[3];
// 仅处理直接提交或amend场景
if (!['message', 'commit'].includes(commitType)) {
  process.exit();
}

方案2:在commit-msg钩子中用git commit --amend补提交

如果不想更换钩子,可以在版本更新后,用amend命令将新版本文件追加到当前提交中,同时需要避免钩子无限循环(amend会再次触发commit-msg)。

修改.husky/commit-msg:

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# 标记是否为amend触发,防止循环
if [ -z "$AMENDING" ]; then
  export AMENDING=1
  npm run auto-version $1 && git add version.json && git commit --amend --no-edit
fi

注意:此方式会修改提交历史,建议将git add --all改为git add version.json,避免意外提交其他未暂存文件。

额外优化建议

  • 把auto-version.js中的版本更新逻辑和提交消息验证逻辑合并,无需单独保留commit-msg钩子做重复验证。
  • 保留pre-commit钩子的lint、格式化流程,与版本更新逻辑分离,职责更清晰。

内容的提问来源于stack exchange,提问作者Paradoxdotexe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 12:05:23