Posted in

Git Worktree 使用教程(一个仓库同时 checkout 多个分支)

Worktree 允许你把同一个 Git 仓库的多个分支,同时 checkout 到不同的目录里,互不干扰。

传统方式下,一个仓库目录同一时刻只能看到一个分支。想看另一个分支就得 stash/commit 然后切换。Worktree 让你直接开多个目录,各自看不同分支,同时工作。


直观对比

没有 worktree 时

纯文本纯文本项目目录/
├── src/
├── README.md
└── .git/          ← 只有一个工作区,只能在一个分支上

想同时看 mainfeature/login?要么来回 git switch,要么 clone 两份仓库(浪费空间)。

有了 worktree 后

纯文本纯文本主仓库/                        ← 在 main 分支
├── src/
└── .git/

~/worktrees/feature-login/      ← 在 feature/login 分支,独立目录
├── src/
└── .git  → 指向主仓库的 .git(不是复制)

~/worktrees/hotfix/             ← 在 hotfix 分支,又一个独立目录
├── src/
└── .git  → 指向主仓库的 .git

所有 worktree 共享同一个 .git 仓库数据(objects、refs、logs),只是各自有独立的工作区和独立的 HEAD。


核心设计要点

特性说明
共享 Git 对象库commits、blobs、trees 只有一份,不重复占用磁盘
独立工作区每个 worktree 有自己的文件状态,互不影响
独立分支同一个分支不能同时被两个 worktree checkout(就是你刚才碰到的限制)
共享 refs分支、tag 在所有 worktree 里都能看到

常见使用场景

1. 正在开发一半,突然要修线上 bug

bashbash# 不用 stash,直接开个新 worktree
git worktree add ../hotfix main
cd ../hotfix
# 改完、提交、push、PR,关掉

2. 需要同时跑两个分支的测试

比如你在对比两个分支的性能差异,各开一个 worktree,分别编译运行,互不干扰。

3. 代码审查时对照查看

bashbashgit worktree add ~/review-pr-123 feature/some-pr
cd ~/review-pr-123
# 跑起来看看效果

基本操作速查

bashbash# 创建:基于某分支开新 worktree
git worktree add ../my-feature feature/login

# 创建并新建分支
git worktree add -b feature/new-branch ../new-dir main

# 列出所有
git worktree list

# 删除(会清理目录 + 更新 Git 记录)
git worktree remove ../my-feature

# 清理已手动删除目录留下的"僵尸记录"
git worktree prune

一个小细节

.git 文件在不同位置长的不一样:

  • 主仓库.git/ 是个目录,里面是完整的 objects、refs 等
  • worktree.git 是个文件,内容类似: 纯文本纯文本gitdir: /home/user/main-repo/.git/worktrees/my-feature实际数据全在主仓库的 .git/worktrees/<name>/ 下面。

常见问题

  • Q:Git Worktree 和 git clone 有什么区别?A:clone 复制整份 .git 占双倍盘;worktree 只加工作目录,共享同一 .git。
  • Q:一个分支能同时被两个 worktree checkout 吗?→ A:不能,会报 “branch is already checked out”,这正是防冲突的设计。
  • Q:直接删了 worktree 目录怎么办?→ A:记录还在,用 git worktree prune 清僵尸。
  • Q:worktree 额外占盘吗?→ A:工作区文件占一点,commits/blobs 等对象只有一份,全共享。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注