资讯动态

Husky 故障排查完全指南:从 Command not found 到 Windows 平台问题的一次性解决方案

发布时间:2026/9/19 18:20:56 来源:尧图企业网站定制
Husky 故障排查完全指南从 Command not found 到 Windows 平台问题的一次性解决方案【免费下载链接】huskyGit hooks made easy woof!项目地址: https://gitcode.com/gh_mirrors/hu/husky本指南以官方文档 docs/zh/troubleshoot.md 为主线系统梳理 Husky 使用中最常见的四类故障钩子找不到命令、钩子不运行、卸载后.git/hooks/失效以及 Windows 上 Yarn 的 stdin 问题。每类问题都给出可立即执行的修复步骤并辅以本仓库源码husky、index.js、测试用例佐证其底层机制读完即可独立定位与解决实际工程问题。问题一找不到命令Command not found症状执行git commit、git push等命令时钩子脚本报出command not found。排查方向Husky 的钩子由 shell 脚本驱动而 shell 解析命令依赖PATH环境变量。当PATH中没有包含node_modules/.bin时钩子里调用的 npm 脚本、Node 命令就会找不到。官方中文文档给出的首要指引是参阅 如何使用docs/zh/how-to.md因为该类问题通常不是 Husky 安装本身出错而是运行环境的PATH配置不完整。底层机制Husky 如何保证 PATH 可用看仓库根目录的 husky这是 Husky 安装时拷贝到.husky/_/h的钩子执行器它明确做了三件事export PATHnode_modules/.bin:$PATH sh -e $s $ c$? [ $c 127 ] echo husky - command not found in PATH$PATH在执行用户钩子脚本$s之前先把node_modules/.bin前置到PATH这样npm test、eslint等本地命令总能被找到如果命令退出码为127shell 约定命令未找到会额外打印出当时的PATH内容方便你定位缺失的目录相关行为由测试 test/7_node_modules_path.sh 验证钩子内执行echo $PATH | grep node_modules/.bin且提交成功证明 PATH 注入确实生效。常见根因与修复使用了 Node 版本管理器nvm、fnm、asdf、volta 等版本管理器只在交互式终端初始化GUI 客户端VS Code、SourceTree 等启动的钩子拿不到初始化后的PATH。解决方案是把版本管理器的初始化代码写入~/.config/husky/init.sh例如# ~/.config/husky/init.sh export NVM_DIR$HOME/.nvm [ -s $NVM_DIR/nvm.sh ] \. $NVM_DIR/nvm.sh # 加载 nvmHusky 在每次运行钩子前都会读取并执行该初始化文件见 husky 中的[ -f $i ] . $i其中$i即${XDG_CONFIG_HOME:-$HOME/.config}/husky/init.sh。更多细节参见 docs/zh/how-to.md 的「Node 版本管理器和 GUI」小节。node_modules/.bin缺失确认依赖确实已安装如果只安装了dependencies而未安装devDependenciesHusky本身是 devDependency根本不会被安装prepare脚本会失败。此时可把prepare改为husky || true或使用 docs/zh/how-to.md 中介绍的.husky/install.mjs按环境跳过安装。问题二钩子未运行症状.husky/pre-commit等文件已创建但提交时钩子没有任何反应。按官方文档的顺序逐项检查验证钩子文件名是否正确。Git 对钩子名有严格约定precommit、pre-commit.sh都是无效名称。Git 官方完整钩子清单见git-scm.com/docs/githooks常用合法名称包括pre-commit、pre-push、commit-msg、prepare-commit-msg、post-checkout、post-merge等。本仓库的 index.js 也维护了一份安装时自动生成的钩子白名单let l [pre-commit, pre-merge-commit, prepare-commit-msg, commit-msg, post-commit, applypatch-msg, pre-applypatch, post-applypatch, pre-rebase, post-rewrite, post-checkout, post-merge, pre-push, pre-auto-gc]检查core.hooksPath是否正确。运行git config core.hooksPath输出应指向.husky/_或你的自定义目录。安装时 index.js 会执行c.spawnSync(git, [config, core.hooksPath, ${d}/_])即把 hooks 目录指向.husky/_。测试 test/6_command_not_found.sh 和 test/9_husky_0.sh 都通过expect_hooksPath_to_be .husky/_断言了这一点该断言定义在 test/functions.sh。确认 Git 版本高于2.9。core.hooksPath配置项从 Git 2.9 起才可用Husky 依赖它来接管钩子目录。低于该版本无法生效。其它隐藏原因.husky不在 Git 仓库根目录出于安全考虑Husky 拒绝在父目录安装index.js中有if (d.includes(..)) return .. not allowed。若项目结构是.git在根目录、package.json在frontend/子目录需要在prepare脚本中cd .. husky frontend/.husky处理具体见 docs/zh/how-to.md 的「项目不在 Git 根目录」小节。.husky目录是否存在检查根目录下是否有.husky/文件夹安装时由index.js创建内含_子目录及.gitignore、h等文件。钩子被HUSKY0禁用见下文「如何跳过钩子」说明注意环境变量可能会从 CI 配置或init.sh中泄漏进来。验证钩子是否真正生效把exit 1临时加入钩子脚本若提交被中止说明钩子链路已打通详见 docs/zh/how-to.md 的「测试钩子」小节# .husky/pre-commit exit 1git commit -m testing pre-commit code # 提交不会被创建问题三卸载后.git/hooks/无法正常使用症状移除 husky 之后原本在.git/hooks/下手动放置的钩子不再执行。原因Husky 安装时通过git config core.hooksPath .husky/_改写了 Git 配置把钩子目录从默认的.git/hooks/重定向到.husky/_。卸载 Husky 只是删除了node_modules里的包和.husky目录但不会自动撤销这条 Git 配置Git 仍会去已不存在的.husky/_找钩子导致.git/hooks/下的钩子失效。修复手动删除该配置项让 Git 回到默认的.git/hooks/git config --unset core.hooksPath执行后可用git config core.hooksPath确认输出为空。这个原理也可以反过来说明安装 Husky 本质就是设置core.hooksPath这也是为什么「钩子未运行」的排查中第一步就要检查该项。问题四在 Windows 上使用 Yarnstdin is not a tty症状Windows 用户使用 Git Bash 运行 Yarn 相关的 Git 钩子时报错stdin is not a tty钩子失败。原因Git Bash 环境下winpty与交互式 stdin 的兼容性问题Yarn 需要读取 TTY 输入例如询问交互问题时拿不到有效的终端设备。官方解决方案创建一个公共的初始化脚本在钩子运行前把 stdin 重定向回/dev/tty创建.husky/common.shcommand_exists () { command -v $1 /dev/null 21 } # Windows 10、Git Bash 和 Yarn 的解决方案 if command_exists winpty test -t 1; then exec /dev/tty fi在运行 Yarn 命令的钩子中引入它注意使用dirname保证从任意工作目录都能找到脚本比写死相对路径更稳健# .husky/pre-commit . $(dirname -- $0)/common.sh yarn ...要点说明command -v $1 /dev/null 21用于检测winpty是否存在于 PATH同时静默丢弃输出test -t 1判断标准输出是否为终端两者同时成立才执行重定向避免影响无 TTY 的 CI 场景exec /dev/tty将当前 shell 的标准输入替换为 TTY从而满足 Yarn 对交互式输入的要求。附与故障排查强相关的机制速查HUSKY 环境变量与钩子开关Husky 支持通过HUSKY环境变量全局控制钩子这在排查钩子莫名不运行时很关键HUSKY0 git ...临时禁用单个命令的钩子命令执行后自动恢复见 husky 中的[ ${HUSKY-} 0 ] exit 0export HUSKY0在当前 shell 会话中长期禁用unset HUSKY恢复在~/.config/husky/init.sh中写export HUSKY0在 GUI 或全局永久禁用安装阶段设置HUSKY0则跳过安装见 index.js 的if (process.env.HUSKY 0) return HUSKY0 skip install。测试 test/9_husky_0.sh 完整覆盖了这一行为HUSKY0时core.hooksPath为空未安装正常安装后钩子生效再通过XDG_CONFIG_HOME注入export HUSKY0的 init.sh 后钩子被跳过、提交成功。常见问题快速对照表症状直接检查项修复command not foundPATH是否包含node_modules/.bin是否用了版本管理器修正 PATH初始化~/.config/husky/init.sh钩子不运行文件名是否合法git config core.hooksPath是否为.husky/_Git 版本是否 ≥ 2.9改名/重装重置core.hooksPath升级 Git卸载后.git/hooks/失效git config core.hooksPath是否残留git config --unset core.hooksPathWindows Yarnstdin is not a tty是否缺少.husky/common.sh及钩子内 source创建common.sh并exec /dev/tty钩子被静默跳过是否存在HUSKY0shell、CI、init.sh移除/反设置该变量一个值得注意的兼容性提示从源码结构看husky 与 test/12_deprecated.sh旧版钩子文件中#!/usr/bin/env sh. $(dirname -- $0)/_/husky.sh的写法目前仍能运行测试以退出码 0 通过但 index.js 会在生成的_/husky.sh中打印弃用警告并声明该写法在 v10.0.0 将不再兼容。若你从 v4 或更早版本迁移而来且遇到异常请参考仓库中的 docs/zh/migrate-from-v4.md 完成迁移。总结Husky 的故障大多集中在三个层面Git 配置层面core.hooksPath、环境层面PATH、TTY、版本管理器和目录结构层面.husky位置、文件名合法性。本文的排查路径与官方文档 docs/zh/troubleshoot.md 完全一致并补充了 husky、index.js 等核心源码与 test/ 测试用例作为佐证。遇到问题时先对照快速对照表定位层面再按对应小节逐步修复即可如需更完整的安装、配置与自定义说明可继续阅读 docs/zh/get-started.md 与 docs/zh/how-to.md。【免费下载链接】huskyGit hooks made easy woof!项目地址: https://gitcode.com/gh_mirrors/hu/husky创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价