中文

工作树

工作树

在 ChatGPT 桌面应用的 Codex 中使用 Git 工作树并行运行聊天

工作树让 Codex 能够在同一项目中运行多个相互独立、互不干扰的聊天。仓库、工作树和命令都保留在包含该项目的计算机或远程开发环境中。你可以直接在 ChatGPT 桌面应用中工作,也可以在 ChatGPT 移动应用中使用 Remote,在连接的计算机上启动、指导、批准和审查工作树聊天。

对于 Git 仓库,计划任务可以在专用的后台工作树上运行,避免与你正在进行的工作冲突。在未使用版本控制的项目中,计划任务会直接在项目目录中运行。你也可以手动在工作树中启动聊天,并使用 Handoff 在 Local 和 Worktree 之间移动聊天。

什么是工作树

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

术语

  • 本地检出:你创建的仓库。在 ChatGPT 桌面应用中有时简称为 Local
  • 工作树:在 ChatGPT 桌面应用中从本地检出创建的 Git 工作树
  • Handoff:在 Local 和 Worktree 之间移动聊天的流程。Codex 会处理在二者之间安全移动工作所需的 Git 操作。

为什么使用工作树

  1. 与 Codex 并行工作,而不干扰当前的 Local 设置。
  2. 将工作排入后台队列,同时专注于前台任务。
  3. 准备好检查、测试或开展更直接的协作时,再将聊天移入 Local。

开始使用

工作树需要 Git 仓库。请确保所选项目位于 Git 仓库中。

  1. 选择“Worktree”

    在新聊天视图中,选择编辑框下方的 Worktree。 你也可以选择一个本地环境,为工作树运行设置脚本。

  2. 选择起始分支

    在编辑框下方,选择工作树所基于的 Git 分支。它可以是你的 main / master 分支、功能分支,或包含未暂存本地更改的当前分支。

  3. 提交提示词

    提交提示词后,Codex 会基于所选分支创建 Git 工作树。默认情况下,Codex 在“分离 HEAD”状态下工作。

  4. 选择继续工作的位置

    准备好后,你可以继续直接在工作树上工作,也可以将聊天移交给本地检出。移交到 Local 或从 Local 移出时,会同时移动聊天和代码,以便你在另一个检出中继续工作。

在 Local 和 Worktree 之间工作

工作树的外观和使用体验与本地检出非常相似,区别在于它们在工作流中的位置。你可以将 Local 视为前台,将 Worktree 视为后台。Handoff 可让你在二者之间移动聊天。

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

实际使用中有两种常见方式:

  1. 仅在工作树上工作。如果你能直接在工作树上验证更改,例如已通过本地环境设置脚本安装依赖项和工具,那么这种方式最合适。
  2. 将聊天移交给 Local。当你想将聊天移到前台时可使用此方式,例如,你想在常用 IDE 中检查更改,或只能运行一个应用实例。

选项 1:在工作树上工作

如果你想带着更改始终在工作树上工作,请使用聊天标题栏中的 Create branch here 按钮,将工作树转换为分支。

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

你可以使用标题栏中的“Open”按钮在 IDE 中打开工作树,也可以使用集成终端,或在工作树目录中使用所需的任何其他工具。

包含分支控件和工作树详细信息的工作树聊天视图(浅色模式)
请记住,如果你在工作树上创建分支,就无法在任何其他工作树(包括本地检出)中检出该分支。

选项 2:将聊天移交给 Local

如果你想将聊天移到前台,请在聊天标题栏中选择 Hand off,然后将其移动到 Local

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

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

每个聊天会始终保留与同一个工作树的关联。如果之后将聊天交回工作树,Codex 会让它返回同一个后台环境,以便你从上次中断的位置继续。

将聊天从工作树移交到 Local 的 Handoff 对话框(浅色模式)
你也可以反向操作。如果你已经在 Local 中工作,并想释放前台,请使用 **Hand off** 将聊天移到工作树。当你希望 Codex 继续在后台工作,同时将注意力转回本地的其他事项时,这很有用。

由于 Handoff 使用 Git 操作,属于 .gitignore 文件的任何文件都不会随聊天移动,除非 Codex 使用 .worktreeinclude 将它们复制到本地托管工作树中。

高级详情

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

默认情况下,聊天使用 Codex 托管工作树。它们旨在提供轻量且可随时弃用的体验。Codex 托管工作树通常专用于一个聊天;如果你之后将该聊天交回工作树,Codex 会让它返回同一个工作树。

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

Codex 如何为你管理工作树

Codex 在 $CODEX_HOME/worktrees 中创建工作树。起始提交是你启动聊天时所选分支的 HEAD 提交。如果所选分支包含本地更改,Codex 也会将未提交的更改应用到工作树。工作树不会作为分支被检出,而是处于分离 HEAD 状态。这样,Codex 无需让你的分支变得杂乱,就能创建多个工作树。

将忽略的本地文件复制到托管工作树

本地 Codex 托管工作树从 Git 检出开始,因此跟踪的文件已存在。如果仓库忽略了新工作树所需的本地设置文件,请将 .worktreeinclude 文件添加到仓库根目录,并列出 Codex 创建托管工作树时要复制的忽略路径或 .gitignore 风格的模式。

此功能适用于 Git 有意忽略的文件,例如 .env.env.localconfig/secrets.json。Codex 只复制与 .worktreeinclude 匹配的忽略文件;它不会复制 Git 未跟踪的其他本地文件。请勿列出已跟踪的文件。

Codex 会自动将忽略的 AGENTS.override.md 复制到本地托管工作树,因此无需在 .worktreeinclude 中列出它。

# .worktreeinclude
.env
.env.local
config/secrets.json

Codex 会跳过源符号链接,并且不会覆盖新检出中已存在的文件。此行为适用于 ChatGPT 桌面应用在本地托管的工作树,不适用于远程工作树或你自行从命令行创建的 Git 工作树。

分支限制

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

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

若要解决此问题,你需要在工作树上检出 feature/a 以外的其他分支。

如果你打算在本地检出该分支,请使用 Handoff 将聊天移入 Local,不要尝试让同一个分支同时在两个位置保持检出状态。

为什么存在此限制 Git 不允许同一个分支同时在多个工作树中检出,因为分支代表单个可变引用(`refs/heads/`),其含义是工作树的“当前检出状态”。

检出分支后,Git 会将其 HEAD 视为由该工作树所有,并要求提交、重置、变基和合并等操作以定义明确的串行方式推进该引用。如果允许多个工作树同时检出同一个分支,就无法明确哪个工作树的操作应更新分支引用,并会产生竞态条件,可能导致提交丢失、索引不一致或冲突解决方式不明确。

通过强制实施每个工作树一个分支的规则,Git 可保证每个分支只有一个权威工作副本,同时仍允许其他工作树通过分离 HEAD 或独立分支安全地引用相同提交。

工作树清理

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

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

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

  • 有置顶聊天与其关联
  • 聊天仍在进行中
  • 该工作树是永久工作树

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

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

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

常见问题

我可以控制工作树的创建位置吗? 可以。默认情况下,Codex 会在 `$CODEX_HOME/worktrees` 下创建托管工作树。 若要选择其他位置,请打开 **Settings > Worktrees** 并更改 **Worktree root**。

我可以在 Local 和 Worktree 之间移动聊天吗? 可以。使用聊天标题栏中的 **Hand off**,可在本地检出和工作树之间 移动聊天。Codex 会处理在不同环境之间安全移动聊天所需的 Git 操作。 如果你之后将聊天交回工作树,Codex 会让它返回 同一个关联的工作树。

如果工作树被删除,聊天会怎样? 即使底层工作树目录已被删除,聊天仍可保留在历史记录中。 对于 Codex 托管工作树,Codex 会在删除工作树前保存快照, 并在你重新打开关联的聊天时提供恢复选项。 归档永久工作树的聊天时,不会自动删除该工作树。