默认一个工作区对应一个 .git
目录。worktree
让你在多个目录同时检出同一仓库的不同分支;submodule
在 tree 里用 gitlink
指向另一仓库;alternates 让多个对象库共享
objects/。三者都会让「项目根下的
.git」不再是完整对象库——需要读
gitdir: 指针。
一、链接工作树(worktree)
主仓库执行:
git worktree add ../wt2 -b wtbranch次要工作树目录 wt2/.git
不是目录,而是文本文件:
gitdir: /path/to/main/.git/worktrees/wt2
主仓库 .git/worktrees/wt2/ 含:
gitdir:指回wt2绝对路径HEAD、index、logs 等工作树私有状态
对象库与 refs 仍在主
.git,多工作树共享,避免重复存储。
限制:同一分支不能同时在两个 worktree 检出(除非
worktree 允许配置)。
二、submodule
.gitmodules
在工作区;子模块检出后对象库常在:
.git/modules/<name>/
父仓库 tree 中条目 mode 160000,SHA
为子模块当前 commit(gitlink),不是
blob。子模块有自己的
refs、objects,与父库逻辑分离。
git submodule update 会 clone/fetch
子模块并写上述路径。备份父仓库须连同
.git/modules 或重新 init 子模块。
三、alternates 共享对象库
.git/objects/info/alternates
文本文件,每行一个绝对或相对路径,指向另一个仓库的
objects 目录:
../../shared.git/objects
读取对象时 Git 先查本库,再查 alternate。用于同一机器多克隆省磁盘;损坏与 gc 须谨慎(共享库被 prune 会影响所有依赖方)。
与 worktree 不同:alternates 是对象级链接,不是工作树级。
四、对比
| 机制 | 典型路径 | 共享内容 |
|---|---|---|
| worktree | .git/worktrees/* |
objects、refs(主库) |
| submodule | .git/modules/* |
无(独立对象库) |
| alternates | objects/info/alternates |
他库 objects |
五、本文边界
- 不教 submodule 版本策略与 CI 配置。
- 不讨论 partial clone promisor remote。
复现 worktree:
git worktree add ../wt2 -b wtbranch
cat ../wt2/.git
ls .git/worktrees/参考资料
- Git documentation, gitrepository-layout
git worktree/git submodulemanual pages- 实验环境:Git 2.54.0
系列索引:Git 内部结构 · 上篇:fetch/push · 下篇:SHA-256 与 reftable
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【Git 内部】.git 目录全景:三棵树与仓库布局
git init 之后 .git 里每个路径干什么?对照 gitrepository-layout 与本地 find 清单,建立 bare/non-bare、三棵树、objects/refs/index 的磁盘级地图。
【Git 内部】松散对象:zlib 载荷与 SHA-1 路径
blob/tree/commit 在磁盘上如何编码?对象头 type size、zlib 压缩、objects/ab/cdef 路径命名,对照 git hash-object 与手工 SHA-1 验证。
【Git 内部】对象图:tree、commit、tag 的链式结构
一次提交在对象库里如何连成链?tree 条目 mode/name/hash、commit 的 tree/parent 字段、annotated tag,用 git cat-file -p 展开并画对象图。
【Git 内部】refs、HEAD 与 packed-refs
分支和标签在磁盘上只是一行 SHA?refs/heads、符号引用 HEAD、packed-refs 文件头与 peeled tag 的格式与生成时机。