hooks
rs hooks 命令用于安装、更新和卸载仓库级 Git hooks。hook 脚本会在执行安装命令的项目目录中运行。
用法
直接运行 rs hooks 即可安装或更新 hooks。
rs setup 是 rs hooks 的别名。
安装 hooks
hook 脚本默认存放在 Git 仓库根目录的 .rstack/hooks 中。如果当前目录不在 Git 仓库内,命令会跳过安装。
在负责管理仓库 hooks 的项目中,将 rs hooks 添加到 package.json 的 prepare 脚本:
执行一次该脚本,完成 hooks 安装:
例如,创建一个 pre-commit hook,并在其中运行 rs staged:
安装命令可以安全地重复执行,并且不会加载 rstack.config.*。克隆仓库后或生成的 hook 文件缺失时,请再次运行 rs hooks。
rs hooks 会更新仓库的 core.hooksPath。如果检测到其他 hooks 路径或已有 Git hooks,命令会跳过安装。可运行 rs hooks --force,改用 Rstack 管理 hooks。
安装选项
--force
即使已经存在其他 Git hooks 配置,也可以使用 --force(或 -f)安装 Rstack hooks:
Rstack 会保留原有 hook 文件,并将 core.hooksPath 指向其生成的 hooks 目录。该配置生效期间,Git 不会执行原路径下的 hooks。
--force 无法替换由其他 Rstack 项目管理的 hooks。
rs hooks --force 只需运行一次。prepare 脚本中应使用不带 --force 的 rs hooks。
--hooks-dir
指定 hook 脚本的自定义存放目录,路径相对于 Git 仓库根目录。
使用自定义目录时,请将完整命令写入负责管理 hooks 的项目 package.json:
路径中不能包含
..,以免通过父目录路径在仓库之外创建或覆盖 hook 文件。
--help
--help(或 -h)用于显示命令的用法、子命令和安装选项。
卸载 hooks
请在安装 hooks 的项目目录中运行:
Rstack 会自动定位当前生效的 hooks,并移除 core.hooksPath 配置和生成的 _ 目录,但不会删除 .rstack/hooks/pre-commit 等项目 hook 文件。由其他项目或工具管理的 hooks 不会被删除。
如果不希望再次安装 hooks,请从 prepare 脚本中移除 rs hooks。
如果之前使用 --force 接管了 .git/hooks 中的 hooks,卸载后这些 hooks 会重新生效。
Hook 文件
默认目录结构如下:
与 _ 同级的文件是仓库 hook 脚本。_ 目录包含生成文件,并由 Git 忽略。rs hooks 会将 core.hooksPath 指向 .rstack/hooks/_。
支持的 hooks
Rstack CLI 支持以下客户端 Git hooks:
pre-commitpre-merge-commitprepare-commit-msgcommit-msgpost-commitapplypatch-msgpre-applypatchpost-applypatchpre-rebasepost-rewritepost-checkoutpost-mergepre-pushpre-auto-gc
在与 _ 同级的位置创建对应的同名文件即可。
Hook 运行时
Rstack CLI 使用 POSIX sh -e 运行 hook 脚本。它会转发 Git 提供的参数和标准输入,并返回 hook 的退出码。运行 hook 前,Rstack 会切换到安装 hooks 的项目,并将该项目的 node_modules/.bin 添加到 PATH 开头。
禁用与调试
将 RSTACK_HOOKS 设为 0,可以跳过安装或 hook 执行:
将 RSTACK_HOOKS 设为 2,可以跟踪 Rstack CLI 的 hook 运行时,包括调用 hook 脚本和处理退出码等步骤;如需跟踪 hook 脚本内部的命令,请在脚本中添加 set -x:
配置 hook 运行环境
运行 hook 脚本前,Rstack CLI 会加载以下可选的 POSIX shell 文件:
可以在其中初始化 Node.js 版本管理器、更新 PATH,或为当前用户设置 RSTACK_HOOKS=0。
所有权保护
每个生成的 hooks 目录都会记录所属项目。只有该项目应在 prepare 脚本中调用 rs hooks。其他项目即使使用 --force 调用安装命令,也会被跳过;卸载命令同样会拒绝删除其他项目的 hooks。
如需转移所有权:
- 从原项目的
prepare脚本中移除rs hooks。 - 在原项目中运行
rs hooks uninstall。 - 将
rs hooks添加到新项目的prepare脚本,并运行一次。
Monorepo
在 monorepo 中,提供 Rstack CLI 的项目可能位于 frontend/ 等子目录。在该目录中运行 rs hooks,hooks 仍会安装到 Git 仓库根目录:
Rstack 会将 frontend 记录为 hooks 所属项目。hook 脚本仍保存在仓库根目录,但会从 frontend 目录运行,因此可以直接使用其中的配置和依赖,无需显式执行 cd:
Worktree 行为
Rstack 会保留当前生效的 core.hooksPath 所在的 Git 配置作用域。如果 linked worktree 使用的是 worktree 作用域配置,rs hooks --force 会在同一作用域中替换它,而不会写入一个被 Git 忽略的 local 配置。
rs hooks uninstall 也会从同一作用域中移除配置。卸载 worktree 作用域的安装只影响当前 worktree,不会改变其他 worktree 中的 hooks。local 作用域的 core.hooksPath 会在多个 worktree 之间共享,因此更改或移除该配置会影响所有未覆盖它的 worktree。
故障排查
Hook 未运行
- 确认 hook 脚本使用支持的名称,并与
_目录同级。 - 运行
git config --show-scope --get core.hooksPath,检查当前生效的配置作用域和路径。 - 重新运行
rs hooks,恢复生成文件及其可执行权限。 - 检查环境变量或初始化文件中是否设置了
RSTACK_HOOKS=0。 - 如果命令检测到其他 hooks 配置,请运行
rs hooks --force。 - 如果命令提示其他项目是 hooks owner,请按照所有权保护中的步骤转移 owner。
hook 脚本不需要可执行权限,因为 Rstack CLI 会使用 sh 运行它。
找不到命令
退出码为 127 时,Rstack CLI 会打印实际生效的 PATH。如果 GUI Git 客户端找不到 Node.js 或包管理器,请在 hooks-init.sh 中初始化相关环境。
Windows 与 Yarn
在 Windows 上,hooks 会通过 Git for Windows 自带的 POSIX shell 运行。请在 hook 中使用 LF 换行符和 / 路径分隔符。
Yarn PnP 不提供 node_modules/.bin。请通过 Yarn 脚本运行工具,例如 yarn run test;必要时可通过 hooks-init.sh 配置 Node.js 和 Yarn。