教程2026-10-30 · 智涌AI

并行 Coding Agent 时 git worktree 怎么清理才安全

Git worktree 卫生教程头图:终端展示 list、祖先检查、status 与 remove/prune

并行跑多个 Coding Agent 时,常见做法是给每个任务开一个 git worktree,避免抢同一工作区。任务合完之后,如果不清 worktree,磁盘和分支会堆成垃圾场;清错了——尤其在脏树上 --force,或在即将删除的 worktree 里删自己——又会丢掉未提交改动。下面按 Git 官方 git-worktree 文档,整理一套可复制的卫生流程:何时可 reap、prune 和 remove 差在哪、审批门放哪里。

前置条件:本机 Git 支持 worktree(Git 2.5+ 起有;请用较新版本)。已有一个主克隆,并会用 git worktree add 开并行目录。下面命令在主 worktree 或任意仍保留的 linked worktree 里执行均可,但删除某个 worktree 时,不要站在那个即将被删的目录里操作。

Worktree 在官方文档里是什么

一个仓库可以挂多棵工作树:主 worktree 由 clone/init 得到,其余用 git worktree add 挂上,称为 linked worktree。它们共享同一份对象库,但各有自己的 HEAD、索引与未提交改动。用完 linked worktree 后,文档要求用 git worktree remove 拆除;若有人只删了目录、没走命令,仓库里 $GIT_DIR/worktrees 下的管理文件会变成陈旧项,之后靠 git worktree prune(或 gc 相关过期配置)清掉。

# 新建:常见是新分支名取路径最后一段
git worktree add ../hotfix-login

# 已有分支接到新目录
git worktree add ../review-pr-123 feature/login

# 一次性试验、不建分支
git worktree add -d ../scratch-try

分步一:先列表,再决定谁能删

清理脚本的第一步不是 remove,是把清单打成机器可读格式:

git worktree list --porcelain
# 建议再加 -z,路径含换行时更安全
git worktree list --porcelain -z

Porcelain 输出里,每棵树以 worktree <path> 开头,空行结束一条记录;可见 HEAD、branch、detached、locked、prunable 等字段。人眼查看可用默认表格;脚本只解析 porcelain,避免被列宽与注释打乱。

可 reap 的经验条件(需同时满足,再进入审批):

  1. 该 worktree 对应的主题分支(或其上的提交)已经合入保护分支(如 main)。
  2. 工作区干净:无已跟踪文件修改、无未跟踪文件(与 git worktree remove 默认要求一致)。
  3. 未被 lock(便携盘、网络盘上的树常会 lock,强删前要先确认)。

「已合入」可用祖先检查(在主仓库执行,把 WT_HEAD 换成该 worktree 的 HEAD 提交):

# 若 WT_HEAD 已是 main 的祖先,说明其提交已在 main 历史上
git merge-base --is-ancestor "$WT_HEAD" main && echo "merged-into-main"

merge-base --is-ancestor A B 在 A 是 B 的祖先时退出码为 0。注意:若合入用了 squash,主题分支尖端可能不是 main 的祖先,需要改用 PR 状态、cherry 等价检测或「分支已删除且 PR merged」等你们仓库约定的信号,不能只靠这一条。

分步二:remove 掉干净树;脏树先停手

官方语义很干脆:

# 推荐:只删确认干净且已合入的
git worktree remove /path/to/linked-wt

# 危险:丢弃该树上所有未提交改动与未跟踪文件
# git worktree remove --force /path/to/linked-wt

对 Coding Agent 自动收尾时,默认策略应是:脏树一律跳过并告警,不要替人 --force。Agent 常在树上留下实验文件、失败半截的补丁;强制删除等于静默扔掉证据。

可 reap ≠ 可 force。合入只说明历史已进主线;工作区脏,仍然可能有你还没提交的修复。

分步三:prune 清的是「管理信息」,不是替代 remove

有人习惯 rm -rf ../old-wt,目录没了,但 $GIT_DIR/worktrees/<id> 还在。这时:

git worktree prune -n -v          # dry-run:只报告
git worktree prune -v             # 真正删掉陈旧管理项
git worktree prune --expire 1day  # 只处理超过时效的缺失树

prune 的对象是「工作树目录已经不存在」的管理条目;它不会帮你安全地拆掉一棵还在磁盘上的干净 linked worktree——那是 remove 的工作。文档也写了:下次请用 remove,别再只删目录。

若 worktree 被挪走过,优先 git worktree repair 重连,而不是 prune 掉再重建。

分步四:从主 checkout 清理,别在「自杀目录」里删自己

操作顺序建议固定:

  1. cd 到主 worktree(或另一棵不会被删的树)。
  2. git worktree list --porcelain 解析候选。
  3. 对每个候选:检查合入信号 → git -C <path> status --porcelain 确认干净 → 人工或规则审批 → git worktree remove <path>。
  4. 最后 git worktree prune -n 看是否还有陈旧项。
# 示例:在主库检查某 linked 树是否干净
git -C /path/to/linked-wt status --porcelain
# 无输出 ⇒ 对 remove 而言通常可视作干净(仍须避开 submodule 等特殊情况)

在即将删除的 worktree 内执行 remove,轻则命令失败,重则当前 shell 的 cwd 已失效,后续脚本继续写文件会写到「已消失的路径」上。Agent 自动化尤其容易踩这个坑:任务结束时 cwd 往往就在该 worktree 里。

分步五:加审批门,再交给脚本

并行 Agent 一多,收尾脚本会变成高权限工具。最低审批门可以是:

与 AGENTS.md / 仓库规范配合时,把上述条件写成明文规则,让 Agent 在「任务完成」钩子里只提议 reap,不自行 --force。也可对照 Coding Agent 团队实践 里的收尾习惯。

常见坑

完成标准

最后

Worktree 让 Agent 并行变得便宜;卫生流程让并行不至于变成仓库负债。先把 list --porcelain 和「脏树不 force」写成团队默认,再谈自动 reap。需要对照命令细节时,直接打开 Git 官方 git-worktree 页,以你本机 git version 对应的行为为准。

关注公众号「智涌AI速递」

每天的 AI 快讯、实用教程和 AI项目实测,也会同步发到微信公众号。在微信里搜索「智涌AI速递」就能关注;不用微信的话,可以用 RSS 订阅本站。