Git worktree 使用指南:一个仓库同时开发多个分支
前言
平时使用 Git 开发项目时,经常会遇到一种情况:当前分支的代码改到一半,突然需要切换到另一个分支修复问题。
通常可以通过 git stash 暂存修改,再切换分支。但如果两个任务需要来回切换,或者想同时打开两个版本的代码,这种方式就不太方便了。
Git 提供了一个比较实用的功能:worktree。它允许同一个仓库关联多个工作目录,每个目录可以检出不同的分支。
一、git worktree 是什么?
普通 Git 仓库通常只有一个工作目录。切换分支时,Git 会更新这个目录中的文件。
而使用 git worktree,可以让不同分支分别拥有自己的工作目录,同时共享同一个仓库的 Git 对象数据库和分支引用等信息。
例如:
project/
├── src/
└── ...
project-fix/
├── src/
└── ...
两个目录对应同一个 Git 仓库,但可以分别检出 main 和 fix-login 分支。
这样就能一边继续开发新功能,一边修改另一个分支中的问题,而不必来回执行 git switch。
二、创建新的工作目录
假设当前已经进入项目根目录,并且正在 main 分支开发。
可以执行:
git worktree add -b fix-login ../project-fix
这里:
worktree add:创建一个新的工作目录。-b fix-login:创建名为 fix-login 的新分支。../project-fix:新工作目录的位置。
如果没有指定其他起点,新分支会基于当前 HEAD 创建。
执行完成后,原来的 project 目录仍然保持原有分支和未提交的修改,新目录则检出 fix-login 分支。
进入新目录:
cd ../project-fix
git status
接下来就可以在新目录里独立修改代码。
三、使用已经存在的分支
如果修复分支已经存在,就不需要使用 -b 创建新分支。
例如:
git worktree add ../project-dev dev
这会在新的工作目录中检出已经存在的 dev 分支。
需要注意,Git 默认不允许同一个本地分支同时被两个工作目录检出。
如果 dev 已经在另一个 worktree 中使用,Git 通常会拒绝操作。这个限制可以避免不同工作目录同时修改同一分支造成混乱。
四、查看当前有哪些工作目录
执行:
git worktree list
可能看到类似输出:
/home/user/project a1b2c3d [main]
/home/user/project-fix e4f5a6b [fix-login]
可以看到每个工作目录的路径、当前提交和所在分支。
如果管理了多个修复分支,这条命令非常有用。
五、不同工作目录之间共享什么?
虽然两个 worktree 的文件是分开的,但它们并不是两个完全独立的 Git 仓库。
它们通常共享:
- Git 对象和提交历史
- 本地分支引用
- 远程仓库配置
- 已获取的远程引用
而每个工作目录都有自己的:
- 当前检出的文件
- 暂存区
- HEAD 状态
- 未提交的修改
例如,在 fix-login 工作目录提交修复代码后,原仓库也能看到这个提交对应的分支引用,不需要重新执行 git fetch。
但原来的 main 分支不会因此自动包含修复代码。是否合并仍然需要通过正常的 Git 操作完成。
另外,node_modules、Python 虚拟环境和构建产物等工作目录中的文件通常不会自动共享,这一点在大型项目中需要留意。
六、工作完成后怎么删除?
假设已经完成修复并提交代码,可以回到原项目目录:
cd ../project
查看所有工作目录:
git worktree list
确认不再需要临时工作目录后执行:
git worktree remove ../project-fix
正常情况下,Git 会删除对应的工作目录,并清理关联的 worktree 管理信息。
需要注意,如果目录中还存在未提交的修改,Git 通常会拒绝删除,避免意外丢失代码。
除非明确知道自己在做什么,否则不建议直接添加 --force。
还有一点:删除 worktree 不等于删除对应分支。修复分支仍然存在。
如果分支已经合并,并且不再需要,可以再通过正常的分支管理命令删除:
git branch -d fix-login
七、为什么不建议直接删除文件夹?
有时为了省事,会直接通过文件管理器删除 worktree 所在目录。
这样做可能留下 Git 的关联管理信息,导致以后查看 worktree 时出现已经不存在的路径。
如果已经手动删除了目录,可以先检查:
git worktree list
再预览哪些失效记录可以清理:
git worktree prune -n
确认无误后,可以使用:
git worktree prune
这里清理的是已经失效的 worktree 管理记录,不是删除项目的 Git 提交历史。
八、git worktree 和 git stash 怎么选?
两者解决的问题其实不同。
git stash 更适合临时保存未完成的修改,比如当前正在改一个文件,需要短暂切到其他分支处理问题。
git worktree 则适合两个开发任务需要持续并行的情况。例如一个目录开发新功能,另一个目录修复线上问题,或者同时使用两个编辑器窗口查看不同分支。
不过 worktree 会额外占用一份工作目录空间,项目依赖和构建环境也可能需要分别准备。对于很小的修改,直接切换分支不一定更麻烦。
总结
git worktree 最常用的命令只有几个:
# 新建工作目录和分支
git worktree add -b fix-login ../project-fix
# 查看工作目录
git worktree list
# 删除不再需要的工作目录
git worktree remove ../project-fix
# 预览失效记录清理
git worktree prune -n
相比反复 stash、切换分支再恢复代码,worktree 可以让多个开发任务保留各自的工作现场。
对于需要同时维护功能分支、修复分支,或者经常并行处理多个任务的项目,这是一个值得了解的 Git 功能。
- 点赞
- 收藏
- 关注作者
评论(0)