拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Git Worktree 详解

Git Worktree 详解

Git Worktree 详解

Git worktree(工作树)允许你在同一份仓库中同时检出多个分支到不同的目录,无需反复切换分支或克隆多份仓库。这是处理并行任务(多分支开发、热修复、代码评审)的利器。

为什么需要 worktree?

普通 Git 工作流的痛点:

  1. 切换分支成本高:git checkout会暂停当前工作,未提交的修改会阻塞切换或带来冲突。
  2. 并行需求冲突:想在 A 分支写功能,又想马上切到 B 分支修 bug,如果依赖未提交内容就会互相干扰。
  3. 克隆多份仓库占用空间大:git clone会把整个.git历史复制多份,磁盘和索引损耗都很大。

worktree 的解决方案:共享同一份仓库历史(同一个.git目录),但每个 worktree 有独立的工作目录 + 暂存区 + HEAD。你可以同时打开多个目录,分别处于不同分支,互不阻塞。


核心概念

  • main worktree(主工作树):默认的一棵工作树,通常对应仓库根目录。
  • linked worktree(链接工作树):通过git worktree add额外检出的工作树,位于其他目录。
  • .git目录共享:所有 worktree 共享同一份对象库(objects)、引用(refs)、配置(config),因此切换成本极低。

目录结构说明

project/ ├── .git/ # 共享:对象库、refs、config(整个仓库唯一的 .git) ├── index.html # main worktree(主工作树 / 当前分支) └── _feature/ # linked worktree(另一个分支) ├── .git # 这是一个文件,内容指向共享 .git 目录 └── index.html # feature 分支的文件

链接 worktree 里的.git不是目录,而是一个文本文件,内容形如:
gitdir: /path/to/project/.git/worktrees/_feature
这就是所有 worktree 共享同一份历史的关键。


常用命令速查

操作命令
查看所有 worktreegit worktree list
新建 worktree(新分支)git worktree add <目录> -b <新分支名> [基点]
新建 worktree(检出已存在分支)git worktree add <目录> <已存在分支>
基于某个 commit/tag 创建git worktree add <目录> <commit/tag>
从临时分支创建git worktree add --detach <目录> <commit>
移动 worktreegit worktree move <旧目录> <新目录>
锁定 worktreegit worktree lock <目录>
解锁 worktreegit worktree unlock <目录>
清理已删除分支的 worktree 记录git worktree prune
删除 worktreegit worktree remove <目录>

经典使用场景

1. 并行多分支开发

# 在 main 工作树基于 master 开一个功能分支的工作树 git worktree add ../project-feature -b feature/new-ui # 在另一个目录并行做热修复 git worktree add ../project-hotfix -b hotfix/login-bug # 三个目录互不干扰,都指向同一个仓库 git worktree list

2. 边开发边代码评审

# 检出同事的 PR 分支,不影响你当前正在写的代码 git worktree add ../review -b review/branch-name origin/pr-branch

3. 快速尝试验证某个版本

# 临时查看某个 tag/commit,不想动当前分支 git worktree add --detach ../tmp-v2.0 v2.0 # 用完即删 git worktree remove ../tmp-v2.0

使用注意事项

一个分支只能有一个 worktree

同一分支在同一仓库中只能被一个 worktree 检出。若已有一棵 worktree 在feature/x上,再git worktree add ../t2 feature/x会报错:
fatal: 'feature/x' is already checked out at '...'
这是为了确保对一个分支的提交方向是唯一的。

删除前先检查是否干净

git worktree remove默认拒绝删除有未提交改动或未跟踪文件的 worktree,需先清理或加--force(谨慎)。

分支删除后残留的记录

分支被删除后,其 worktree 相关记录仍存在。定期执行git worktree prune清理。

暂存区相对独立

每个 worktree 有独立的暂存区(index)。在 A worktree 暂存的改动不会出现在 B worktree。


完整练习:从 0 上手

# 1. 创建演示仓库 mkdir demo-worktree && cd demo-worktree git init -b main echo "hello" > README.md && git add . && git commit -m "init" # 2. 查看当前 worktree(只有 main) git worktree list # demo-worktree <hash> [main] # 3. 创建功能分支的 worktree git worktree add ../demo-wt-feature -b feature/hello # 4. 进入新 worktree 写代码 cd ../demo-wt-feature echo "world" >> README.md git commit -am "update from feature worktree" # 5. 回到主 worktree,main 分支完全没受影响 cd ../demo-worktree git log --oneline # 仍只有 init # 6. 删除 worktree 并清理 cd .. git worktree remove --force ../demo-wt-feature git branch -d feature/hello git -C demo-worktree worktree prune

高级技巧

给 worktree 配置不同远程

可以将不同 worktree 指向不同远程,便于发布/测试:

git worktree add ../prod -b release/prod git -C ../prod remote add prod git@example.com:prod-repo.git git -C ../prod fetch prod

用 shell 别名加速

# ~/.bashrc 或 ~/.zshrc alias wt-add='git worktree add' alias wt-list='git worktree list' alias wt-rm='git worktree remove' alias wt-prune='git worktree prune'

在 worktree 间跳转

# 列出后,用 -C 直接到对应目录执行 git git worktree list git -C ../project-feature status

常见问题(FAQ)

Q:worktree 会重复占用磁盘空间吗?
A:不会重复保存历史对象。所有 worktree 共享同一.git对象库,只额外占一份工作目录 + 暂存区的空间。

Q:可以嵌套多个 worktree 吗?
A:可以,git worktree add可重复创建任意多棵,只要目录不冲突、分支不重复检出。

Q:worktree 里的分支能 push 吗?
A:能,它就是一份正常的 Git 检出,push/pull/fetch 都照常工作。

Q:误删了 worktree,还能找回吗?
A:分支和提交仍保留在仓库历史里,可用git branch重建分支后重新git worktree add检出。

Q:不同 worktree 之间能合并吗?
A:能,本质是不同分支,在该仓库任意 worktree 中git merge或git rebase即可。


总结

场景是否建议用 worktree替代方案
并行开发多个功能✅ 强烈推荐多份 clone(费空间)
频繁切换分支写代码✅ 推荐git stash + checkout
边写边评审他人 PR✅ 推荐切分支 / stash
只是想看旧版本✅ 适合git show
一次性实验一般临时 clone / stash

一句话记忆:git worktree用「一份历史、多份工作目录」解决「多任务并行」。

返回列表