前言: 什么是 Git Worktree?
Git Worktree 允许你在同一个 Git 仓库中,同时拥有多个独立的工作目录,每个目录可以检出不同的分支.
Git Worktree 完全手册
基于实际对话整理,涵盖底层原理、工作流场景与常见误区。
目录
1. 底层原理
1.1 文件系统层面的实现
当你运行 git worktree add <path> <branch> 时,Git 并不会复制整个仓库,而是创建了一个轻量级的链接机制。
额外工作树的 .git 是一个文本文件,而非目录:
1 | # 在 my-feature/.git 文件中 |
主仓库 .git 目录的变化:
1 | .git/ |
1.2 与 git clone 的本质区别
| 维度 | git clone |
git worktree |
|---|---|---|
| Objects 数据库 | 复制一份 | 共享 |
| Refs 引用 | 独立 | 共享 |
| 磁盘占用 | 大(完整副本) | 极小(仅工作目录差异) |
| 同步方式 | 需 fetch/pull | 天然同步(共用 objects) |
2. 核心机制
| 层面 | 行为 |
|---|---|
| Objects 数据库 | 所有 worktree 共享 .git/objects,不重复存储 |
| Refs 引用 | 共享 .git/refs,但每个 worktree 有独立的 HEAD |
| Index 暂存区 | 各自独立,每个 worktree 维护自己的索引 |
| 分支限制 | 同一个分支不能同时检出到多个 worktree(防止冲突) |
| 裸仓库支持 | 可以从 bare repo 创建多个工作树,实现"一个仓库多份检出" |
3. 工作流应用场景
| 场景 | 痛点 | Worktree 解决方式 |
|---|---|---|
| 并行开发 | 开发到一半要切分支修 Bug,被迫 stash | 新目录直接检出 hotfix 分支,原目录完全不动 |
| 代码审查 | Review 同事 PR 时需要切换分支,打断当前流 | 单独 worktree 检出 PR 分支,主目录继续编码 |
| 多版本维护 | 同时维护 v2.x LTS 和 v3.x 主线 | 两个 worktree 分别长期持有不同分支 |
| 长耗时构建 | 切分支后 node_modules 或构建缓存失效 |
各 worktree 有独立的工作目录,依赖互不干扰 |
| CI/CD 优化 | 流水线需要同时构建多个分支 | 基于同一个裸仓库创建多个 worktree,节省磁盘和 clone 时间 |
4. 场景示例:紧急热修复不中断功能开发
背景
你正在 feature/payment-gateway 分支上开发支付网关重构,修改了 20 个文件,但还没准备好提交。此时生产环境突发严重 Bug,需要立即修复。
传统方式的问题
1 | git stash push -m "WIP: payment gateway" # 暂存当前工作 |
痛点:stash/restore 可能出错;如果功能分支有未跟踪文件,stash 不会保存;切换分支可能导致 IDE 重新索引、构建缓存失效。
Worktree 方式
1 | # 当前在 ~/projects/kimi 的 feature/payment-gateway 分支上开发中 |
效果
1 | ~/projects/ |
优势:
- ✅
~/projects/kimi里的 20 个未提交修改完全不受影响 - ✅ IDE 保持打开,无需重新加载项目
- ✅ 两个目录有独立的
node_modules,不会因分支差异导致依赖混乱 - ✅ 修复完成后直接删除
kimi-hotfix目录即可,零副作用 - ✅ 磁盘占用极小,因为 objects 数据库共享
5. 常见误区:删除 worktree 不等于合并分支
问题
当走到最后一步
git worktree remove ../kimi-hotfix后,kimi中是否已经更新了kimi-hotfix修改的内容?
答案:不会
删除 kimi-hotfix 工作树后,kimi 主工作树中的文件内容不会自动包含 hotfix 的修改。
区分三个层面
| 层面 | 状态 | 原因 |
|---|---|---|
| Git 对象数据库 | ✅ 已包含 hotfix 提交 | 所有 worktree 共享同一个 .git/objects,commit 已经写入了 |
| 分支引用 | ✅ hotfix/critical-bug 分支存在 |
共享 .git/refs,删除 worktree 不影响引用 |
| 主工作树的文件 | ❌ 不包含 hotfix 修改 | kimi 检出的是 feature/payment-gateway,与 hotfix/critical-bug 是两个独立分支 |
为什么不会自动更新?
Worktree 的核心设计就是隔离的工作目录。每个 worktree 维护自己的 HEAD 和 index:
1 | kimi/ HEAD → feature/payment-gateway |
删除 kimi-hotfix 只是移除了一个工作目录的入口,并不会触发任何分支合并操作。feature/payment-gateway 分支的指针没有移动,所以 kimi 目录里的代码保持原样。
正确做法:显式合并
1 | # 1. 先确保 hotfix 合并到 main(通过 PR 或命令行) |
💡 一句话总结:Worktree 让你并行检出多个分支,但从不帮你自动合并它们。删除 worktree ≠ 合并分支。
6. 常用命令速查
1 | # 查看所有工作树 |