Git Worktree / Worktrunk:并行 AI 开发工作流实战

作者:RickeyBoy日期:2026/3/9

最近在日常开发中尝试了用 Git Worktree (Worktrunk) 配合 Claude Code 进行并行开发,体验下来效果非常好。这篇文章就来分享一下这套工作流的搭建和使用经验,希望能对大家有点帮助~

欢迎大家点个 star:Github以及下载我的独立 app: iColors

一、为什么需要 Git Worktree

先说一个日常开发中很常见的场景:你正在开发一个新功能,突然来了一个紧急 bug 需要修复。通常你要么 git stash,要么 git commit 一个半成品,切换分支去修 bug,改完再切回来。

这个过程不仅繁琐,而且一旦涉及到 AI 辅助开发(比如 Claude Code),问题就更大了——每个 Claude 会话的上下文会因为切换分支而断掉。

Git Worktree 就是为了解决这个问题的。简单来说,它允许一个 Git 仓库拥有多个工作目录,每个目录检出不同的分支:

1my-project/            # 主仓库,develop 分支
2my-project.feature-A/  # worktree,feature-A 分支
3my-project.feature-B/  # worktree,feature-B 分支
4my-project.bugfix/     # worktree,bugfix 分支
5

核心优势:

  • 不需要多次克隆仓库,所有 worktree 共享同一个 .git 数据库
  • 多个分支同时活跃,互不干扰
  • 磁盘空间省得多,不像 clone 那样每次都复制整个 git 历史

二、Worktree vs Clone:到底省了什么

可能有同学会问:我直接 clone 多份不也行吗?

当然可以,不过在回答这个问题之前,我们先看看一个 Git 仓库到底包含了哪些东西。

.git 目录里有什么

当你 git clone 一个仓库,实际上拿到的是两部分:工作目录(你能看到的源代码文件)和 .git 目录(Git 的"数据库")。

.git 目录里主要包含这些内容:

目录/文件作用说明
objects/对象数据库存储所有的 commit、tree、blob 对象,经过压缩打包后放在 objects/pack/ 中。这是 Git 历史的核心
refs/引用分支指针(refs/heads/)、标签(refs/tags/)、远程跟踪(refs/remotes/)
logs/操作日志记录 HEAD 和各分支的变更历史(reflog)
hooks/钩子脚本pre-commit、pre-push 等自动化脚本
lfs/大文件存储如果项目使用了 Git LFS,大文件(图片、二进制等)会缓存在这里
index暂存区记录当前 staged 的文件状态
HEAD当前指针指向当前检出的分支或 commit
config仓库配置remote 地址、分支追踪关系等

实际项目的占比

那这些东西到底占多大空间呢?我用我的一个 iOS 项目跑了一下:

1.git 目录总大小:4.2 GB
2├── lfs/       3.4 GB  (81%)   大文件缓存(图片、字体等)
3├── objects/   761 MB  (18%)   所有历史 commit 的压缩包
4├── logs/      1.3 MB  (<1%)
5├── refs/      196 KB  (<1%)
6├── hooks/      88 KB  (<1%)
7└── 其他        ~2 MB  (<1%)
8

可以看到,.git 里面大头是两块:LFS 大文件缓存objects 对象数据库,两者加起来占了 99% 以上。

不过这里说的"工作目录"可不只是源代码。我实际看了一下手边这个项目的空间分布:

1仓库总大小:82 GB
2├── .git/         4.2 GB    Git 数据库
3├── .spmCache/    4.9 GB    SPM 依赖缓存
4├── Features/      56 GB    功能模块(含 SPM .build 缓存)
5├── Core/          16 GB    核心模块(含 SPM .build 缓存)
6├── fastlane/     320 MB
7└── 其他           ~1 GB    纯源码、配置文件等
8

好家伙,56 GB 的 Features 目录?点进去一看,每个模块下面都有一个巨大的 .build/ 目录——这是 SPM resolve 之后生成的本地构建缓存。比如其中一个模块,源码才 208 KB,但 .build 有 7.3 GB。

简单来说,这 82 GB 的构成是这样的:

类别大小说明
纯源码 + 配置~1 GB真正的代码文件
SPM 构建缓存~72 GB每个模块的 .build/ + .spmCache/
Git 数据库~4.2 GB.git/ 目录
其他(fastlane 等)~4.8 GB工具链、脚本

Clone vs Worktree 对比

那么问题来了,如果我需要 4 个分支同时工作。

纯净状态下(刚创建、还没编译),一个 worktree 只有约 1 GB(纯源码)。这时候对比非常夸张:

方案4 个分支并行说明
Clone × 4~328 GB每份都要完整下载 .git + 全部文件
Worktree × 4(纯净)~85 GB主仓库 82 GB + worktree 源码 1 GB × 3

差距很明显。而且 clone 还有一个隐性成本:每次都要重新下载整个 Git 历史,网络慢的时候能等很久。Worktree 是本地秒创建的。

编译后空间会膨胀吗

不过需要注意的是,如果你在 worktree 中运行了 app(执行了编译),空间会显著增长。主要来自两部分:

1. SPM 构建缓存(在项目目录内)

每个 worktree 执行 SPM resolve 和编译后,会在各模块下生成独立的 .build/ 目录。以我的项目为例,这部分加起来就有 70+ GB。这个缓存是不共享的,每个 worktree 都会生成自己的一份。

2. Xcode DerivedData(在全局目录)

好消息是,Xcode 的 DerivedData 默认存放在 ~/Library/Developer/Xcode/DerivedData/,不在项目目录内,所以不会直接撑大 worktree 文件夹。但每个 worktree 编译后会在 DerivedData 里新增一个条目——我看了下我的 DerivedData 总共 37 GB。

所以实际使用中的空间大概是这样:

场景每个 worktree 大小
刚创建(纯源码)~1 GB
resolve 了 SPM 依赖~5 GB
完整编译运行过~70+ GB

如果你只是用 Claude Agent 写代码、不需要在每个 worktree 里都编译运行,那空间占用是很小的。只在需要验证的 worktree 中编译就好,不必每个都跑一遍。

说实话,如果每个 worktree 都跑一遍完整编译,那空间上的优势就没那么大了——省下的只是 .git 数据库的重复(4.2 GB × N),相比 70+ GB 的构建缓存,这点节省确实不算大。

那 worktree 的核心优势到底在哪?其实是创建速度和工作流

  • 秒级创建:不需要重新 clone、不需要等网络下载,本地一行命令就搞定
  • Git 状态天然隔离:每个 worktree 有独立的 HEAD、暂存区、工作目录,分支切换零成本
  • 按需编译:大部分 worktree 只写代码(~1 GB),只在需要验证的那个里编译就好

合理的做法是:大部分 worktree 只写代码,选一两个去编译验证。这样既享受了并行开发的便利,又不会把磁盘撑爆。

三、Claude Agent 并行开发

好了,这才是重头戏。有了 Worktree,跑多个 Claude Agent 就变得非常自然:

1终端标签页 1  my-project.feature-A/  claude
2终端标签页 2  my-project.feature-B/  claude
3终端标签页 3  my-project.bugfix/     claude
4

每个标签页里的 Claude:

  • 在独立的工作目录中操作
  • 提交到各自的分支
  • 完全不会互相影响

这样你就可以让一个 Claude 做功能 A,另一个做功能 B,第三个修 bug,三件事同时推进。每个 Agent 的上下文都是干净的,不会因为别的任务搞乱文件状态。

四、Worktree 管理工具:Worktrunk

手动管理 worktree 的命令其实挺繁琐的,正常流程你得这样:

1git worktree add ../my-project.feature-A develop -b feature-A
2cd ../my-project.feature-A
3

每次都要敲这么一长串,分支名还得写两遍,确实不太优雅。

推荐使用 Worktrunk(命令行工具名为 wt),它是一个用 Rust 写的 worktree 管理器,专门为并行 AI 开发设计的。用起来就一行:

1wt switch -c feature-A
2

这条命令会自动帮你:

  1. 基于当前分支创建新分支 feature-A
  2. 在主仓库的同级目录下创建 worktree
  3. 切换到新的工作目录

执行完之后,你的目录结构就变成了这样:

1~/Projects/
2├── my-project/            # 主仓库(你执行命令的地方)
3   ├── .git/              # 完整的 Git 数据库
4   ├── src/
5   └── ...
6├── my-project.feature-A/  # 新创建的 worktree
7   ├── .git               # 注意:这里只是一个文件,指向主仓库的 .git
8   ├── src/               # 完整的工作目录副本
9   └── ...
10└── my-project.feature-B/  # 另一个 worktree(如果你再创建一个的话)
11    ├── .git
12    ├── src/
13    └── ...
14

注意看 worktree 目录下的 .git——它不是一个目录,而是一个文件,内容就一行指向主仓库 .git 的路径。这就是 worktree 能共享 Git 数据库的原理。

你还可以搭配 Claude Code 一起用(但其实没必要):

1wt switch -x claude -c feature-A -- '实现功能 A'
2

这条命令会创建 worktree 之后自动启动 Claude,并把任务描述传给它。

五、实际开发流程

我目前的开发流程大概是这样的:

第一步:创建 worktree

1wt switch -c feature-A
2wt switch -c feature-B
3wt switch -c bugfix
4

第二步:在各个 worktree 中启动 Claude

每个终端标签页进入对应的 worktree 目录,然后启动 claude

第三步:并行工作

三个标签页同时推进,互不干扰。想看哪个任务的进度就切到对应的标签页。

第四步:完成后合并

每个 Agent 完成任务后,正常走 PR 流程合并回主分支就行。

第五步:清理不必要分支

清理用完的 worktree,节省空间,具体方式可以看后续。

六、用完之后怎么清理

Worktree 用完不清理,时间一长目录就会越积越多。正确的清理姿势分两步:

1. 删除 worktree

用 git 命令删除

1git worktree remove ../my-project.feature-A
2

这条命令会同时做两件事:

  • 删除 worktree 对应的目录(my-project.feature-A/
  • 清理主仓库 .git/worktrees/ 中的关联记录

用 wt 命令删除

1wt remove feature-A
2

效果一样,如果是用了 Worktrunk 的话这条命令更简洁。

手动删了目录怎么办?

如果你直接 rm -rf 了 worktree 目录,Git 并不知道它已经没了,git worktree list 里还会显示这条记录。这时候跑一下:

1git worktree prune
2

它会扫描所有 worktree 记录,把指向已不存在目录的条目清理掉。

2. 清理构建产物

前面提到,git worktree remove 会删掉整个 worktree 目录,所以目录内的 SPM .build/ 缓存会一并清理。但 Xcode 的 DerivedData 不会被清理——它在全局目录 ~/Library/Developer/Xcode/DerivedData/ 里,每个 worktree 编译后都会留下一个条目。

以我的项目为例,两个 worktree 编译后的 DerivedData 条目加起来就有 39 GB:

1~/Library/Developer/Xcode/DerivedData/
2├── MyProject-abwbwhgd...  21 GB   主仓库的
3├── MyProject-gqrqpoak...  18 GB   某个 worktree 
4└── ...
5

worktree 删了,但对应的 DerivedData 条目还在。时间一长这里会积攒大量无用缓存。

用 Worktrunk hook 自动清理

如果你用了 Worktrunk,可以通过 hook 在删除 worktree 时自动清理 DerivedData。

这里的关键问题是:DerivedData 目录名是 项目名-<一段哈希>,这个哈希是根据 .xcodeproj 的完整路径用 MD5 生成的,没法直接从 worktree 路径推算出来。但好在每个 DerivedData 目录下都有一个 info.plist,里面的 WorkspacePath 字段记录了对应的项目路径:

1$ plutil -p ~/Library/Developer/Xcode/DerivedData/MyProject-gqrqpoak*/info.plist
2  "WorkspacePath" => "/Users/me/Projects/my-project.feature-A/MyProject.xcodeproj"
3

利用这一点,我们可以配一个 Worktrunk 的 post-remove hook,在 worktree 删除后自动清理对应的 DerivedData。

post-remove 阶段虽然目录已经被删了,但 Worktrunk 的模板变量(如 {{ worktree_path }})仍然可用,它们引用的是被删除 worktree 的信息。

配置文件位置:

  • 项目级:仓库根目录下的 .config/wt.toml
  • 用户级(推荐,全局生效):~/.config/worktrunk/config.toml

在配置文件中加上:

1[post-remove]
2clean-derived = """
3  grep -rl {{ worktree_path }} \
4    ~/Library/Developer/Xcode/DerivedData/*/info.plist 2>/dev/null \
5  | while read plist; do
6      derived_dir=$(dirname "$plist")
7      rm -rf "$derived_dir"
8      echo "Cleaned DerivedData: $derived_dir"
9    done
10"""
11

原理很简单:DerivedData 的 info.plist 是 XML 格式的纯文本文件,用 grep -rl 直接搜索包含当前 worktree 路径的 plist,找到了就删掉对应目录。

这不是 Worktrunk 的官方方案,是我根据 Xcode DerivedData 的 目录命名机制 写的自定义 hook。hook 中可以使用 Worktrunk 的模板变量,比如 {{ worktree_path }}(worktree 完整路径)、{{ repo }}(仓库目录名)、{{ branch }}(分支名)等,完整列表参考 Worktrunk hook 文档。另外注意模板变量会自动 shell-escape,不需要额外加引号。

这样每次执行 wt remove 时,只会精确清理这个 worktree 对应的 DerivedData,不会误删主仓库或其他 worktree 的编译缓存。

手动清理

如果你没有用 Worktrunk 的话,那只能手动清理了。直接删掉对应的 DerivedData 目录即可(说起来容易做起来难,主要是难以找到对应的编译产物目录,所以我推荐用 Worktrunk,第一次配置麻烦一点,但之后省事)

1# 查看有哪些条目
2ls ~/Library/Developer/Xcode/DerivedData/
3# 删掉不需要的(根据名称和时间判断)
4rm -rf ~/Library/Developer/Xcode/DerivedData/MyProject-gqrqpoak*
5

3. 清理分支

删掉 worktree 并不会删除对应的分支。如果分支已经合并了、不再需要,记得顺手清理:

1# 删除本地分支
2git branch -d feature-A
3
4# 删除远程分支(如果 push 过的话)
5git push origin --delete feature-A
6

完整清理流程

总结一下,一个 worktree 用完后的标准清理流程:

使用原生 Git 命令

1# 1. 回到主仓库
2cd ~/Projects/my-project
3# 2. 删除 worktree(目录 + SPM 缓存一起清理)
4git worktree remove ../my-project.feature-A
5# 3. 删除本地分支
6git branch -d feature-A
7# 4.(可选)清理对应的 DerivedData
8rm -rf ~/Library/Developer/Xcode/DerivedData/MyProject-<hash>
9# 5.(可选)如果之前手动删过目录,统一清理残留记录
10git worktree prune
11

使用 Worktrunk

1# 1. 删除 worktree + 分支一步搞定
2wt remove feature-A
3# 2. DerivedData 通过 post-remove hook 自动清理(需提前配置)
4

如果配置了 post-remove hook,Worktrunk 会在删除 worktree 后自动执行清理脚本,连 DerivedData 都不用手动管。这也是我推荐用 Worktrunk 的原因之一——清理流程从 5 步缩减到 1 步。

七、用 GitHub Desktop 查看 Diff

Claude Code 在 worktree 里改了一堆代码,你怎么 review 呢?纯命令行 git diff 看大量改动还是挺累的。我本身是用 GitHub Desktop 来查看 diff,它对 worktree 的支持其实并没有那么好,但是免费。

第一次需要手动添加仓库

GitHub Desktop 不会自动识别 worktree 目录,你需要手动把它添加进来:

  1. 打开 GitHub Desktop
  2. 菜单 → File → Add Local Repository(或直接 ⌘O
  3. 选择 worktree 所在的目录(比如 ~/Projects/my-project.feature-A/

添加一次之后就会一直保留在列表里,下次直接切换就行。

日常使用

添加完之后,体验和普通仓库完全一样:

功能说明
Changes 面板实时查看 Claude 改了哪些文件
Diff 视图逐行查看代码变更,高亮增删
History查看 Agent 的提交历史
分支切换在左上角切换不同的 worktree 仓库

如果你同时开了多个 worktree,可以在 GitHub Desktop 的仓库列表里快速切换,每个 worktree 都是独立的条目。这样一边让 Claude 在终端里写代码,一边在 GitHub Desktop 里实时看 diff,体验非常舒服。

八、其他实用工具

gwq:Worktree 管理 UI

当你的 worktree 越来越多(比如超过 10 个),手动管理就开始头疼了。这时候可以试试 gwq,它提供了一个模糊搜索的 UI 来管理 worktree:

1gwq list
2

运行后会弹出一个交互式的列表,你可以快速搜索、切换、删除 worktree。对于重度 worktree 用户来说挺方便的。

九、总结

最后总结一下这套方案的核心:

  • Git Worktree 让多个分支可以同时活跃,共享 Git 数据库,节省磁盘空间
  • Claude Code 在每个独立的 worktree 中运行,上下文隔离互不干扰
  • Worktrunk(wt) 简化了 worktree 的创建和管理,一行命令搞定
  • GitHub Desktop 免费查看 diff,手动添加一次 worktree 目录即可

整套方案搭下来,其实就这几个工具:

1Git + git worktree + wt + Claude CLI + GitHub Desktop
2

没什么复杂的配置,但效率提升确实很明显。尤其是在需要同时推进多个功能或修复的时候,并行开发的优势就体现出来了。


Git Worktree / Worktrunk:并行 AI 开发工作流实战》 是转载文章,点击查看原文


相关推荐


在OrangePi-5 Plus/5 Ultra上实时运行yolo26进行无人机检测,fps超50!
吃素的力2026/3/1

在OrangePi-5 Plus/5 Ultra上使用VideoPipe与YOLO26n实现高性能无人机检测 视频效果展示 RK3588无人机检测 前言 随着低空经济的快速发展,无人机检测已成为安防监控、边境巡逻、关键区域保护等场景中的重要需求。OrangePi 5 Plus和OrangePi 5 Ultra作为瑞芯微RK3588平台的高性能开发板,凭借其强大的NPU算力,成为边缘端AI推理的理想选择。 本文将详细介绍如何基于VideoPipe框架,结合最新的Y


花 200 美刀买“黑盒”?Claude Code 这波更新,把程序员当傻子了吧…
Dcs2026/2/21

有些产品吧,功能再强,只要开始“藏事儿”,程序员的雷达立马就响了: 你到底读了哪个文件?你到底搜了啥?你到底改了啥?——别跟我说“别管细节,反正我很聪明”。哥们,工程不是玄学,是可验证、可追溯、可复盘。 然后,Claude Code 2.1.20 就真把这事做了:把“读取文件路径”和“搜索 pattern”这种最基础的可观测信息,直接干没了。 1)更新前 vs 更新后:从“可审计”变成“随缘”🤡 以前你会看到它读了哪些文件、搜了什么关键词,属于那种一眼就能判断它有没有跑偏的“低噪音透明输出”


为什么 Memo Code 先做 CLI:以及终端输入框到底有多难搞
mCell2026/2/12

同步至个人站点:为什么 Memo Code 先做 CLI:以及终端输入框到底有多难搞 如果你对我的 Code Agent项目感兴趣,可以看这里: Github Repo: Memo Code - Github 站点:Memo Web Site 大概四年前,我刚接触编程。学的是 C 语言,第一个程序当然是 hello world。 很简单,几行就写完。run 一下,弹出来一个 terminal(我已经忘了当时用的是什么:cmd?PowerShell?反正不重要),然后打印了一行: “hell


Java8 API文档搜索引擎_优化构建索引速度
_周游2026/2/3

本专栏前文已介绍完成索引模块程序: https://blog.csdn.net/m0_63299495/article/details/157515700?spm=1011.2415.3001.5331https://blog.csdn.net/m0_63299495/article/details/157515700?spm=1011.2415.3001.5331并对关键部分进行了细节整理: https://blog.csdn.net/m0_63299495/article/details


Linux软件安装 —— Flink集群安装(集成Zookeeper、Hadoop高可用)
吱唔猪~2026/1/25

文章目录 一、节点说明二、配置节点间免密登录三、JDK安装四、Zookeeper安装五、Hadoop安装六、Flink安装1、基础环境准备(1)下载安装包(2)上传并解压 2、修改配置(1)配置zookeeper(2)配置flink-conf.yaml(3)配置workers(4)创建必要的目录(5)配置环境变量 3、分发flink 七、集群测试1、启动zookeeper,hadoop2、Yarn Session测试(1)模式介绍(2)准备测试资源


图解DeepSeek最新论文,人人都能看得懂!
饼干哥哥2026/1/16

DeepSeek 又发论文了。 这一次,没有惊天动地的参数军备竞赛,没有万卡集群的暴力美学。 他们只是冷静地指出了当前 AI 届一个“皇帝的新衣”: 我们最顶尖的大模型,其实都在做着极其愚蠢的事情。 在这篇名为《Conditional Memory via Scalable Lookup》(基于可扩展查找的条件记忆)的论文中,DeepSeek 创始人梁文锋亲自署名,揭示了下一代大模型架构(V4?)的核心秘密:与其让模型更努力地“思考”,不如教它学会“作弊”。 01.愚蠢的天才:为什么要用算力去


如何在CentOS 7.9 服务器上配置并优化 Ceph 分布式存储集群,提升数据冗余与性能?
A5IDCCOM2026/1/8

本文基于A5IDC在真实生产环境(跨机房 Ceph 集群支撑虚拟机盘、对象存储及容灾复制)的实战经验,详细讲解如何从零部署 Ceph 集群在 CentOS 7.9 上,并通过硬件配置选择、网络优化、Ceph 参数调优等实用细节提升 数据冗余能力与性能表现。文章包含具体产品型号、系统配置表、命令示例与性能评估对比表,适合中大型数据中心储存架构实施。 一、背景与目标 随着业务系统对海量数据持久层的要求不断提升,我们需要一个高可靠、易扩展、具有自动自愈能力的分布式存储平台。Ceph 是开源生态


Git/Gitee/GitHub有什么区别
lifewange2025/12/31

Git、GitHub、Gitee(码云)三者核心区别 & 完整详解 你想弄清楚这三者的关系和差异,本质上Git 是「工具」,GitHub/Gitee 是「平台」,这是最核心的定位区别,三者不是同一维度的东西,先把这个核心逻辑吃透,所有差异就一目了然了。 ✅ 一、三者的「本质定位」(最核心,必记) 1. Git —— 本地的「版本控制系统」(纯软件 / 工具) Git 是一个免费、开源的分布式版本控制软件,它是一个安装在你电脑本地的程序 / 工具,不依赖任何网络、不依赖任何网站就能独立运行


Apache Tika XXE注入漏洞 | CVE-2025-66516 复现&研究
探索宇宙真理.2025/12/21

0x0 背景介绍 Tika Pdf Parser Module是Apache软件基金会开发的Java库,专用于解析PDF文件内容。核心功能包括文本提取、元数据解析及嵌入式对象处理,基于Apache Tika框架实现,依赖PDFBox等开源库。 Apache Tika的tika-core(1.13-3.2.1)、tika-pdf-module(2.0.0-3.2.1)和tika-parsers(1.13-1.28.5)模块存在严重XXE漏洞(跨平台),攻击者可通过构造PDF内的XFA文件实施XM


tig 的untracked changes和unstaged changes含义?
aoxiang_ywj2025/12/13

背景:你理解tig中untracked changes和unstaged changes的含义?它们对应的代码存在哪里呢?在本地仓库?提交到gitlab线上库了?下面将解答这些疑问。 一、核心结论先明确 tig 中显示的 Untracked changes(未跟踪变更)和 Unstaged changes(未暂存变更)都属于本地工作区的修改,完全没有提交到 GitLab 线上库,甚至连「本地仓库的提交(commit)」都没完成 —— 它们和 GitLab 线上库没有任何关联,仅存在于你的本地

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客