三个 Agent 同时改一个仓库,代码互相覆盖:Worktrunk 把 git worktree 变成切分支一样简单,9 千星

三个 Agent 同时改一个仓库,代码互相覆盖:Worktrunk 把 git worktree 变成切分支一样简单,9 千星

三个 Agent 同时改一个仓库,代码互相覆盖:Worktrunk 把 git worktree 变成切分支一样简单,9 千星 封面

你开了三个 Agent。一个写登录,一个修分页,一个补测试。都很努力。四十分钟后回来验收,登录写好了,分页的改动没了,测试写在了三天前的旧代码上。

没有谁犯错。它们只是挤在同一个目录里,读写同一批文件,最后提交的是最后一个动手的那个。

这不是模型的锅。Worktrunk 的 README 里就有一句:无人值守跑长任务已经很常见,”manage 5-10+ in parallel” 是可能的。卡住你的不是模型不够聪明,是它们没有一个各自的房间。

为什么要同时开这么多?因为任务本来就能拆。站内这篇 Codex 多智能体 V2 讲得很清楚:主 Agent 当包工头,便宜模型干执行。手越多,越需要各自有块地方站着。

git worktree 早就把答案给了你

git 其实早就给了答案,叫 worktree。一个仓库,多个工作目录,共享同一份 .git,每个目录挂着自己的分支。三个 Agent 各占一个目录,冲突从物理层面消失。

它比多 clone 几份聪明在共享:历史只有一份,不用重复下载。开第五个目录的成本和开第一个差不多。

但现实中没几个人这么用。大家要么让一群 Agent 继续抢同一个目录,赌它们改的文件不重叠;要么自己切到别的分支去看代码,结果往往更惨:Agent 不会跟着你切,你一 checkout,它脚下的世界就塌了,接下来半小时的产出全是幻觉。

赌赢了省事,赌输了就是开头那一幕。

那为什么一直没人用

因为原生 worktree 的交互太糙。开一个新工作区,分支名要打三遍:

git worktree add -b feature-auth ../repo.feature-auth
cd ../repo.feature-auth

一次在 -b 后面,一次在路径里,一次在 cd 里。用完还要清两次。想知道每个工作区跑到哪了,git worktree list 只给路径和分支名,没有 diff,没有领先落后,你还是得一个一个 cd 进去看。

单看每一步都不难,加在一起就没人愿意碰。于是大家算完这笔账,又回到那个赌局里去了。

每个分支一块独立目录:Worktrunk 让路径由模板算出来
每个分支一块独立目录:Worktrunk 让路径由模板算出来

先装上,别忘了那一步 shell 集成

Worktrunk 是 Rust 写的,仓库在 max-sixty/worktrunk,官网 worktrunk.dev。安装就一行命令,按环境挑一条:

# macOS & Linux(Homebrew)
brew install worktrunk && wt config shell install

# 有 Rust 工具链
cargo install worktrunk && wt config shell install

# Windows(wt 与 Windows Terminal 撞名,用 git-wt)
winget install max-sixty.worktrunk
git-wt config shell install

Arch 用 sudo pacman -S worktrunk,conda 与 pixi 也各有源,装完同样补一句 wt config shell install。

那半句 shell 集成不是可选项。不装的话,wt 只是个普通二进制,改不了当前 shell 的目录,wt switch 把 worktree 建出来了,你的终端还留在原地,等于白切。

三个命令:switch、list、merge

核心思路很短:按分支名寻址 worktree,路径由模板算出来。你只说分支名,目录放哪、叫什么,它替你决定:

wt switch --create feature-auth
✓ Created branch feature-auth from main and worktree @ ~/repo.feature-auth

建分支、建 worktree、切进去,一条命令。路径由模板算还有个更值钱的副作用:你永远知道该去哪找它,写脚本、配 IDE 都不用先查。

第二个命令 wt list,把各处进度摆到一张表上:Branch、Status、HEAD±、main↕、Remote⇅、Commit、Age、Message。@ 是当前工作区,+ 有暂存改动,↑1 领先 main 一个提交,⇡ 有没推送的提交。开十个 Agent 时这张表就是仪表盘。

第三个命令 wt merge main,一条干完五件事:LLM 生成提交信息、提交、rebase、fast-forward 合并、后台把 worktree 和分支一起删掉,最后切回 main。原生 git 里这是五条命令加两次清理。

和原生 git 的差距,三行就说完:

开新工作区  git: worktree add -b feat ../repo.feat + cd   wt: wt switch --create feat
看进度      git: worktree list 只有路径                    wt: wt list 带 diff 和 CI
合并清理    git: 五条命令分两次清                          wt: wt merge main

真正的用法:一条命令开一个 Agent

最实用的姿势是官方文档里这段示例,原样照抄:

wt switch -x claude -c feature-a -- 'Add user authentication'
wt switch -x claude -c feature-b -- 'Fix the pagination bug'
wt switch -x claude -c feature-c -- 'Write tests for the API'

-c 建分支,-x 表示切过去之后执行后面的命令,– 之后的参数原样传给它。三条跑完,你有三个目录、三个分支、三个已经开始干活的 Agent。而且 -x 不绑任何一家,今天 claude,明天 codex,格式都一样。

三条都跑起来后,wt list 的另一半价值才显现:它告诉你该先管哪一个。Age 那列显示某分支二十分钟没动静,多半是那个 Agent 卡住了,先去救它。并行的难点不是开得多,是知道哪个快烂尾。

一个人调度多个 Agent 早就不科幻。站内这篇 千问 Agent Teams 在做类似的事:AI 组个剧组,导演、摄影、剪辑各司其职。Worktrunk 补的是更下面那层,让每个角色有独立工位。

上不上这套,判断很简单。如果你的 Agent 一跑十几分钟不吭声,这种开法最划算;只是问两句就结束的任务,直接开个目录反而更轻。

从建分支到合并清理,整条流水线压进一条命令
从建分支到合并清理,整条流水线压进一条命令

让它自己干完:hooks 的十个节点

开三个 Agent 只是开始。每个新 worktree 都是空的,依赖没装,dev server 没起。这些活还得你手动做,并行就又退回串行了。

hooks 覆盖十个节点:pre-switch、post-switch、pre-start、post-start、pre-commit、post-commit、pre-merge、post-merge、pre-remove、post-remove。规则很好记:pre-* 阻塞,失败即中止;post-* 后台跑,输出写日志。

官方文档的建议很明确:创建阶段最常用的是 post-start。装依赖、起 dev server、跑长构建都该挂在后台。除非后面步骤必须等它完成,否则别用 pre-start,白等的时间就是你被吃掉的时间。

还有一个细节:十个 worktree 起十个 dev server,必然抢同一个 3000 端口。模板过滤器 hash_port 给每个 worktree 算一个唯一端口:

echo 'PORT={{ branch | hash_port }}' > .env.local

pre-merge 是天然的测试关卡,跑不过就合不进去,因为 pre-* 阻塞、失败即中止。质量门放在合并前,比事后回滚便宜得多。

从提交到合并:那条流水线,以及安全边界

安全上有道闸门值得单独说。项目级 hooks 第一次运行要人工批准:

▲ repo needs approval to execute 3 commands:
○ pre-start install: npm ci
○ pre-start build: cargo build --release
○ pre-start env: echo 'PORT={{ branch | hash_port }}' > .env.local
❯ Allow and remember? [y/N]

批准记录存在 ~/.config/worktrunk/approvals.toml,命令一改就要重新批准;拒绝则跳过该项目本次所有命令。CI 里可用 –yes 跳过,或 –no-hooks 整个跳过。要警惕的是批准记住后长期有效,克隆来路不明的仓库带一堆项目级 hook 时,按 y 之前请逐条读完。

收尾也有流水线。走 PR 的顺序是 wt step commit、gh pr create、wt remove;本地合并一条 wt merge main 收工。想看每条分支的 CI 状态和 AI 摘要用 wt list –full,去某个 PR 上看看就 wt switch pr:123。

工程化做到这个密度,省下的不只是命令,还有上下文。Pi 1.0 把工具藏起来、把提示词开销压掉 40% 的思路,和这里是同一件事:让 Agent 少操心环境,把注意力留给真正的任务。

还有个容易忽略的点:十个 worktree 各装一份 node_modules,时间和磁盘都是十倍。wt step copy-ignored 用写时复制,把 target/、node_modules/ 分给十个 worktree,只占一份空间。

别急着 All in:它还没到 1.0

说点劝退的话。

最新版本 v0.80.0,发布于 2026 年 9 月 27 日。GitHub 上 9,238 星、332 fork、61 个 open issues(2026 年 10 月 15 日查得)。建库 2025 年 10 月,最近一次 push 是 2026 年 10 月 15 日,项目还在推进。但 0.x 就是 0.x,命令行为随时可能变,别把它焊进核心脚本。

README 里那句”年初发布,已 quickly become the most popular git worktree manager”,是作者自己的说法,不是第三方排名,请自带折扣。

许可也要留意。README 徽标写的是 MIT OR Apache-2.0 的双许可标注,GitHub 的 license 字段却没识别成标准 SPDX。公司要用,先让法务看一眼。

copy-ignored 也不是万能的。写时复制只在 APFS、btrfs、XFS 上生效,用这三种之外的文件系统,这部分收益直接归零。

回到那三个 Agent

它们互相覆盖,原因不在模型,在你只给了它们一个房间。

多 Agent 的瓶颈从来不在模型那一层,在目录那一层。模型会越来越聪明,目录冲突不会自己消失,它是个工程问题,得用工程手段解。

Worktrunk 做的事很朴素:把开一个工作区的成本压到和切分支一样低。装它一行命令,日常记住 wt switch、wt list、wt merge 三个词,剩下的交给模板和 hooks。

三个 Agent 各进各的房间,四十分钟后回来,三份改动都在,提交信息还是它自己写的。

关注圈圈,持续带你玩转 AI 工具。

© 版权声明
THE END
喜欢就支持一下吧
点赞62 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容