Skip to content

Worktree ​

DevAgent 如何将每个功能或缺陷变成它自己的 git worktree。

DevAgent 是以 worktree 为原生模型的。它不是在单个检出上进行分支和 stash,而是通过 git worktree 为每个任务创建一份自己的磁盘上的 repo 副本。这正是并行 agent 得以安全运行的原因——它们永远不会互相踩到对方的文件。

模型 ​

  • 每个 repo 有一个基准 ref(通常是 origin/main)。
  • 每个 worktree 有一个起始 ref——它从这里分出。
  • 每个 worktree 有自己的分支、自己在磁盘上的文件,以及自己的 agent 终端。
  • 删除一个 worktree 会同时移除目录和分支(会有确认)。如果 git 因为某个本地分支可能还有未合并的提交而保留它,DevAgent 可以提供一个审查步骤——见被保留的分支。

单个功能的生命周期 ​

  1. 创建 —— 任务名称、起始点选择器、可选的 GitHub / Linear / Jira / GitLab 链接。
  2. 工作 —— agent 终端、编辑器 标签页、浏览器 标签页、终端 窗格,全都限定在此 worktree 内。
  3. 审查 —— 相对起始 ref 的 diff 视图、Annotate AI Diff、Attribution。
  4. 交付 —— 提交、推送、开 PR、等待检查——全都内联完成。
  5. 归档或删除 —— 一键移除 worktree 和分支。

创建在后台运行 ​

提交创建 Worktree 对话框后会立即关闭它——git fetch 和 git worktree add 的工作会在后台继续,而你可以继续使用 DevAgent。新的 worktree 会带着一个进度行出现在侧边栏中,该 worktree 的 标签页 会显示实时的设置状态,直到检出完成并切换到终端。当创建仍在进行时,你可以切换到其他 worktree、观察进度,或从 标签页 内的面板取消它。如果创建失败,面板会显示错误并提供重试。

起始点选择器 ​

创建 worktree 时你可以选择从哪里分支。这可以是:

  • repo 的基准 ref(快速路径)。
  • 另一个本地分支——对于在审查中的 PR 之上叠加工作很有用。
  • 一个特定的 commit SHA。
  • 一个已存在的远程分支——DevAgent 会 fetch 并检出它。

共享目录与被 gitignore 的文件 ​

一个全新的 worktree 是一份干净的检出。依赖、缓存以及存放在被 gitignore 路径下的本地密钥,在你重新创建它们之前都是缺失的。

DevAgent 通过三种互补的方式填补这个缺口:

  1. Worktree Shared Paths(按 repo 配置,位于 设置 → 仓库)—— 这些路径会从主检出实体化到每个新 worktree 中(在 macOS 上尽可能使用 APFS 克隆复制,否则使用符号链接)。
  2. orca.yaml 中的 worktree.sharedDirectories —— 一份签入 repo 的被 gitignore 目录列表,以同样方式共享(符号链接/共享,而非复制)。用于像 node_modules 或 .cache 这样可重建的大型目录树。条目必须在主检出中作为目录存在且被 gitignore;被跟踪或缺失的路径会被跳过。(配置文件名固定为 orca.yaml,请按原样命名,DevAgent 只识别这个文件名。)
  3. repo 根目录下的 .worktreeinclude —— 一份要复制(而非符号链接)到每个新 worktree 的被 gitignore 文件或目录列表,因此每个 worktree 拥有自己的副本。典型条目:.env、.vscode/ 下的本地配置。允许空行和 # 注释。目前仅支持字面量路径——glob 和取反会被跳过并给出警告。被跟踪、缺失或未被 gitignore 的路径不会被复制。

orca.yaml 中的共享目录是追加到每个用户的 Worktree Shared Paths 列表上的;它们绝不会替换该列表。已经被共享/链接的路径不会再从 .worktreeinclude 复制一遍。

# orca.yaml (repo root)
worktree:
  sharedDirectories:
    - node_modules
    - .cache
# .worktreeinclude (repo root)
.env
.env.local
.vscode/settings.json

创建对话框:Project、Run on、agent 和任务链接 ​

创建 Workspace 对话框为 Project 和 Run on 使用了带即时输入过滤的组合框:

  • 输入即可过滤;Enter 提交当前选中的行。
  • Project 始终将 Add a new project 固定在底部——当安装中还没有任何项目时,创建流程绝不会走进死胡同。
  • Run on 列出就绪的主机和 recipe,以及那些在该机器上仍需项目设置的主机。需要设置的行会显示诸如 Project not set up on this host 之类的细节;它们可见但在就绪之前不可选。已断开的 SSH / 远程主机可以提供 Connect,而无需将它们选为运行目标。Add host 会为 SSH 或 Remote DevAgent Server 目标保持固定。
  • Agent 选择器(折叠或展开状态)可以为你在创建时选择的 agent 执行 Set as default,包括 Blank Terminal。
  • 可从名称字段链接一个 GitHub PR、Linear issue、GitLab MR 或 Jira issue(粘贴 Jira URL 或在 Jira 模式下搜索)。已链接的 issue 会显示在 worktree 卡片上。见 Jira 条目抽屉。

见运行 DevAgent 的方式。

Emoji 工作区名称 ​

在工作区名称字段中,你可以输入 Slack 风格的短代码(:rocket:),并从短代码建议弹窗中选择。当你双击重命名一个 worktree、在 Edit Worktree Details 中编辑它,或在 Worktree 跳转面板(Cmd-J)中输入短代码时,同一个选择器都能用。显示名称会保留 emoji;当 DevAgent 派生 git 分支名时,它会把已知的 emoji 重写为可读的短代码(例如 🚀 → rocket)。跳转面板搜索会通过这个由短代码派生的片段来匹配以 emoji 命名的工作区。

命名分支 ​

默认情况下,DevAgent 会从你输入的工作区名称派生新 worktree 的分支名,或者当工作区是从某个链接的 GitHub PR、Linear/Jira issue 或 GitLab MR 创建时,从那个链接项派生。若要改为设置一个明确的分支名,请在创建 Worktree 对话框中展开 Advanced 抽屉,并在 Branch name 字段中输入(占位提示 feature/my-branch)。

当你从一个 Linear issue 创建时,DevAgent 会使用 Linear 自己为该 issue 提供的分支名(当 Linear 提供时)作为分支覆盖项——即 Linear 会在其 UI 中建议的同一名称——而不仅仅是将 issue 标题 slug 化。

只有当你从输入的工作区名称或一个基准分支创建时,才会提供 Branch name 字段。当工作区绑定到一个被跟踪的工作项时,分支会从该工作项派生——一个链接的 GitHub PR 甚至会在提交时重新解析分支——因此 DevAgent 会隐藏该字段,以避免一个被静默忽略的覆盖项。

侧边栏布局 ​

侧边栏默认按项目对 worktree 分组——顶层行是项目(一个项目 = 一个 git repo 或一组相关的集群),展开成你正在积极处理的 worktree。表头有自己的过滤输入框(与全局搜索分开),因此你可以在不离开侧边栏的情况下缩小列表。

侧边栏表头的过滤菜单将主机和项目范围归入一个共享的 Show 区块(Hosts 和各项目的子菜单行),然后是隐藏开关:

  • 休眠中的工作区 —— 每个项目的入口 / 主工作区在此过滤器下仍保持可见,这样当那个检出空闲时项目行不会消失
  • 除默认分支外(仅当 Hide sleeping 开启时)—— 在休眠清扫期间保持默认分支的工作区可见;当休眠工作区已经显示时,此子选项会被隐藏
  • 默认分支工作区(主检出行)
  • 自动化创建的工作区
  • CLI 创建的工作区 —— 通过 devagent worktree create 创建(悬停卡片可查看 DevAgent CLI 来源详情)
  • 其他客户端的工作区 —— 当某个共享的 Remote DevAgent Server 拥有从另一个配对客户端创建的工作区时,会出现 Hide other-client workspaces;打开它可让本设备的列表只保留你在此处创建的工作区。空 Cmd-J 最近项和数字快捷键遵循同一过滤器;输入查询后仍会找到隐藏的行。
  • 游离 HEAD工作区 —— 停在某个提交而非分支上的检出

活跃过滤器的数量会显示在过滤控件上;Clear 只会重置已开启的过滤器。一旦你输入查询,文本搜索和 Worktree 跳转面板(Cmd-J)仍能到达仅被这些过滤器隐藏的工作区——跳转面板还有自己的主机/项目过滤器(标签页)。

当你添加一个包含多个 Git repo 的父文件夹时,DevAgent 可以分别导入所选的 repo,或将它们归入一个项目组下。

侧边栏顶部的 Search 按钮会打开 Worktree 跳转面板(Cmd-J)——同一界面,为不依赖键盘导航的用户提供点击驱动的方式。状态栏内联显示 agent 活动;未读的 worktree 会加粗,而不是加徽章。

你可以将一个 worktree 固定到其项目的顶部,以便让长期运行的工作保持可见;右击一个 worktree 可显示归档 / 休眠 / 删除操作。点击时按住 Cmd(Linux/Windows 上为 Ctrl)可将 worktree 加入多选,或按住 Shift 选择一段连续范围——右击任一已选 worktree 会将该操作应用到选中的每一个 worktree。repo 行本身可以通过拖拽重新排序。

当一个 worktree 拥有嵌套的子 worktree 时(例如来自编排,或带父级的 worktree create),右键菜单还可以提供 Sleep with Descendants (N) 和 Delete with Descendants…。带后代一起休眠会关闭所选工作区以及同一项目、repo 和主机内每个已验证的嵌套子级上的活跃面板——只有拥有活跃终端或浏览器 标签页 的工作区才会成为休眠目标。带后代一起删除则让既有的级联删除变得明确。陈旧的血缘链接、循环,以及跨主机或 repo 边界的子级都会被排除。

在侧边栏中双击 worktree 标题可就地重命名它。双击卡片上的其他位置仍会打开完整的编辑对话框。在 Edit Worktree Details 中,issue 字段接受 GitHub 或 Linear(字段上有 chip;粘贴一个 URL 即可自动检测)。每个工作区一个链接的 issue——更改提供方或清空字段会解除对上一个的链接。对于主机已断开的 SSH 工作区,卡片标题行可以显示一个内联的重连控件(见 SSH worktree)。

被保留的分支 ​

批量删除工作区(侧边栏多选或 Resource Manager 清理)仍会移除磁盘上的文件夹。如果 git 因为某个本地分支可能包含未合并的提交而拒绝删除它,DevAgent 会保留这些分支并显示一个诸如 Review N Branches 的提示。打开它会列出被保留的分支,以便你强制删除其中一些、保留其他。未选中的分支会留在仓库中;工作区文件夹不会被恢复。

多 repo 项目组与文件夹工作区 ​

当你导入一个包含多个 Git repo 的父文件夹时,DevAgent 可以将这些 repo 归入侧边栏中单个项目组下。每个项目组都会暴露一个文件夹工作区流程——一个类似 worktree 的条目,存在于父文件夹层级,并将其任务来源绑定到下面某一个 repo 上,这样一个功能的 GitHub/GitLab/Linear/Jira 任务界面就能保持挂接到正确的 repo 上,即便工作区本身在侧边栏中与其同级项归为一组。

要创建一个,请在侧边栏中悬停项目组的表头行并点击 + 操作(工具提示:"Create workspace for group")。合成对话框("Create Folder Workspace")会要求你为工作区的任务来源选择源项目、命名工作区,并可选地附加一个链接的 issue 或 PR。提交后,文件夹工作区会与常规的 repo 范围 worktree 一起出现在项目组下。

删除一个项目组时,DevAgent 还会提供一个复选框,在同一操作中移除该组包含的项目(底层的 repo 注册)——这样清理一个不再使用的集群只需一次确认,而不是好几次。

使用原生 git ​

每个 DevAgent worktree 都是一个真实的 git worktree。你可以在其中打开终端并使用 git status、git rebase、git cherry-pick 以及任何其他命令——DevAgent 会在下次渲染时拾取这些更改。

你自己用 git worktree add 创建的 worktree 在你导入它们之前会保持为外部状态。如果 repo 隐藏了外部 worktree,DevAgent 会在 New externally-created worktrees 收件箱中显示新检测到的 worktree,以便你导入它们或让它们保持隐藏。

如果你从 CLI 执行 git worktree remove,DevAgent 会在下次刷新该 repo 时注意到并清理它自己的状态。

DevAgent 桌面客户端文档