Git Worktree:多工作目录的高效开发模式
worktree
提供了一种在使用相同 .git
文件夹的情况下,实现多工作目录的能力。
通常情况下,git clone
远程仓库至本地会创建一个工作目录(例如 A
),并在 A
目录下创建 .git
目录以记录 Git 仓库信息。
在 IDE(如 VS Code)中,开发者通常将目录 A
设置为工作区(workspace),以直接访问项目资源,切换分支,提交更改等操作。不过,这种模式只能感知并识别 A
目录下的文件变化,属于 1 仓库:1 工作目录:N 分支 的模式。
而通过 worktree
,可以扩展额外的工作目录,使工作模式变为 1 仓库:N 工作目录:N 分支。
场景假设
假设如下场景:
张三被开发组长分配了一个新功能开发任务(任务 A),并且组长为他创建了开发分支 dev-a
。张三切换到 dev-a
分支后开始开发。正当张三兴致勃勃地推进任务时,项目经理突然冲过来,一边拍桌子一边抱怨:生产环境出了问题,需要立刻修复。开发组长于是创建了 hotfix-b
分支,将这个紧急任务交给张三处理。
由于 hotfix-b
的优先级更高,张三需要暂停任务 A。这时他有三种选择:
-
直接提交:将当前
dev-a
的所有内容(包括未完成的开发内容)提交,然后清空工作目录,切换到hotfix-b
分支,完成修复后切回dev-a
,再通过soft reset
恢复原有状态。
缺点:临时提交可能会导致误同步至远程仓库。 -
使用 Stash:将当前任务 A 的内容
stash
,清空工作目录,切换至hotfix-b
。完成修复后切回dev-a
分支,并pop
出之前的stash
内容继续开发。
缺点:stash
与分支管理不当可能引发冲突。 -
使用 Worktree:直接创建一个新的工作目录并关联
hotfix-b
分支。开发完成后,通过git worktree remove
删除新工作目录,不留任何痕迹。
这是李四举手,说,我觉得方法1,2,3差不太多啊。
李四同学说的对,坐下。
在简单场景下,1,2,3方法差别确实不大,但这里面有个隐含要素。涉及到上下文切换的代价问题。
为什么上下文切换有代价?
在没有电脑的年代,处理多个任务的最佳办法不是将当前办公桌上的资料全部收起来,再重新摆放,而是借用别人的办公桌。上下文切换会中断开发人员的专注,而专注是高效开发的前提。
此外,方法 1 和 2 还引入了额外的管理风险:
- 方法 1:临时提交可能误同步至远程仓库。
- 方法 2:
stash
内容容易误操作或丢失。
相比之下,使用 Worktree 的优势在于:
- 当前任务的工作目录无需任何改动。
- 开启新的工作目录对现有任务零侵入。
- 上下文切换的代价几乎为零。
Worktree 的其他优势
除了多任务切换,worktree
还解决了以下痛点:
-
跨分支文件参考
张三正在开发新功能,但需要查看另一个分支的某个文件状态。使用worktree
,可以直接创建一个新的工作目录以切换到目标分支,而无需清空当前工作内容或放弃现代 IDE 的便利功能。 -
代码 Review 场景
开发组长需要同时完成自己的开发任务和代码审查。如果不使用worktree
,他需要频繁切换分支,这不仅中断开发,还影响效率。而使用worktree
,可以专门创建一个用于 Review 的工作目录,Review 完成后直接关闭即可,丝毫不影响自己的开发喜欢看在线版的随意。
我是如何使用 Worktree 的
经过大量实践,我总结出以下常用配置:
- Dev 目录:用于完成当前开发任务。
- Review 目录:专门用于审查别人的提交。
- Main 目录:参考主分支或特定分支的代码。
- Release 目录:用于准备当前 Sprint 的发布内容。
可能有人会问:“直接多 clone
一份仓库不也行吗?”
理论上可以,你硬盘大CPU快你有理。但 worktree
的优势在于:
- 多个目录共享同一组
.git
信息,避免冗余。 - 节省磁盘空间和文件碎片。
- 执行效率更高。
有些软件开发公司并没有给开发同学配备高性能的电脑,任何拖累性能的东西都是压死骆驼的最后一根稻草。
此外,共享 .git
的工作目录还能继承本地设置(如 git hook
、git config
等),无需重复配置。
git worktree命令简明说明
// 列出当前所有worktree
git worktree list
// 创建基于特定分支的工作目录
git worktree add ../[目录名] [分支名]
// 删除特定的工作目录
git worktree remove ../[目录名]
感谢阅读,最后,愿天下的程序员都能需要一个好经理,不需要疯狂加班。
此文章由AI辅助完成