在同一份检出里同时跑两个编码智能体,你很快就会明白软件团队为什么要用分支。一个智能体正在给模块改名,另一个却拿改了一半的代码去跑测试。一个把另一个刚删掉的文件加进了暂存区。它们谁都没错,只是共用了一张桌子。
SuperDevSpace 会在同一个仓库里同时运行一个 manager 和多个 worker。本文介绍让它们彼此隔离的机制——git worktree——以及应用围绕它遵守的具体规则。
什么是 git worktree
一个 git 仓库通常只有一个工作目录。git worktree 让同一个仓库拥有多个工作目录,每个检出在自己的分支上,所有目录共享同一个对象库。没有第二个克隆,也没有第二份历史:新建一个 worktree 只占用一份检出的文件,别无其他。
你可以在任何仓库里手动试一试。命令在哪儿都一样,只是 shell 不同:
macOS / Linux
git worktree add -b agent/frontend-demo ../myrepo-frontend
git worktree list
cd ../myrepo-frontend && git status
cd - && git worktree remove ../myrepo-frontendWindows (PowerShell)
git worktree add -b agent/frontend-demo ..\myrepo-frontend
git worktree list
cd ..\myrepo-frontend; git status
cd ..\myrepo; git worktree remove ..\myrepo-frontend每个 worktree 都有自己的 HEAD、自己的索引和自己的文件。两个进程可以同时在两个 worktree 里编辑、构建和测试,互相看不到对方改到一半的内容。这正是一支智能体团队需要的特性。
SuperDevSpace 如何使用它们
规则很简单,对每个组织都一样:
- manager 在你的主检出里工作。 它负责规划、审查和合并;那是各分支汇合的唯一地方。
- 每个 worker 在自己的分支上拥有自己的 worktree。 manager 招聘 worker 时,应用会为它运行
git worktree add -b <branch> <path>。除非你自己命名,分支名为agent/<worker 名>-<时间戳>。 - worktree 存放在应用自己的数据目录里,位于
worktrees/<组织>/<worker>下,绝不放进你的仓库。你的项目文件夹不会被智能体的目录塞满。 - 每一轮都会提交。 worker 完成一轮后,应用会把它 worktree 里的所有改动提交(
agent(<name>): turn)。worker 做过的任何事,都不会只停留在未提交的工作目录里。 - 合并采用 squash merge。 manager 接受某个 worker 的报告后,分支会通过
git merge --squash以一个提交并入你的主线。如果合并冲突,应用会中止合并,把仓库恢复干净以便下一步操作,而不是把你丢在冲突的合并中间。 - 每个仓库同一时间只执行一个 git 操作。 worktree 目录隔离了文件;每个仓库一条队列,把 git 命令本身串行化,所以两个 worker 同时完成时,也不会争抢 git 的元数据。
以文本查看图表
gitGraph
commit id: "main"
branch agent/frontend
commit id: "frontend: 第 1 轮"
checkout main
branch agent/qa
commit id: "qa: 第 1 轮"
checkout agent/frontend
commit id: "frontend: 第 2 轮"
checkout main
merge agent/frontend id: "squash: frontend"
merge agent/qa id: "squash: qa"在看板上,这表现为几项任务同时在推进,每项属于不同的 worker,每项下面都有自己的分支。

让它真正好用的细节
新建的 worktree 只包含 git 跟踪的文件。这通常不足以把项目跑起来:node_modules、本地的 .env、生成的文件都没有。下面两个细节解决了这个问题。
每个仓库一个初始化脚本
如果你的仓库里有 .super/scripts/setup-worktree.sh,应用会在 worker 启动前,在每个新 worktree 里运行它,并用 SUPERDEV_MAIN_REPO 指向你的主检出。它的输出会实时显示,漫长的安装不再是盲等,而且你可以随时取消。
#!/usr/bin/env bash
set -euo pipefail
# 从主检出复制仅存在于本地的文件
cp "$SUPERDEV_MAIN_REPO/.env" .env 2>/dev/null || true
# 安装依赖(pnpm 从共享存储建立链接,所以很快)
pnpm install --frozen-lockfile子模块
git worktree add 不会填充子模块。如果新 worktree 里有 .gitmodules 文件,应用会在其中运行 git submodule update --init --recursive,避免 worker 在悄悄缺失依赖的情况下构建。
清理时不丢失工作
worktree 会越积越多。应用会回收它们,但非常谨慎:
以文本查看图表
flowchart TD
start["worker 已完成"] --> clean{"工作区干净吗?"}
clean -->|"否"| keep["保留 worktree"]
clean -->|"是"| merged{"分支已并入你的主线?"}
merged -->|"否"| keep
merged -->|"是"| remove["删除 worktree"]有未提交改动的 worktree,或者其分支上还有尚未进入你主线的工作,都会原样保留。删掉的文件夹可以重建,丢掉的工作却回不来。对分支也一样谨慎:应用会记录自己创建的分支,并且只动这些分支。
这对你意味着什么
每个 worker 都有自己的分支之后,"同时跑四个智能体"就不再是一场赌博。你可以:
- 给 manager 一条能拆成独立任务的指令,让 worker 们并行工作;
- 单独阅读任何一个 worker 的 diff,旁边就是产生它的对话;
- 拒绝某个 worker 的改动,而不影响其他人;
- 团队工作时,你自己照常使用主检出。
这和人类团队遵守的纪律是一样的,只是用在了那些不会提醒你"我们快踩到对方脚了"的智能体身上。如果你好奇我们为什么要围绕这件事做一整个应用,第一篇文章讲了这个故事。
试一试
14 天试用为 Premium,无需绑卡。下载 SuperDevSpace,把一个新组织指向某个仓库,看着 manager 招聘第一批 worker 时一个个 worktree 随之出现。