仓库搬家后用Git修复智能体工作树
移动主仓库目录会使关联工作树中的绝对路径失效,导致Claude Code、Codex等任务目录无法正常执行Git命令。文章解释双向路径引用,并介绍用git worktree repair修复链接;原有提交和未提交修改仍在磁盘上。
AI 深度解读
挪一下项目目录,主仓库还能用,Claude Code、Codex 的工作目录却同时报错。原文给出的解释很具体:Git worktree 靠路径互相定位,目录搬走后,连接失效了,代码通常还在。修复入口是 git worktree repair。
这篇值得读的地方,是把「搬了什么、该在哪修、什么时候必须传路径」讲清楚了。它也提醒了两个容易误判的点:主仓库正常不代表所有 worktree 正常;相对路径能减少搬家故障,却有目录布局和工具兼容性的前提。
为什么主仓库正常,Agent 的目录却全坏了
关联工作树(linked worktree)不是完整复制一份仓库。它的顶层 .git 是文本文件,里面用 gitdir: 指向主仓库的 .git/worktrees/<name>。这个管理目录保存着该 worktree 自己的 HEAD 和索引(index),后者记录暂存区状态。
连接还有反方向:管理目录里的 gitdir 文件,指回工作目录中的 .git 文件。Git 会据此判断工作目录是否还存在。
默认情况下,这两个方向记录的都是绝对路径。
例如执行 mv ~/code/shop ~/code/store,原本指向 shop 的路径就过期了。具体坏在哪边,取决于搬动范围:
- 只搬主仓库,关联 worktree 的
.git指向旧地址,里面的 Git 命令会失败。 - 只搬关联 worktree,主仓库保存的反向地址过期,
git worktree list -v可能标记其为prunable,即具备清理条件。 - 把两者共同的父目录搬走,两个方向都可能失效。

原文给出的工具布局也解释了故障差异:Claude Code 的 --worktree 默认放在仓库内的 .claude/worktrees/<name>/,搬仓库通常会一起搬走;Codex app 则放在 $CODEX_HOME/worktrees,位于仓库外,搬主仓库时它们通常留在原处。
因此,同一次目录改名,对不同 Agent 可能触发不同的修复方式。
修复前先确认:到底搬走了哪些目录
作者用一个空提交和三个模拟任务复现问题:fix-login、tidy-auth、add-tests 分别对应 agent/$t 分支,worktree 建在主仓库旁边的 ../wt/ 下。随后把 shop 改名为 store。
此时在 wt/fix-login 中运行 git status 会失败,cat .git 仍能看到旧的 shop/.git/worktrees/fix-login。原文指出,Git 2.48 的错误以 fatal: not a git repository: 开头,Git 2.56.0 对应源码中的措辞则是 gitfile does not point to a valid repository。错误文字不同,检查方向相同。
只搬主仓库时,在新的主仓库位置运行下面这段即可恢复连接:
cd ~/scratch/wt-demo/store
git worktree repair
git -C ../wt/fix-login status
注意第二行的执行位置是主仓库;第三行用于确认关联 worktree 已能响应。
如果主仓库和关联 worktree 都换了位置,Git 无法凭空知道新地址,需要显式告诉它。作者把整个示例目录从 ~/scratch/wt-demo 搬到 ~/scratch/wt-moved 后,在新的主仓库中执行 git worktree repair ../wt/*,再用 git worktree list -v 检查。对于仓库内的 Claude Code 布局,对应路径通常是 .claude/worktrees/*,仍应以实际目录为准。
repair 会把修复信息输出到 stderr;原文提到的测试信息包括 gitdir incorrect 和 .git file incorrect。
这里最该记住的操作顺序是:
先修复连接,再考虑清理失效记录。
搬家之后出现的 prunable 不代表任务可以丢弃。先运行 git worktree prune,可能删掉 $GIT_DIR/worktrees 中仍然有用的管理记录,包括各 worktree 的 HEAD 和索引。原文还提醒,git gc 会按照 gc.worktreePruneExpire 清理过期记录,默认期限为三个月。
修复后的验证也应覆盖全部目录。原文通过 git worktree list --porcelain 提取路径,再逐个执行 git -C "$p" rev-parse --git-dir,以 ok 或 BAD 标识连接是否恢复。
相对路径能预防,但不是所有布局都适合
原文指出,Git 2.48 于 2025 年 1 月发布,开始支持用相对路径保存这两条连接。下面这段既开启配置,也转换已有 worktree:
git config worktree.useRelativePaths true
git worktree repair --relative-paths
关键是第二行。原文援引相关提交说明:即使旧路径仍然正确,repair --relative-paths 也会替换连接格式。
它适合主仓库与 worktree 一起移动的布局,例如 .claude/worktrees/,或把两者放在同一个父目录下整体搬迁。如果只把主仓库搬远,双方相对位置发生变化,相对路径同样会失效,仍要 repair。
兼容性有两层。
第一层是 Git。开启该设置会启用 extensions.relativeWorktrees,旧版 Git 遇到不认识的仓库扩展会拒绝操作。原文建议在所有访问该仓库的环境执行 git --version,包括 dev container、捆绑 Git 的 GUI 客户端和其他机器,确保版本至少为 2.48。
第二层是读取路径的上层工具。原文引用了一条 2026 年 2 月的问题报告:Claude Code 2.1.37 在 dev container 中开启相对路径后,claude -r 显示 No conversations found to resume。报告者追踪到的原因,是 git worktree list --porcelain 输出了 worktree ../../../my-repo-branch,工具却拿它与绝对工作目录直接比较;通过 session ID 恢复仍然可用。
该问题被作为更广泛恢复问题的重复项关闭,页面没有注明修复。作者也明确表示,不知道当前 Claude Code 是否仍受影响。报告者的绕行方式是把配置改回 false,再运行 git worktree repair 写回绝对路径。自己编写路径比较脚本时,也需要先把路径解析到一致形式。
我的判断
这篇最有价值的是故障模型清楚,操作可以复现。它提供的是「路径为何失效、如何修复」的解释,没有提供多团队对照数据,也没有证明相对路径适用于所有 Agent 工具链。
我会把相对路径视为一种有条件的配置选择:目录总是整体移动、Git 版本统一时,收益明确;多台机器、容器和 GUI 混用时,应先核对兼容性。
另一个边界是:Git 修好,不等于 Agent 会话也恢复。原文指出,Claude Code 的 --continue 按启动目录选择最近会话,搬家前的会话可能仍归在旧路径下。遇到 belongs to a different repository 或 is a leftover worktree,文档给出的处理还包括换一个 worktree 名称。
作者也推广了自己开发的 Hermes IDE,应把产品介绍与通用 Git 方法分开看。原文所述 Hermes 2.3.4 为每个任务创建 hermes/<name> 分支和普通 worktree,提供 Worktrees 页面;自 2.3.0 起可移除路径已不存在的项目,再通过 Open folder… 添加新位置。这些功能方便管理,但不改变 Git 的连接机制。它采用 BSL 1.1,不能把「源码可见」直接理解成没有许可证限制。
还有一个更直接的替代操作:如果只是主动移动单个关联 worktree,优先使用 git worktree move,它会更新连接。不过它不能移动主工作树,也不能移动包含 submodules 的 worktree。
能拿来做什么
- 给前端或 Node 项目改目录名前,先让 Agent 完成任务或停止运行,再用
git worktree list记录所有工作目录。原文特别提醒,macOS 和 Linux 上退出 Hermes 不会停止其 Agent。 - 搬家后按实际范围执行 repair:只搬主仓库,就在新位置运行
git worktree repair;关联 worktree 也搬了,就传入各自的新路径。随后逐个验证,避免只检查主仓库。 - 团队准备启用相对路径前,先检查开发机、容器和 GUI 使用的 Git 版本,再验证会话恢复是否正常。Git 命令成功与 Agent 能否找到旧会话,需要分别确认。
- 遇到搬家后的
prunable,先核对目录是否仍在。保留现场并修复连接,比立即运行清理命令更有助于保住暂存区和任务状态。