Git-git worktree的使用

用了git这么多年,居然第一次听说git worktree,于是搜索了一番学习记录一下。

我们知道,一个git仓库可以对应多个分支,通常来说都有一个主分支,例如master或develop,每个研发在日常进行功能开发的时候,都基于develop创建新的feature分支,代码写好以后合并到主分支。那么你可能遇到过这种场景:你还在feature分支开发,此时突然遇到一个紧急的bug需要你在develop分支提交代码。此前我的做法通常是:

复制代码
1. 把当前所有更改全部提交到一个临时的commit,push到远端防止丢失
2. git checkout到develop分支,git pull拉最新代码
3. git checkout -b hotfix分支
4. 改bug完成后hotfix合并到develop
5. git checkout 到feature分支
6. 继续开发feature

还有的小伙伴可能是:

复制代码
复制一个目录,然后直接在新目录切develop分支改bug

实际操作下来会发现,在3-4步骤之间以及5-6步骤时间,需要配置cmake以及构建程序,此时由于两个分支之间有差异,checkout的速度以及cmake+build的速度实在不尽如人意,尤其是在分支差异很大的时候,这种感觉更加明显,因为差异文件越多,checkout的文件需要越多,由于源码变更,很多时候几乎要把整个项目重新编译,这种时候会发现checkout的"成本"很高。

复制目录的方式,短期内看起来能解决问题,但是一个10g的项目在磁盘上拷贝一份就变成20g,分支再多点就不敢想象。并且对于每个工作区目录,如果要同步git仓库状态,只能先将一个目录的状态push到远端,然后在另一个目录git pull进行同步,略显繁琐。

说了这么多,终于轮到git worktree出场了:)既然一个git仓库能对应多个分支,那么为什么一个git仓库不能对应多个工作区目录呢?遇到上面的场景,我们只需要在当前项目根目录执行

bash 复制代码
git worktree add ../Project-hotfix develop

此时就会在上一层目录生成一个Project-hotfix目录,这个目录是另一个工作区,对应的分支是develop。我们cd ../Project-hotfix就可以进到另一个工作区,git pull之后,就可以开始愉快的修bug了。分支hotfix结束后,我们如果希望删除这个工作目录,执行:

bash 复制代码
git worktree remove ../Project-hotfix

要查看当前有哪些worktree,使用:

bash 复制代码
git worktree list

那么和之前的方法比有什么优势呢?我们逐个分析

  1. 相比于checkout,添加一个新的工作区,使得C++编译的obj文件相互独立,即使分支差异很大,只有第一次创建工作区以后需要在新工作区进行一次比较长时间的build,原工作区完全不受影响。因此对比两次checkout后的build "成本",我们相当于少了一次。并且如果以后经常需要在不同分支切换,我们不需要将这个工作区删除,节省的build成本就更多了
  2. 我们的不同工作区之间,不需要通过远端同步,一个目录的分支和commit变更,分支信息实时同步到其他目录,这是因为创建出来的worktree使用的git信息实际上是引用原目录的.git目录的,在Project-hotfix下可以看到.git变成一个文件,文件内容指向原目录的.git文件夹。
  3. 新工作区目录的大小比原目录小很多,原因如第二点所述,有相当一部分信息都复用了原始目录.git文件夹中的信息

由此可见,在这种场景下,从时间、速度、磁盘利用等角度来看,git worktree都比原有的方法更加方便、高效。这里贴一个链接,可以看看还有哪些场景适合使用git worktree。

参考:

  1. https://git-scm.com/docs/git-worktree
  2. https://stackoverflow.com/questions/31935776/what-would-i-use-git-worktree-for
相关推荐
吃好睡好便好2 分钟前
用for循环语句求和
开发语言·人工智能·学习·matlab·学习方法
萌新小码农‍2 分钟前
人工智能数学基础+python实例(人工智能学习day3)
开发语言·人工智能·python
Lumbrologist5 分钟前
【C++】零基础入门 · 第 1 节:第一个程序 Hello World 与编译运行
开发语言·c++
超梦dasgg22 分钟前
Java 生产环境 MQ 技术选型全解析
java·开发语言·java-rocketmq·java-rabbitmq
_李小白38 分钟前
【C++学习笔记】新特性之inline变量
c++·笔记·学习
桀人1 小时前
C++——模板初阶(收录在专栏C++入门到精通)
开发语言·c++
一直有一个ac的梦想1 小时前
cmu15445 2025fall lec 18 transactions with two-phase lock
java·开发语言·数据库
JAVA社区1 小时前
Java进阶全套教程(四)—— SpringMVC框架详解
java·开发语言·spring·面试·职场和发展
Lumbrologist1 小时前
【C++】零基础入门 · 第 2 节:变量、基本数据类型与输入输出
java·开发语言·c++