Git Worktree 可视化理解指南

一句话理解

一个 Git 仓库,同时在多个目录里检出不同分支,共享同一份 .git 数据库。

无需 clone 多份仓库,就能并行工作在多个分支上。


先搞清楚两个最基础的问题

💡 Q1:这几个文件夹是独立的吗?

是的,它们就是磁盘上 3 个完全独立的文件夹,跟普通文件夹一模一样。

Q2:它们彼此有什么关联?

共享一份隐藏的"历史档案库"(.git),但你肉眼看不到这层关联。


用真实文件演示:一步一步看

假设有一个项目 myapp,就两个文件:README.mdmain.c

第 1 步:原始状态,只有 1 个文件夹

plaintext 复制代码
/home/mi/myapp/          ← 唯一的文件夹(主 worktree)
├── .git/                ← 隐藏文件夹,存所有历史
├── README.md            ← 内容:"main 分支的 README"
└── main.c               ← 内容:printf("main");

此时 git branch 能看到 mainfeature-ahotfix 3 个分支。但文件夹只有一个 ,显示的是当前检出的 main 分支内容。


第 2 步:执行 git worktree add 命令

bash 复制代码
cd /home/mi/myapp
git worktree add ../myapp-feature-a feature-a
git worktree add ../myapp-hotfix    hotfix

执行完后,磁盘上凭空多出两个文件夹

plaintext 复制代码
/home/mi/
├── myapp/                     ← 原来就有的(主 worktree)
│   ├── .git/                  ← 完整的 .git 目录(真正的历史库)
│   ├── README.md              ← "main 分支的 README"
│   └── main.c                 ← printf("main");
│
├── myapp-feature-a/           ← 新出现!
│   ├── .git                   ← 注意:这是一个"文件",不是文件夹!
│   ├── README.md              ← "feature-a 分支的 README"
│   └── main.c                 ← printf("feature");
│
└── myapp-hotfix/              ← 新出现!
    ├── .git                   ← 同样是文件
    ├── README.md              ← "hotfix 分支的 README"
    └── main.c                 ← printf("hotfix");

三个文件夹完全独立,你可以:

  • 用 VSCode 同时开 3 个窗口,每个窗口打开一个文件夹
  • myapp-feature-a/main.c 里改代码,另外两个文件夹纹丝不动
  • 在三个文件夹里分别跑 makenpm start,互不影响

关联在哪?关键在那个"指针文件"

cat 看一下附加 worktree 里的 .git

bash 复制代码
$ cat /home/mi/myapp-feature-a/.git
gitdir: /home/mi/myapp/.git/worktrees/myapp-feature-a

翻译成人话:

"我这个文件夹不存历史。历史都存在主仓库的 .git/ 里。那边才是真老大。"

所以虽然磁盘上看起来是 3 个独立文件夹,但两个附加 worktree 都通过这个小指针挂在 主仓库的 .git/ 上。
/home/mi/myapp-hotfix/
/home/mi/myapp-feature-a/
/home/mi/myapp/ (主 worktree)
指向
指向
.git/

真·历史库

objects / refs / HEAD ...
README.md / main.c

(main 分支内容)
.git 指针文件

gitdir: .../worktrees/feature-a
README.md / main.c

(feature-a 分支内容)
.git 指针文件

gitdir: .../worktrees/hotfix
README.md / main.c

(hotfix 分支内容)

橘黄色 = 真仓库,存着所有 commit 历史。淡蓝色 = 空壳,只有代码文件和一个指向主仓库的小指针。


生活化类比:图书馆的阅览室

把 Git 仓库想象成一座图书馆

概念 图书馆里对应什么
.git 目录 📚 总书库(所有书的所有版本都存在这里)
worktree 📖 阅览室,从书库里调出某一版本的书到桌上看/改
git worktree add 🏗️ 新开一间阅览室,再调一份不同版本的书出来
  • 3 间阅览室(myapp/myapp-feature-a/myapp-hotfix/物理上是 3 个独立房间,互不干扰
  • 但它们共用同一个书库 ,你在任一阅览室把涂改稿"归档"(git commit),书库里立刻多一本新版本,其他阅览室也能看到

自测三道题

读完上面内容,试着回答:

Q1 :在 myapp-feature-a/main.c 改了代码但没 commit,myapp/main.c 会变吗?

不会,三个文件夹的工作区完全独立。

Q2 :在 myapp-feature-a/git commit 后,到 myapp/ 执行 git log feature-a,能看到这个 commit 吗?

,commit 进了共享的 .git 书库,所有 worktree 都能看到。

Q3 :把 /home/mi/myapp/(主 worktree)整个删掉,另外两个还能用吗?

不能 ,它们的 .git 只是指针,指向的真书库没了就全废了。


核心架构:共享 .git,独立工作区

.git 对象库

objects / refs / packed-refs

全局唯一一份
worktree #1(主)

HEAD → main

独立 index / 工作区
worktree #2

HEAD → feature-a

独立 index / 工作区
worktree #3

HEAD → hotfix

独立 index / 工作区

关键点

  • .git 只有一份 → 省磁盘、省带宽
  • 每个 worktree 有自己的 HEADindex → 互不干扰
  • 一处 git fetch,所有 worktree 都能看到新分支

典型场景:紧急修 bug 不打断手头工作

远端仓库 hotfix 工作区(新建) feature 工作区 开发者 远端仓库 hotfix 工作区(新建) feature 工作区 开发者 正在写 feature,代码未完成 无需 stash,无需切分支 上下文完全保留, 改到一半的代码还在 git worktree add ../myapp-hotfix hotfix 定位 bug → 修复 → git commit git push 回到 feature 工作区继续编码

不用 git stash,不用切分支,不用 clone 第二份仓库。


对比:git clone 两份 vs git worktree

方案 B:git worktree
.git

100GB(共享一份)
worktree 1
worktree 2
✅ 磁盘不翻倍

✅ fetch 一次全同步

✅ 分支实时可见
方案 A:git clone 两份
.git #1

100GB
.git #2

100GB
❌ 磁盘翻倍

❌ fetch 两次

❌ 分支状态不同步

仓库越大,优势越明显(想象一下 100GB 的 Chromium 仓库)。


该不该用 worktree?决策图

否,只是偶尔切分支







需要在多分支间工作?
会并行推进

2 个以上任务?
git switch / git stash

就够了
仓库很大

或编译很慢?
✅ 强烈推荐

git worktree
需要并行跑

测试 / CI?
习惯多窗口

并行编辑?


常用命令速查

操作 命令
基于已有分支开 worktree git worktree add ../repo-feat feature-a
开 worktree 并新建分支 git worktree add -b new-branch ../repo-new main
列出所有 worktree git worktree list
移除 worktree(先删目录) git worktree remove ../repo-feat
清理无效元数据 git worktree prune
锁定 worktree(防误删) git worktree lock ../repo-feat

典型用途汇总

🚀

  1. 并行开发 --- 手上的 feature 没写完,随时开 worktree 修 hotfix
  2. 长编译场景 --- 主目录编译中,另开 worktree 写下一个任务(Vela/NuttX 编译慢场景非常实用)
  3. Code Review --- 拉同事分支到独立目录看代码,不污染自己工作区
  4. 版本对比 --- 同时检出 old/new,并排 diff 或对比测试
  5. CI / 脚本任务 --- 自动化任务在独立 worktree 跑,不干扰开发者

注意事项(踩坑清单)

⚠️

  • 🚫 同一分支不能被两个 worktree 同时检出 --- 会报错 already checked out
  • 🧹 删 worktree 目录后必须 git worktree prune --- 否则 .git/worktrees/ 残留元数据
  • 🔒 HEAD / index / reflog 每个 worktree 独立 --- 但对象库共享
  • 📦 git stash 是每个 worktree 独立的 --- 不能跨 worktree 访问 stash

在 Vela/NuttX 项目里

p65-trunk 这类 Google repo 管理的多仓库项目,原生 git worktree 只管单仓库。要一次性给所有子仓开 worktree,用项目里的 repoworktree(rwt) 工具更合适 ------ 它封装了对整个 repo manifest 下所有仓库批量开 worktree 的逻辑,能为每个 feature 开一个完整的多仓隔离工作空间。

相关推荐
happymaker06263 小时前
git使用快速入门
git
不做超级小白4 小时前
从零到可用:在手机上用 Termux + Git + Obsidian 打造稳定同步环境(踩坑全记录)
git·智能手机
凡客丶4 小时前
Git安装与使用保姆教程【超详细】
git
android_cai_niao4 小时前
给Git项目添加多个远程仓库
git·gitee·github
胡小禾4 小时前
多账号下git自动切号
git
zhensherlock4 小时前
Protocol Launcher 系列:Working Copy 提交与同步全攻略
javascript·git·typescript·node.js·自动化·github·js
前端若水4 小时前
Git 全命令超级详细指南
大数据·git·elasticsearch
SiYuanFeng16 小时前
新手学Git:如何把本地 Git 项目上传到 GitHub
git·github
前端若水18 小时前
git回退并合并分支操作
git