Skip to content

Worktrees(工作树)

在 Codex 应用中使用 Git 工作树,让 Codex 能够并行工作

在 Codex 应用中,工作树(worktrees)允许 Codex 在同一个项目中同时运行多个独立任务,互不干扰。对于 Git 仓库,自动化任务在专用的后台工作树上运行,因此不会与你正在进行的工作产生冲突。在非版本控制的项目中,自动化任务直接在项目目录中运行。你也可以手动在工作树上启动线程,并使用 Handoff(移交)功能在线程的本地环境和工作树之间移动。

工作树仅适用于属于 Git 仓库的项目,因为它们在底层使用了 Git 工作树。工作树允许你创建仓库的第二份副本(“检出”)。每个工作树都有仓库中每个文件的独立副本,但它们都共享相同的元数据(.git 文件夹),包括提交、分支等信息。这使得你可以并行检出和操作多个分支。

  • Local 检出:你创建的仓库。在 Codex 应用中有时简称为 Local(本地环境)。
  • Worktree(工作树):在 Codex 应用中从你的本地检出品创建的 Git 工作树
  • Handoff(移交):将线程在本地环境和工作树之间移动的流程。Codex 会处理安全移动工作所需的 Git 操作。
  1. 与 Codex 并行工作,同时不干扰你当前的本地环境设置。
  2. 在后台排队执行任务,而你继续专注于前台工作。
  3. 当你准备好更直接地检查、测试或协作时,将线程移入本地环境。

工作树需要一个 Git 仓库。请确保你选择的项目位于 Git 仓库中。

  1. 选择 “Worktree”

在新线程视图中,在输入框下方选择 Worktree。你也可以选择为工作树运行设置脚本的本地环境。

  1. 选择起始分支

在输入框下方,选择作为工作树基础的 Git 分支。这可以是你的 main / master 分支、功能分支,或者带有未暂存本地更改的当前分支。

  1. 提交你的提示词

提交你的任务后,Codex 将基于你选择的分支创建 Git 工作树。默认情况下,Codex 在 “分离 HEAD”(detached HEAD)状态下工作。

  1. 选择继续工作的位置

当你准备好时,可以直接在工作树上继续工作,也可以将线程移交给本地检出品。移入或移出本地环境将移动你的线程和代码,以便你可以在另一个检出品中继续工作。

工作树的外观和体验与本地检出品非常相似。区别在于它们在流程中的位置。你可以将本地环境视为前台,将工作树视为后台。Handoff 让你可以在两者之间移动线程。

在底层,Handoff 处理在两个检出品之间安全移动工作所需的 Git 操作。这一点很重要,因为 Git 一次只允许在一个地方检出同一个分支。如果你在工作树上检出了一个分支,就无法同时在本地检出品中检出它,反之亦然。

实践中,有两条常见的路径:

  1. 专门在工作树上工作。当你可以在工作树上直接验证更改时(例如因为你使用本地环境设置脚本安装了依赖项和工具),这条路径效果最好。
  2. 将线程移交给本地环境。当你想将线程带到前台时使用此方式,例如因为你想在常用的 IDE 中检查更改,或者因为你的应用只能运行一个实例。

如果你想完全在工作树上处理你的更改,请使用线程标题栏中的 Create branch here(在此创建分支) 按钮将工作树转变为分支。

从这里你可以提交更改、将分支推送到远程仓库,并在 GitHub 上创建拉取请求。

你可以使用标题栏中的 “打开” 按钮在工作树目录中打开 IDE、使用集成终端,或执行任何其他你需要做的操作。

请记住,如果你在工作树上创建了分支,就无法在任何其他工作树(包括本地检出品)中检出该分支。

如果你想将线程带到前台,请点击线程标题栏中的 Hand off(移交) 并将其移动到本地环境。

当你想在常用的 IDE 窗口中查看更改、运行现有的开发服务器,或在你日常使用的同一环境中验证工作时,这条路径非常有效。

Codex 处理在线程的工作树和本地检出品之间安全移动所需的 Git 步骤。

每个线程随时间保持关联的同一个工作树。如果你稍后将线程移交回工作树,Codex 会将其返回到同一个后台环境,以便你从上次中断的地方继续。

你也可以反向操作。如果你已经在本地环境中工作,并想释放前台,可以使用 Hand off 将线程移动到工作树。这在你想让 Codex 在后台继续工作而你将注意力切换回本地其他事情时非常有用。

由于 Handoff 使用 Git 操作,因此 .gitignore 文件中的任何文件不会随线程一起移动。

Codex 托管的工作树和永久工作树

Section titled “Codex 托管的工作树和永久工作树”

默认情况下,线程使用 Codex 托管的工作树。这些工作树设计为轻量级和可丢弃的。Codex 托管的工作树通常专用于一个线程,并且如果稍后移交回来,Codex 会将线程返回到同一个工作树。

如果你想要一个长期存在的环境,可以从侧边栏中项目的三点菜单创建永久工作树。这将创建一个新的永久工作树作为独立项目。永久工作树不会自动删除,你可以从同一个工作树启动多个线程。

Codex 在 $CODEX_HOME/worktrees 中创建工作树。起始提交将是启动线程时所选分支的 HEAD 提交。如果你选择了带有本地更改的分支,未提交的更改也将应用到工作树上。工作树不会作为分支检出,它将处于分离 HEAD 状态。这让 Codex 可以创建多个工作树而不会污染你的分支。

假设 Codex 在工作树上完成了一些工作,你选择使用 Create branch here 在其上创建 feature/a 分支。现在你想在本地检出品上尝试它。如果你尝试检出该分支,将会收到以下错误:

Terminal window
fatal: 'feature/a' is already used by worktree at '<WORKTREE_PATH>'

要解决这个问题,你需要在工作树上检出另一个分支而不是 feature/a

如果你计划在本地检出该分支,请使用 Handoff 将线程移入本地环境,而不是尝试在两个地方同时保持同一分支的检出状态。

Git 阻止同一个分支同时在多个 worktree 中签出,因为一个分支代表一个单一的可变引用(refs/heads/<name>),其含义是工作树的 “当前签出状态”。

当一个分支被签出时,Git 会将其 HEAD 视为由该 worktree 拥有,并期望操作(如提交、重置、rebase 和合并)以明确定义的序列化方式推进该引用。允许多个 worktree 同时签出同一分支会产生歧义和竞争条件,导致无法确定哪个 worktree 的操作会更新分支引用,从而可能导致提交丢失、索引不一致或冲突解决不清晰。

通过执行 “一分支一 worktree” 规则,Git 保证每个分支只有一个权威工作副本,同时仍允许其他 worktree 通过分离 HEAD 或使用不同分支安全地引用相同的提交。

工作树可能会占用大量磁盘空间。每个工作树都有自己的一套仓库文件、依赖项、构建缓存等。因此,Codex 应用会尽量将工作树数量保持在合理范围内。

默认情况下,Codex 保留你最近的 15 个 Codex 托管的工作树。如果你希望自行管理磁盘使用情况,可以在设置中更改此限制或关闭自动删除。

Codex 尽量避免删除仍然重要的工作树。Codex 托管的工作树在以下情况下不会被自动删除:

  • 有固定的对话与之关联
  • 线程仍在进行中
  • 该工作树是永久工作树

Codex 托管的工作树在以下情况下会被自动删除:

  • 你归档了关联的线程
  • Codex 需要删除较旧的工作树以保持在配置的限制内

在删除 Codex 托管的工作树之前,Codex 会保存其工作的快照。如果你在某个对话的工作树被删除后打开该对话,你将看到恢复它的选项。

  • 我可以控制工作树的创建位置吗? 今天不行。Codex 会在 $CODEX_HOME/worktrees 下创建 worktrees,以便能够一致地管理它们。
  • 我可以在本地环境和工作树之间移动线程吗? 可以。在线程标题中使用 Hand off 将线程在本地签出和 worktree 之间移动。Codex 会处理所需的 Git 操作,以确保线程在环境之间安全移动。如果你稍后将线程交还给 worktree,Codex 会将其返回到相同的关联 worktree。
  • 如果工作树被删除,线程会怎样? 即使底层 worktree 目录被删除,线程仍可以保留在你的历史记录中。对于 Codex 管理的 worktrees,Codex 会在删除 worktree 前保存快照,并在你重新打开关联线程时提供恢复选项。永久 worktrees 在归档其线程时不会被自动删除。
-
0:000:00