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

Husky commit-msg hook执行完毕后触发Enquirer脚本的方案问询

解决Husky Hooks并行执行与进程终止问题

看起来你遇到的核心问题是两个Husky钩子(commit-msg和post-commit)的执行时机没按预期串行,且post-commit里的Enquirer脚本会跟着commit-msg的进程退出而终止。这通常是因为commit-msg中的HTTP请求是异步执行的,导致钩子提前结束,而Git的进程组会在commit完成后终止所有关联子进程,进而影响到post-commit的脚本。下面给你几个可行的解决方案:

方案一:确保commit-msg脚本同步完成HTTP请求

最直接的方法是让commit-msg钩子等待HTTP请求完全完成后再退出,这样post-commit会在commit-msg彻底结束后才启动,自然不会出现并行执行的问题。

如果你的commit-msg脚本用Node.js编写,把异步HTTP请求改成阻塞式等待:

const fs = require('fs');
const axios = require('axios'); // 用axios更方便处理异步请求

async function sendCommitData() {
  // 读取提交信息
  const commitMsgPath = process.env.HUSKY_GIT_PARAMS;
  const commitMsg = fs.readFileSync(commitMsgPath, 'utf8');

  try {
    // 等待HTTP请求完成
    await axios.post('https://your-api-endpoint.com/submit', {
      message: commitMsg
    });
    console.log('HTTP请求已完成');
  } catch (err) {
    console.error('HTTP请求失败,终止提交:', err);
    process.exit(1); // 请求失败时终止commit流程
  }
}

// 执行并等待异步任务完成
sendCommitData().catch(() => process.exit(1));

如果是Bash脚本,用curl时加上--fail确保请求完成后再继续:

#!/bin/bash
COMMIT_MSG=$(cat "$1")
# 发送HTTP请求并等待响应
curl --fail --silent -X POST \
  -H "Content-Type: application/json" \
  -d "{\"message\": \"$COMMIT_MSG\"}" \
  https://your-api-endpoint.com/submit

# 如果请求失败,终止commit
if [ $? -ne 0 ]; then
  echo "HTTP请求失败"
  exit 1
fi

方案二:用标记文件实现钩子间的同步

如果因为某些原因无法让commit-msg同步执行(比如HTTP请求耗时极长,不想阻塞commit流程),可以用临时标记文件让post-commit等待commit-msg的异步任务完成。

步骤1:修改commit-msg脚本

在脚本开头创建标记文件,HTTP请求完成后删除它:

#!/bin/bash
# 创建临时标记文件
touch /tmp/commit_msg_pending

# 异步执行HTTP请求,完成后删除标记
curl --fail --silent -X POST \
  -H "Content-Type: application/json" \
  -d "{\"message\": \"$(cat "$1")\"}" \
  https://your-api-endpoint.com/submit && rm /tmp/commit_msg_pending &

步骤2:修改post-commit脚本

循环检查标记文件是否存在,直到文件被删除再执行Enquirer脚本:

#!/bin/bash
# 等待标记文件被删除
while [ -f /tmp/commit_msg_pending ]; do
  sleep 0.3
done

# 运行Enquirer脚本
node path/to/your-enquirer-script.js

方案三:让Enquirer脚本脱离进程组

如果post-commit脚本被终止是因为它属于Git的进程组,当commit-msg完成后Git终止整个进程组,你可以让Enquirer脚本脱离父进程,独立运行。

Bash版本

用nohup让脚本后台运行并脱离会话:

#!/bin/bash
nohup node path/to/your-enquirer-script.js > /dev/null 2>&1 &

Node.js版本

用child_process.spawn创建独立进程:

const { spawn } = require('child_process');

// 启动Enquirer脚本并脱离父进程
const enquirerProcess = spawn('node', ['path/to/your-enquirer-script.js'], {
  detached: true,
  stdio: 'ignore' // 忽略标准输入输出,避免依赖父进程终端
});

// 解除与父进程的关联
enquirerProcess.unref();

总结

优先尝试方案一,它从根源上解决了钩子并行的问题,也是最符合Husky钩子设计逻辑的方式。如果必须让HTTP请求异步执行,再考虑方案二或三。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 20:17:37