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
相关推荐
si莉亚10 小时前
ROS2安装EVO工具包
linux·开发语言·c++·开源
清心歌10 小时前
CopyOnWriteArrayList 实现原理
java·开发语言
智者知已应修善业11 小时前
【51单片机单按键切换广告屏】2023-5-17
c++·经验分享·笔记·算法·51单片机
良木生香11 小时前
【C++初阶】C++入门相关知识(2):输入输出 & 缺省参数 & 函数重载
开发语言·c++
小此方11 小时前
Re:从零开始的 C++ 进阶篇(三)彻底搞懂 C++ 多态:虚函数、虚表与动态绑定的底层原理
c++
忘梓.11 小时前
墨色规则与血色节点:C++红黑树设计与实现探秘
java·开发语言·c++
hhh3u3u3u11 小时前
Visual C++ 6.0中文版安装包下载教程及win11安装教程
java·c语言·开发语言·c++·python·c#·vc-1
凤年徐11 小时前
C++手撕红黑树:从0到200行,拿下STL map底层核心
c++·后端·算法
星河耀银海11 小时前
C++ 模板进阶:特化、萃取与可变参数模板
java·开发语言·c++
cccccc语言我来了11 小时前
【C++---unordered_set/map底层封装】个不拘一格的集合。它不似有序集合那般循规蹈矩,而是以一种洒脱不羁的方式,将元素们随意地散落其中。每一个元素都是独一无二的。
开发语言·c++·哈希算法