在 Codex 应用中,工作树允许 Codex 在同一项目中运行多个独立任务,且互不干扰。对于 Git 仓库, 自动化 会在专用的后台工作树上运行,因此不会与你正在进行的工作发生冲突。在非版本控制的项目中,自动化操作会直接在项目目录中运行。你也可以手动在某个工作树上启动线程,并使用移交(Handoff)功能在线程的本地工作区与工作树之间进行移动。
什么是工作树
工作树仅在属于 Git 仓库的项目中可用,因为它们底层使用的是 Git 工作树 。工作树允许你创建仓库的第二个副本(“检出”)。每个工作树都包含你仓库中所有文件的副本,但它们都共享相同的元数据(.git 文件夹),例如提交、分支等信息。这使你能够并行检出和处理多个分支。
术语
- 本地检出:你创建的仓库。有时也简称为 本地 in the Codex app.
- 工作树: A Git 工作树 是在 Codex 应用中从你的本地检出创建的。
- 移交:在本地和工作树之间移动线程的流程。Codex 负责处理在这两者之间安全迁移工作所需的 Git 操作。
为什么要使用工作树
- 与 Codex 并行工作,而不会打扰你当前的本地环境配置。
- 在保持前台专注的同时,将后台任务加入队列。
- 稍后将线程移至本地工作区,以便你进行直接检查、测试或协作。
入门
工作树需要 Git 仓库。请确保你选择的项目位于 Git 仓库中。
在本地工作区和工作树之间协作
工作树的外观和体验与你的本地检出非常相似。区别在于它们在你工作流程中的定位。你可以将本地工作区视为前台,将工作树视为后台。移交功能让你能够在两者之间移动线程。
在底层,移交功能会处理在两个检出之间安全移动工作所需的 Git 操作。这一点很重要,因为 Git 只允许一个分支在同一时间在一个位置被检出。如果你在工作树上检出分支,你 无法 同时在你的本地检出中检出它,反之亦然。
在实际操作中,有两种常见路径:
- 仅在工作树上工作。当你可以直接在工作树中验证更改时,此路径最为适用,例如因为你已经使用 本地环境设置脚本.
- 将线程移交给本地工作区。当你希望将线程调回前台时,请使用此选项,例如因为你希望在常用的 IDE 中检查更改,或者你的应用只能运行一个实例。
选项 1:在工作树上工作
如果你希望只在带有更改的工作树上继续工作,请使用 在此处创建分支 按钮,将你的工作树转化为一个分支。
从这里你可以提交更改,将分支推送到远程仓库,并在 GitHub 上发起 Pull Request。
你可以使用线程标题中的“打开”按钮在工作树目录中打开你的 IDE、使用集成终端,或执行任何需要在该工作树目录中进行的其他操作。
请记住,如果你在工作树上创建了一个分支,就不能在任何其他工作树(包括你的本地检出)中检出该分支。
选项 2:将线程移交给本地工作区
如果你想把某个线程移至前台处理,请点击 移交给 你的线程标题中的(按钮),并将其移至 本地.
当你想在常用的 IDE 窗口中查看更改、运行现有的开发服务器,或在你日常使用的相同环境中验证工作时,这种方式非常适用。
Codex 会处理在工作树和你的本地检出之间安全移动线程所需的 Git 步骤。
每个线程会随着时间的推移保持与其关联的工作树不变。如果你稍后将线程移回工作树,Codex 会将其恢复到相同的后台环境,以便你从上次中断的地方继续。
你也可以反向操作。如果你已经在本地工作区工作并想释放前台,可以使用 移交给 将线程移动到工作树。当你希望 Codex 在后台继续工作,同时你将注意力转回本地其他事务时,这会非常有用。
由于移交功能使用 Git 操作,因此作为你的 .gitignore 文件一部分的任何文件都不会随线程移动。
高级详细信息
Codex 管理的工作树和永久工作树
默认情况下,线程使用 Codex 管理的工作树。这些工作树旨在保持轻量且用完即弃。Codex 管理的工作树通常专用于单个线程,如果你稍后再次在该线程中操作,Codex 会将同一线程重新指向同一工作树。
如果你需要一个长期的环境,可以从侧边栏项目的三点菜单创建永久工作树。这会创建一个新的永久工作树,并将其作为独立的项目。永久工作树不会被自动删除,你可以从同一工作树启动多个线程。
Codex 如何为您管理工作树
Codex 在以下目录创建工作树: $CODEX_HOME/worktrees。起始提交将是您启动线程时所选分支的 HEAD 提交。如果你选择了带有本地更改的分支,未提交的更改也会应用到该工作树中。该工作树将会 并非 作为分支检出。它将处于 分离 HEAD 状态。这让 Codex 能够创建多个工作树而不会污染你的分支。
分支限制
假设 Codex 在某个工作树上完成了一些工作,你选择使用 feature/a 在其上创建一个分支 在此处创建分支。现在,你想在本地检出的代码中尝试它。如果你尝试检出该分支,你会得到以下错误:
fatal: 'feature/a' is already used by worktree at '<WORKTREE_PATH>'
要解决此问题,你需要检出另一个分支,而不是 feature/a 在工作树上。
如果你计划在本地检出该分支,请使用 Handoff 将线程移动到 Local,而不是试图在两个地方同时检出同一个分支。
为什么存在此限制
Git 阻止同一个分支同时在多个工作树中被检出,因为分支代表一个单一的可变引用(refs/heads/<name>),其含义是工作树的“当前检出状态”。
当检出一个分支时,Git 会将其 HEAD 视为该工作树所独有,并期望提交、重置、变基和合并等操作以定义良好的序列化方式推进该引用。允许多个工作树同时检出同一分支,将会在哪个工作树的操作有权更新分支引用的问题上产生歧义和竞态条件,这可能会导致提交丢失、索引不一致或冲突解决不明确。
通过执行“一个工作树对应一个分支”的规则,Git 确保每个分支都有一个单一的权威工作副本,同时仍允许其他工作树通过分离的 HEAD 或独立的分支安全地引用相同的提交。
工作树清理
工作树会占用大量磁盘空间。每个工作树都有自己的一组仓库文件、依赖项、构建缓存等。因此,Codex 应用会尽量将工作树的数量保持在合理的限度内。
默认情况下,Codex 会保留你最近 15 个由 Codex 管理的工作树。如果你希望自行管理磁盘使用情况,可以在设置中更改此限制或关闭自动删除功能。
Codex 会尽量避免删除仍然重要的工作树。由 Codex 管理的工作树在以下情况下不会被自动删除:
- 与之关联了一个被固定(pinned)的会话
- 线程仍在进行中
- 该工作树是一个永久工作树
由 Codex 管理的工作树会在以下情况下被自动删除:
- 你归档了关联的线程
- Codex 需要删除较旧的工作树以保持在配置的限制内
在删除由 Codex 管理的工作树之前,Codex 会保存其工作快照。如果你在相关工作树被删除后打开会话,将会看到恢复它的选项。
常见问题
我可以控制工作树的创建位置吗?
目前还不行。Codex 会将工作树创建在 $CODEX_HOME/worktrees 以便对其进行统一管理。
我可以在线程的本地模式和工作树模式之间移动吗?
可以。使用线程标题中的 移交给 即可在线程的本地检出和工作树之间进行移动。Codex 会处理将线程在不同环境间安全移动所需的 Git 操作。如果你之后将线程交还给工作树,Codex 会将其返回到原先关联的工作树。
如果工作树被删除,线程会怎样?
即使底层的工作树目录被删除,线程仍会保留在你的历史记录中。对于由 Codex 管理的工作树,Codex 在删除前会保存快照,并在你重新打开关联的线程时提供恢复选项。永久工作树不会在你归档其关联的线程时被自动删除。