钩子
通过钩子,你可以在 worktree 生命周期中自动执行命令。
| 钩子 | 执行时机 | 工作目录 |
|---|---|---|
pre_start |
worktree 创建之后 | 源仓库 |
post_start |
worktree 创建之后 | 新的 worktree |
pre_clean |
worktree 删除之前 | 当前 worktree |
post_clean |
worktree 删除之后 | 主仓库 |
[hooks]pre_start = ["echo '正在准备 worktree...'"]post_start = [ "pnpm install", "pnpm db:migrate"]pre_clean = ["git stash"]post_clean = ["echo '清理完成'"]所有钩子命令中都可以使用以下环境变量:
| 变量 | 说明 |
|---|---|
VIBE_WORKTREE_PATH |
所创建 worktree 的绝对路径 |
VIBE_ORIGIN_PATH |
源仓库的绝对路径 |
[hooks]post_start = [ "echo 'Worktree 创建于: $VIBE_WORKTREE_PATH'", "echo '源仓库: $VIBE_ORIGIN_PATH'"]钩子的输出行为
Section titled “钩子的输出行为”vibe 会在钩子执行期间显示实时的进度树:
✶ Setting up worktree feature/new-ui…┗ ☒ Pre-start hooks ┗ ☒ npm install ☒ cargo build --release ⠋ Copying files ┗ ⠋ .env.local ⠋ node_modules/| 标记 | 含义 |
|---|---|
⠋ |
排队中或正在执行(开始后指示器会转动) |
☒ |
已成功完成 |
✗ |
失败(红色),随后以 (failed: …) 给出原因 |
⊘ |
已放弃(暗色)——运行结束时仍未完成 |
阶段行(外层的 ┗)本身没有结果,它汇总其下所有任务的状态:只要还有任务未完成就显示 ⊘;否则若有任务失败则显示 ✗ 并附上 (failed: N task(s) failed);两者都没有时显示 ☒。
| 情况 | 标准输出 | 标准错误 |
|---|---|---|
| 进度显示启用 | 被抑制 | 始终显示 |
| 进度显示禁用 | 输出到标准错误 | 始终显示 |
| 钩子执行失败 | N/A | 始终显示 |
钩子的执行顺序
Section titled “钩子的执行顺序”对于 vibe start:
- 创建 worktree
- 当配置了
[submodules] configs = [...]时,初始化列出的子模块 - 各个列出的子模块中已信任的
pre_start、copy 规则和post_start会以该子模块根目录为基准执行 - 父仓库的
pre_start钩子在源仓库中执行 - 复制父仓库的文件/目录
- 父仓库的
post_start钩子在新的 worktree 中执行
对于 vibe clean:
pre_clean钩子在当前 worktree 中执行- 删除 worktree
post_clean钩子在主仓库中执行
钩子失败时的行为
Section titled “钩子失败时的行为”钩子以非零状态退出时属于警告而非错误:vibe 会打印
Warning: Hook "..." failed: ...,退出状态仍为 0。真正受影响的是是否执行目录切换,
而这取决于钩子处于生命周期中的哪个位置。
| 钩子 | 失败时的行为 |
|---|---|
pre_start |
充当闸门:跳过复制和 post_start,并让你留在原来的目录 |
post_start |
仅警告:worktree 已完成配置,因此 vibe 仍会切换到该 worktree |
pre_clean |
充当闸门:不会删除 worktree,你仍留在该 worktree 中 |
post_clean |
仅警告:worktree 已被删除,因此 vibe 仍会切换回主仓库 |
因此 pre_start 和 pre_clean 可以用作前置条件检查。例如,用 pre_start 检查密钥
保险库是否可达,就能避免进入一个无法完成配置的 worktree。
被闸门拦下的 vibe start 仍会在磁盘上保留 worktree 目录,被拦下的只是目录切换。
针对同一分支再次运行 vibe start 时会找到该 worktree 并询问是否切换过去,而闸门在
这条路径上同样会再次执行:只要 pre_start 仍然失败,你依旧进不去。修复原因之后,
重新运行还会补上被闸门拦下那次所跳过的复制和 post_start,因此你最终进入的 worktree
是配置完整的。
Claude Code 钩子模式
Section titled “Claude Code 钩子模式”vibe start --claude-code-worktree-hook 没有需要留在原地的 shell,因此 pre_start
闸门无法通过阻止目录切换来体现。该模式会保持既有约定——把 worktree 路径写入 stdout、
退出状态为 0——并改为在 stderr 上输出一行固定的、机器可读的信息来报告闸门:
vibe: pre_start hook failed; worktree is not provisioned该行在每次调用中最多出现一次,不带任何样式(没有颜色码),且仅在 pre_start 被闸门
拦下时出现;post_start 失败只会产生常规的 Warning: Hook "..." failed: ...。请把
它当作一个信号:你刚拿到的路径指向的 worktree 跳过了复制和 post_start。
有两点需要注意:
- 下文的设置示例在命令末尾使用了
2>/dev/null,这会丢弃 stderr,也就一并 丢弃了该信号。如果你想观察到闸门,请去掉这个重定向。 - 该信号只伴随创建 worktree 的那次运行。如果对已经存在 worktree 的分支再次调用钩子, 它会直接返回已有路径而不重新运行钩子,因此第二次调用不会输出该信号。
Node.js 项目
Section titled “Node.js 项目”[hooks]post_start = [ "pnpm install", "pnpm build"]pre_clean = ["git stash --include-untracked"]Bun 项目
Section titled “Bun 项目”[hooks]post_start = [ "bun install", "bun run build"]pre_clean = ["git stash --include-untracked"][hooks]post_start = [ "pnpm install", "pnpm db:migrate", "pnpm db:seed"]Docker 环境
Section titled “Docker 环境”[hooks]post_start = [ "docker-compose up -d", "sleep 5", "pnpm db:migrate"]pre_clean = ["docker-compose down"]Git 子模块
Section titled “Git 子模块”当某个直接子模块有自己的 setup 文件或钩子时,请使用一等公民的子模块配置:
[submodules]configs = ["libs/foo"]这会在新的 worktree 中执行 git submodule update --init -- libs/foo,然后通过常规的 trust store 加载 libs/foo/.vibe.toml。该子模块的 copy 规则和钩子会以 libs/foo 为基准解析路径,并在父仓库的 pre_start 钩子之前执行。
你可以使用 --no-hooks 选项跳过钩子:
vibe start feat/quick-fix --no-hooksClaude Code 集成
Section titled “Claude Code 集成”vibe 可以与 Claude Code 的 WorktreeCreate 和 WorktreeRemove 钩子集成。这会把 Claude Code 默认的 git worktree add 行为替换为 vibe 的完整工作流,包括钩子、CoW 文件复制和配置。
在 Claude Code 的 settings.json 中添加以下内容:
{ "hooks": { "WorktreeCreate": [ { "hooks": [ { "type": "command", "command": "vibe start --claude-code-worktree-hook --quiet 2>/dev/null" } ] } ], "WorktreeRemove": [ { "hooks": [ { "type": "command", "command": "vibe clean --claude-code-worktree-hook --force 2>/dev/null" } ] } ] }}当 Claude Code 创建 worktree 时(通过自然语言、isolation: "worktree" 或 /worktree 命令),vibe 会接管完整的生命周期:
WorktreeCreate:
- 从 stdin 读取 worktree 名称(Claude Code 钩子协议)
- 创建 git worktree
- 当配置了
[submodules] configs = [...]时,初始化列出的子模块并执行其已信任的 setup - 在源仓库中执行父仓库的
pre_start钩子 - 使用 CoW 复制父仓库的文件/目录
- 在新的 worktree 中执行父仓库的
post_start钩子(例如pnpm install) - 将 worktree 路径输出到 stdout 供 Claude Code 使用
WorktreeRemove:
- 从 stdin 读取 worktree 路径(Claude Code 钩子协议)
- 在 worktree 中执行
pre_clean钩子 - 删除 git worktree
- 在主仓库中执行
post_clean钩子
如果没有该集成,Claude Code 创建 worktree 时只会执行 git worktree add。借助 vibe 的钩子,你可以获得:
- 自动安装依赖(
pnpm install、bun install等) - CoW 文件复制(
.env、node_modules等) - 自定义 setup 脚本(数据库迁移、Docker 容器等)
- worktree 删除时的清理钩子