工作树
工作树
在 ChatGPT 桌面应用的 Codex 中使用 Git 工作树并行运行聊天
工作树让 Codex 能够在同一项目中运行多个相互独立、互不干扰的聊天。仓库、工作树和命令都保留在包含该项目的计算机或远程开发环境中。你可以直接在 ChatGPT 桌面应用中工作,也可以在 ChatGPT 移动应用中使用 Remote,在连接的计算机上启动、指导、批准和审查工作树聊天。
对于 Git 仓库,计划任务可以在专用的后台工作树上运行,避免与你正在进行的工作冲突。在未使用版本控制的项目中,计划任务会直接在项目目录中运行。你也可以手动在工作树中启动聊天,并使用 Handoff 在 Local 和 Worktree 之间移动聊天。
什么是工作树
工作树仅适用于 Git 仓库中的项目,因为它们在底层使用 Git 工作树。工作树可让你创建仓库的第二个副本(“检出”)。每个工作树都有仓库中每个文件的独立副本,但它们共享有关提交、分支等的相同元数据(.git 文件夹)。因此,你可以并行检出和处理多个分支。
术语
- 本地检出:你创建的仓库。在 ChatGPT 桌面应用中有时简称为 Local。
- 工作树:在 ChatGPT 桌面应用中从本地检出创建的 Git 工作树。
- Handoff:在 Local 和 Worktree 之间移动聊天的流程。Codex 会处理在二者之间安全移动工作所需的 Git 操作。
为什么使用工作树
- 与 Codex 并行工作,而不干扰当前的 Local 设置。
- 将工作排入后台队列,同时专注于前台任务。
- 准备好检查、测试或开展更直接的协作时,再将聊天移入 Local。
开始使用
工作树需要 Git 仓库。请确保所选项目位于 Git 仓库中。
选择“Worktree”
在新聊天视图中,选择编辑框下方的 Worktree。 你也可以选择一个本地环境,为工作树运行设置脚本。
选择起始分支
在编辑框下方,选择工作树所基于的 Git 分支。它可以是你的
main/master分支、功能分支,或包含未暂存本地更改的当前分支。提交提示词
提交提示词后,Codex 会基于所选分支创建 Git 工作树。默认情况下,Codex 在“分离 HEAD”状态下工作。
选择继续工作的位置
准备好后,你可以继续直接在工作树上工作,也可以将聊天移交给本地检出。移交到 Local 或从 Local 移出时,会同时移动聊天和代码,以便你在另一个检出中继续工作。
在 Local 和 Worktree 之间工作
工作树的外观和使用体验与本地检出非常相似,区别在于它们在工作流中的位置。你可以将 Local 视为前台,将 Worktree 视为后台。Handoff 可让你在二者之间移动聊天。
在底层,Handoff 会处理在两个检出之间安全移动工作所需的 Git 操作。这一点很重要,因为 Git 只允许一个分支同时在一个位置被检出。如果你在工作树中检出某个分支,就无法同时在本地检出中检出该分支,反之亦然。
实际使用中有两种常见方式:
- 仅在工作树上工作。如果你能直接在工作树上验证更改,例如已通过本地环境设置脚本安装依赖项和工具,那么这种方式最合适。
- 将聊天移交给 Local。当你想将聊天移到前台时可使用此方式,例如,你想在常用 IDE 中检查更改,或只能运行一个应用实例。
选项 1:在工作树上工作
如果你想带着更改始终在工作树上工作,请使用聊天标题栏中的 Create branch here 按钮,将工作树转换为分支。
之后,你可以提交更改、将分支推送到远程仓库,并在 GitHub 上创建拉取请求。
你可以使用标题栏中的“Open”按钮在 IDE 中打开工作树,也可以使用集成终端,或在工作树目录中使用所需的任何其他工具。
选项 2:将聊天移交给 Local
如果你想将聊天移到前台,请在聊天标题栏中选择 Hand off,然后将其移动到 Local。
当你想在常用 IDE 窗口中查看更改、运行现有开发服务器,或在日常使用的同一环境中验证工作时,这种方式非常合适。
Codex 会处理在工作树和本地检出之间安全移动聊天所需的 Git 步骤。
每个聊天会始终保留与同一个工作树的关联。如果之后将聊天交回工作树,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.local 或 config/secrets.json。Codex 只复制与 .worktreeinclude 匹配的忽略文件;它不会复制 Git 未跟踪的其他本地文件。请勿列出已跟踪的文件。
Codex 会自动将忽略的 AGENTS.override.md 复制到本地托管工作树,因此无需在 .worktreeinclude 中列出它。
# .worktreeinclude
.env
.env.local
config/secrets.jsonCodex 会跳过源符号链接,并且不会覆盖新检出中已存在的文件。此行为适用于 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 会保存其中工作的快照。如果你在工作树被删除后打开聊天,将看到恢复该工作树的选项。