第十五篇:多分支并行——Git Worktrees 工作区
Hermes Agent 官方教程第十五篇:用 Git Worktrees 让多个 AI 在同一个项目里并行干活。
这篇讲的是:如何用 Git Worktrees 给每个 Hermes 智能体一个独立的“工位”,让它们在同一项目里并行干活互不干扰。
你是不是遇到过这种情况:同一个项目,想同时跑两个实验——一个重构代码,一个修 bug,结果两个智能体在同一个文件夹里改来改去,互相覆盖文件,乱成一锅粥?
Git Worktrees 就是解决这个问题的“分房间”工具。它让你从同一个仓库里“变”出多个独立的文件夹,每个文件夹都有自己的分支和文件副本,就像给每个智能体分配了一间单独的办公室,各干各的,互不打扰。
第1步:创建一个 Worktree(新工位)
假设你的项目在 /path/to/your/repo,打开终端,输入:
cd /path/to/your/repo
git worktree add ../repo-feature feature/hermes-experiment
这条命令会做两件事:
- 在仓库外面新建一个文件夹
../repo-feature - 在里面创建一个新分支
feature/hermes-experiment
现在,你有了一个全新的、干净的“工位”。
第2步:在 Worktree 里启动 Hermes
cd ../repo-feature
hermes
Hermes 会把 ../repo-feature 当作项目根目录,所有文件修改、工具调用都在这个文件夹里进行。它的回滚历史(/rollback)也是独立的,不会影响主仓库。
第3步:并行运行多个智能体
想同时跑两个实验?再建一个工位:
git worktree add ../repo-experiment-b feature/hermes-b
然后开两个终端:
# 终端1
cd ../repo-experiment-a
hermes
# 终端2
cd ../repo-experiment-b
hermes
两个智能体各干各的,一个改 feature/hermes-a,一个改 feature/hermes-b,互不干扰。非常适合批量重构、对比不同方案。
第4步:干完活,清理工位
实验结束,把分支合并回主分支后,清理工位:
cd /path/to/your/repo
git worktree remove ../repo-feature
注意:如果有未提交的改动,Git 会拒绝删除,除非你强制(--force)。删除工位不会自动删除分支,分支可以留着做参考。
偷懒技巧:hermes -w 自动工位模式
不想手动建工位?Hermes 自带 -w 参数,自动帮你创建临时工位:
cd /path/to/your/repo
hermes -w
它会自动在 .worktrees/ 下建一个临时文件夹,开一个独立分支,跑完即走。交互式会话退出时,如果工位里有未提交的改动或未推送的提交,Hermes 会问你:保留工位(默认,回车/Esc 也是这个)、归档并删除(完整工作状态先归档再删除,并打印 hermes worktree restore 命令)、删除并丢弃改动(只有你明确选择才会执行)。单次运行(-q、-z)、cron 任务、网关会话等没有终端的退出不会询问,工位会保留,交给之后的过期工位清理处理;干净且提交已推送的工位则直接删除。配合单次查询:
hermes -w -z "修复 issue #123"
并行跑多个智能体?每个终端都执行 hermes -w,自动各得一个独立工位,省心省力。
过期工位清理与恢复
Hermes 会把创建过工位的仓库记录在 <HERMES_HOME>/worktree_repos.json 里。每次 hermes -w 启动时以及 cron 每 6 小时,都会清扫这些仓库的 .worktrees/:闲置超过时限(hermes-*/subagent-* 24 小时,命名工位 72 小时)且干净、已合并或已推送的工位会被删除;有未提交改动或未推送提交的会先归档再删除;有活跃进程占用、近期有文件/HEAD/reflog 活动、看板任务工位(t_<hex>)、含子模块或内嵌仓库、只被 per-worktree ref 持有的提交、以及超过 worktrees.archive_max_file_mb 的未跟踪文件,都会被保留。被忽略的文件(如 .env 副本、缓存、构建产物)不会归档,会随工位一起删除。
归档是一个存放在 refs/hermes/archive/<tree> 的提交,包含工位的 HEAD、暂存改动、未暂存改动和未跟踪文件(.gitignore 排除的文件不捕获)。常用命令:
hermes worktree list # 列出工位和归档(名称、年龄、分支、原因)
hermes worktree prune --dry-run # 查看每个归档/删除/跳过决定及原因,不做任何改动
hermes worktree restore lane-x # 重建 .worktrees/lane-x 及其分支、暂存和未跟踪文件
hermes worktree restore lane-x --path ../lane-x-review
超过 worktrees.archive_retention_days 的归档会被清扫删除。相关配置:
worktrees:
archive_dirty: true # false = 永不删除有改动/未推送的工位(旧行为)
archive_max_file_mb: 50 # 超过此大小的未跟踪文件不归档,其工位保留
archive_retention_days: 30 # 0 表示永久保留归档
注意:工位里的 Git 配置是“干净”的
Hermes 检出工位时,不会运行仓库自己的 Git 配置——也就是说,仓库里设置的 hooks、core.fsmonitor、以及 clean/smudge 过滤器,在这个工位里统统不生效。Hermes 为看板任务和子智能体创建的工位,也是同样的处理方式。
这带来一个实际影响:如果你的仓库用 Git LFS 存放大文件,工位里拿到的只是 LFS 指针文件(不是真实内容)。如果这次会话需要用到这些文件的真实内容,进工位后手动拉一下:
git lfs pull
最佳实践小结
- 一个实验一个工位:每个大改动建独立分支,PR 小而清晰
- 频繁提交:用 git 记录里程碑,用
/rollback兜底工具误操作 - 别在裸仓库根目录跑 Hermes:用工位目录,职责分明
- 用 LFS 的仓库记得
git lfs pull:否则工位里只有指针文件
总结:Git Worktrees 就是给每个智能体一间独立办公室——独立分支、独立文件、独立回滚历史,并行干活不打架。配合 hermes -w 自动模式,更是零门槛上手。
下篇预告:智能体跑完活,怎么把成果安全地合并回主分支?下一篇我们聊聊 分支合并与冲突解决,敬请期待!
📖 官方文档
本文根据 Hermes Agent 官方文档编写,原文见:官方文档 › user-guide/git-worktrees