Git worktree 允许在同一仓库中同时拥有多个工作目录,每个目录可以检出不同的分支。CodeBuddy Code 利用这一特性提供:
并行开发:在不影响主工作区的情况下进行实验性开发。
安全隔离:AI 的所有更改都在独立目录中进行。
零存储开销:worktree 共享 Git 对象,不会复制整个仓库。
子代理隔离:支持多个 AI 子代理在独立 worktree 中并行工作。
tmux 集成:可选在独立的 tmux 会话中运行。
非 Git 支持:通过 WorktreeCreate/WorktreeRemove hooks,SVN、Perforce 等项目也能使用 worktree 隔离。
# 自动生成名称创建 worktree
codebuddy --worktree
# 指定名称创建 worktree
codebuddy --worktree feature-auth
# 指定基础分支创建 worktree
codebuddy --worktree --worktree-branch origin/develop # 基于远程 develop 分支
codebuddy --worktree --worktree-branch feature/foo # 基于本地 feature/foo 分支
# 在 tmux 会话中运行(推荐用于长时间任务)
codebuddy --worktree --tmux
# 基于 PR/MR 创建 worktree(用于代码审查)
codebuddy --worktree "#123" # GitHub PR 编号
codebuddy --worktree "https://github.com/owner/repo/pull/123" # GitHub PR 链接
codebuddy --worktree "https://gitlab.com/owner/repo/-/merge_requests/456" # GitLab MR 链接
codebuddy --worktree "https://cnb.woa.com/owner/repo/-/pulls/789" # CNB PR 链接
已启动 CodeBuddy Code 会话后,可以通过自然语言请求创建 worktree:
> start a worktree> work in a worktree> 启动 worktree
AI 会自动调用 EnterWorktree 工具创建隔离工作目录并切换过去。
注意:
只有明确提到 “worktree” 时才会触发,说 “帮我开一个分支” 或“修复这个 bug” 不会自动创建 worktree。
参数 | 说明 | 示例 |
| 创建并进入 worktree |
|
| 指定基础分支(需配合 |
|
| 在 tmux 会话中运行(需要安装 tmux) |
|
| 使用传统 tmux 模式(不使用 popup) |
|
当使用 --worktree 参数启动时:
CodeBuddy 在 .codebuddy/worktrees/ 目录下创建新的 worktree
确定基础分支:
如果指定了 --worktree-branch origin/xxx,基于远程分支 origin/xxx
如果指定了 --worktree-branch xxx,基于本地分支 xxx
如果未指定,默认基于远程默认分支(通常是 origin/main 或 origin/master)
自动创建对应的分支(如 worktree-feature-auth)
将工作目录切换到 worktree;如果您是从仓库子目录启动,会优先进入新 worktree 中对应的相对子目录
执行初始化(复制设置、创建符号链接、复制 .worktreeinclude 文件等)
分支不存在时的行为:
如果指定的分支(远程或本地)不存在,会打印警告并自动降级到远程默认分支继续创建
不会中断启动流程
当您退出 worktree 会话时,CodeBuddy 会检测变更并提供选项:
保留 Worktree:保留所有更改和分支,可以稍后继续
删除 Worktree:清理 worktree 和关联分支
保留但退出 tmux:(tmux 模式)保留 worktree 但关闭 tmux 会话
退出前,CodeBuddy 会检测:
未提交的文件变更
未推送的提交
如果没有任何变更,worktree 会自动清理。
在 settings.json 中配置 worktree 行为:
{ "worktree": { "symlinkDirectories": ["node_modules", ".next", ".cache", "dist"] }}
配置项 | 说明 | 默认值 |
| 从主仓库符号链接到 worktree 的目录 |
|
符号链接目录可以避免在每个 worktree 中重复安装依赖,节省时间和磁盘空间。
.env.local、.env.development 等本地配置文件通常被 .gitignore 排除,但新 worktree 中同样需要它们才能正常运行。
解决方式:在仓库根目录创建 .worktreeinclude 文件,列出需要复制的文件(语法与 .gitignore 相同):
# .worktreeinclude
# 列出需要复制到新 worktree 的本地文件
# 环境变量
.env.local
.env.development.local
.env.test.local
# 本地 IDE 配置
.vscode/settings.json
# 本地证书或密钥(如有)
certs/localhost.pem
每次创建新 worktree 时,这些文件会自动从主仓库根目录复制过去。复用已有 worktree 时不会重新复制。
说明:
.worktreeinclude 应该提交到 Git,这样团队成员都能受益。
默认情况下,worktree 功能依赖 Git 内置的 git worktree 命令。对于使用 SVN、Perforce 或没有版本控制的项目,可以通过配置 WorktreeCreate / WorktreeRemove hooks 来使用 worktree 隔离功能。
1. 配置了 WorktreeCreate hook? → 使用 hook 创建(即使在 Git 仓库中也优先使用 hook)2. 在 Git 仓库中? → 使用 git worktree3. 都不满足? → 报错并提示配置 hook
核心规则:
Hook 优先于 Git:配置了 WorktreeCreate hook 后,即使在 Git 仓库中也走 hook,不走 git worktree
创建失败不降级:WorktreeCreate hook 失败时不会回退到 git worktree,直接报错
删除失败不阻塞:WorktreeRemove hook 失败只记录警告,不阻止退出流程
在 .codebuddy/settings.json(项目级)或 ~/.codebuddy/settings.json(全局)中配置:
{ "hooks": { "WorktreeCreate": [ { "hooks": [ { "type": "command", "command": "bash ~/.codebuddy/hooks/worktree-create.sh" } ] } ], "WorktreeRemove": [ { "hooks": [ { "type": "command", "command": "bash ~/.codebuddy/hooks/worktree-remove.sh" } ] } ] }}
两个 hook 独立配置,可以只配 WorktreeCreate 不配 WorktreeRemove(此时退出时不会自动清理,会提示手动删除目录)。
Hook 脚本通过 stdin 接收 JSON 格式的上下文数据。
WorktreeCreate 输入:
{ "hook_event_name": "WorktreeCreate", "session_id": "abc123def456", "cwd": "/Users/user/project", "transcript_path": "/Users/user/.codebuddy/sessions/abc123/transcript.md", "name": "feature-auth"}
字段 | 说明 |
| worktree 名称(用户指定或系统自动生成) |
| 当前工作目录 |
| 当前会话 ID |
| 对话记录文件路径 |
WorktreeRemove 输入:
{ "hook_event_name": "WorktreeRemove", "session_id": "abc123def456", "cwd": "/Users/user/project", "transcript_path": "/Users/user/.codebuddy/sessions/abc123/transcript.md", "worktree_path": "/tmp/codebuddy-worktrees/feature-auth"}
字段 | 说明 |
| 要删除的 worktree 绝对路径 |
WorktreeCreate:
stdout:必须输出创建好的 worktree 绝对路径(取最后一行非空行)
stderr:可输出日志,不影响路径解析
exit code 0:成功,解析 stdout 中的路径
exit code 非 0:创建失败,报错并退出(不降级到 git worktree)
# 正确示例:日志输出到 stderr,路径输出到 stdoutecho "Initializing SVN checkout..." >&2echo "/home/user/.codebuddy/worktrees/feature-auth"
WorktreeRemove:
没有决定控制:任何 exit code 都不会阻止退出流程
失败仅记录警告日志
与 Git worktree 不同,hook-based worktree 退出时始终显示 keep/remove 菜单,不做变更检测(因为非 Git 项目没有 git status)。
WorktreeCreate (~/.codebuddy/hooks/worktree-create.sh):
#!/bin/bash
set -e
INPUT=$(cat)
NAME=$(echo "$INPUT" | jq -r '.name')
CWD=$(echo "$INPUT" | jq -r '.cwd')
WORKTREE_PATH="$HOME/.codebuddy/worktrees/$NAME"
mkdir -p "$WORKTREE_PATH"
# 在这里添加 VCS 初始化逻辑(SVN checkout、P4 sync、目录复制等)
cp -r "$CWD"/* "$WORKTREE_PATH/" 2>/dev/null || true
# 最后一行输出绝对路径到 stdout(必需)
echo "$WORKTREE_PATH"
WorktreeRemove (~/.codebuddy/hooks/worktree-remove.sh):
#!/bin/bash
INPUT=$(cat)
WORKTREE_PATH=$(echo "$INPUT" | jq -r '.worktree_path')
# 安全检查:确保路径在预期范围内
if [[ "$WORKTREE_PATH" != "$HOME/.codebuddy/worktrees/"* ]]; then
echo "Refusing to remove path outside worktrees directory: $WORKTREE_PATH" >&2
exit 1
fi
rm -rf "$WORKTREE_PATH"
说明:
脚本依赖 jq 解析 JSON。macOS:brew install jq,Linux:apt install jq。
SVN 项目:
{ "hooks": { "WorktreeCreate": [ { "hooks": [ { "type": "command", "command": "bash -c 'INPUT=$(cat); NAME=$(echo $INPUT | jq -r .name); DIR=\"$HOME/.codebuddy/worktrees/$NAME\"; svn checkout https://svn.example.com/repo/trunk \"$DIR\" >&2 && echo \"$DIR\"'" } ] } ], "WorktreeRemove": [ { "hooks": [ { "type": "command", "command": "bash -c 'cat | jq -r .worktree_path | xargs rm -rf'" } ] } ] }}
无 VCS 的项目(目录复制):
{ "hooks": { "WorktreeCreate": [ { "hooks": [ { "type": "command", "command": "bash -c 'INPUT=$(cat); NAME=$(echo $INPUT | jq -r .name); CWD=$(echo $INPUT | jq -r .cwd); DIR=\"$HOME/.codebuddy/worktrees/$NAME\"; cp -r \"$CWD\" \"$DIR\" && echo \"$DIR\"'" } ] } ], "WorktreeRemove": [ { "hooks": [ { "type": "command", "command": "bash -c 'cat | jq -r .worktree_path | xargs rm -rf'" } ] } ] }}
使用 --tmux 参数可以在独立的 tmux 会话中运行 CodeBuddy:
# 基本用法
codebuddy --worktree --tmux
# 使用传统模式(不使用 popup)
codebuddy --worktree --tmux --tmux-classic
tmux 版本 3.2 或更高(支持 popup 功能)
如果版本较低,会自动回退到传统模式
按 Ctrl+D 或输入 /exit 退出 CodeBuddy
tmux 会话会根据您的选择保留或关闭
your-repo/├── .codebuddy/│ └── worktrees/│ ├── feature-auth/ # worktree 目录│ │ ├── node_modules -> ../../node_modules # 符号链接│ │ └── ...│ └── fix-bug-123/├── .worktreeinclude # 定义需要复制的本地文件(建议提交)└── ...
CodeBuddy Code 在会话退出时会自动处理 worktree 的清理。但有时需要在会话外手动管理——比如清理残留的 worktree,或者需要更灵活地控制分支和目录位置。
直接使用 Git 命令清理:
# 查看当前所有 worktree
git worktree list
# 删除指定 worktree(worktree 内没有未提交改动时)
git worktree remove .codebuddy/worktrees/feature-auth
# 强制删除(有未提交改动时)
git worktree remove --force .codebuddy/worktrees/feature-auth
# 同时删除对应的分支
git branch -D worktree-feature-auth
# 清理失效的 worktree 引用(目录已删但 Git 还记着)
git worktree prune
有时需要检出已有分支,或者把 worktree 放到仓库目录之外,可以绕开 CodeBuddy Code 直接用 Git 创建,然后再在里面启动会话:
# 新建分支并创建 worktree(放在仓库外)
git worktree add ../project-feature-a -b feature-a
# 检出已有分支
git worktree add ../project-bugfix bugfix-123
# 进入 worktree,启动 CodeBuddy Code
cd ../project-feature-a && codebuddy
# 用完后清理
git worktree remove ../project-feature-a
这种方式适合需要把 worktree 放在特定位置、或者复用现有分支的场景。
当让 CodeBuddy Code 启动多个子代理并行工作时,可以让每个子代理运行在独立的 worktree 中,避免文件冲突。
isolation: worktree 是什么在自定义 Agent 的 frontmatter 中加上 isolation: worktree,每次用 Task 工具启动这个 Agent 时,系统会自动为它创建一个独立的 worktree,而不是在主仓库目录里直接运行。
这意味着:
多个子代理可以同时修改同名文件,互不影响
主仓库目录保持干净,子代理的临时改动不会污染它
子代理完成后,worktree 按需保留或删除
在 .codebuddy/agents/ 目录下创建 Markdown 文件:
---
name: isolated-worker
description: 在独立 worktree 中工作,不影响主仓库
isolation: worktree
---
您在一个独立的 git worktree 中运行。
请专注完成分配给您的任务,完成后汇报结果。
主 Agent 用 Task 工具启动该 Agent 时,会自动为它创建独立的 worktree。多个子代理可以同时工作,即使修改了相同的文件也不会冲突。
子代理完成后:
没有变更:worktree 自动删除
有变更:worktree 保留,主 Agent 会收到 worktree 位置信息
> 使用 isolated-worker agent,在当前目录创建 test.txt,写入 "hello"
检查结果:
# 主仓库里没有这个文件
ls test.txt
# → No such file or directory ✓
# 文件在子代理的 worktree 里
ls .codebuddy/worktrees/agent-xxx/test.txt
# → 存在 ✓
问题:需要在 develop 分支上开发新功能,而不是基于 main 分支。
解决方案:
# 基于远程 develop 分支创建 worktree
codebuddy --worktree feature-xxx --worktree-branch origin/develop
# 基于本地分支创建(保留本地未推送的提交)
codebuddy --worktree feature-yyy --worktree-branch my-local-branch
问题:正在开发新功能,代码改了一半,突然需要修紧急 bug。
解决方案:
# 终端 1:继续开发新功能
codebuddy --worktree feature-payment
# 终端 2:专门修 bug,互不干扰
codebuddy --worktree hotfix-login-crash
两个 worktree 同时打开,互不影响。bug 修完提交 PR,再回到功能开发。
问题:想尝试大规模重构,但不确定能否成功,不想污染主仓库。
解决方案:
codebuddy --worktree refactor-esm
在会话中:
> 帮我把 src/core 目录从 CommonJS 迁移到 ESM
结果:
成功:提交,推 PR,合并。
失败:退出时选择 “Remove worktree”,所有改动一键丢弃。
问题:想在本地跑一下同事的 PR 代码,但不想污染工作目录。
解决方案:
codebuddy --worktree "#456"
在会话中:
> 帮我看看这次 PR 改了什么,有没有潜在问题> 运行一下测试
审查完直接退出,worktree 自动清理。
问题:有多个独立任务(写文档、加测试、开发新接口),想分别推进。
解决方案:
codebuddy --worktree task-docs --tmuxcodebuddy --worktree task-tests --tmuxcodebuddy --worktree task-new-api --tmux
每个 worktree 让 AI 专注做一件事,配合 tmux 实现真正并行工作。
问题:大型任务需要多个 AI 并行处理不同模块。
解决方案:
首先创建隔离型 Agent(见上文子代理隔离章节),然后:
> 使用三个并行的 api-worker 子代理: 第一个处理 src/api/user/ 目录 第二个处理 src/api/order/ 目录 第三个处理 src/api/product/ 目录
三个子代理各自在独立 worktree 中工作,即使修改了共享文件也不会冲突。
--worktree-branch 应该传远程分支还是本地分支?严格区分:
--worktree-branch origin/xxx → 使用远程分支(会先 fetch 最新代码)
--worktree-branch xxx → 使用本地分支(保留本地未推送的提交)
如果指定的分支不存在,会打印警告并降级到远程默认分支,不会中断启动。
不会。所有 worktree 共享 Git 对象数据库,只需要存储工作文件本身。如果配置了 symlinkDirectories,大型目录也会共享,几乎不占额外空间。
不会。复用时直接进入已有目录,跳过初始化。如需同步新配置,需删除 worktree 后重建:
git worktree remove --force .codebuddy/worktrees/my-featuregit branch -D worktree-my-featurecodebuddy --worktree my-feature
不会。worktree 有独立分支,提交只在该分支上。要合并到主分支,需走正常 PR 流程或手动 git merge。
git worktree remove --force .codebuddy/worktrees/<名称>git branch -D worktree-<名称>
然后重新创建即可。
复用已有 worktree 时不会重新初始化。删除旧 worktree 重建一次即可。
不是。子代理在文件层面隔离,但权限与主 Agent 相同,理论上可操作 worktree 之外的文件。这个功能的目的是防止多个 Agent 之间的文件冲突,而非安全限制。
不能同时使用。Hook 优先级高于 Git——一旦配置了 WorktreeCreate hook,所有 worktree 操作都走 hook,即使在 Git 仓库中也是如此。要恢复使用 git worktree,删除 settings.json 中的 WorktreeCreate 配置即可。
创建正常工作,但退出时不会自动清理。系统会提示 worktree 目录保留在哪里,需要手动删除。
WorktreeCreate 失败会直接报错,不会降级到 git worktree,检查脚本的 stderr 输出排查问题。WorktreeRemove 失败只记录警告,不影响退出流程。
hook-based worktree 退出时始终显示 keep/remove 菜单,不进行变更检测(因为非 Git 项目没有 git status)。需要手动选择是否删除。
Git 仓库或 Hook:--worktree 需要 Git 仓库或配置 WorktreeCreate hook(非 Git 项目如 SVN、Perforce 可通过 hook 支持)
分支命名:自动创建的分支以 worktree- 为前缀
清理:长时间未使用的 worktree 不会自动清理,需要手动删除或使用 /rewind 命令
符号链接:某些工具可能不支持符号链接的目录,请根据项目需求配置
CLI 参考 - 完整的命令行参数说明
Hooks 参考 - Hook 系统详细文档
设置配置 - 配置文件说明