最近负责把团队内的git仓库做了一次分拆,解锁一个好用的工具git-filter-repo,给大伙抛砖一波,希望以后遇到类似场景时可以信手拈来。

背景

笔者团队目前是把业务相关的java项目都放到了一个git仓库中,发展初期项目较少放到一块图的就是一个方便,但是几年下来随着项目、人员、玩法等多了以后逐渐显现出一些问题,主要痛点有以下:
1.效率:更新代码缓慢,会下载很多我不关心的内容,既影响开发效率也影响jenkins打包的效率;
2.冲突:合并代码冲突率显著增高,而且一旦冲突往往很难解决,兄弟们苦不堪言,代码合并相互推诿;
3.权限:需要遵循最小范围、按需授权等原则最大限度保证代码不外泄,现有的“大锅饭”模式显然不满足。

期望

拆分以后每个项目一个git仓库,需要保留历史提交记录,方便以后回溯。

为了说明问题,上图是我以交易业务域为场景假想了一个简化版仓库,trade仓库下涵盖了三个java项目,分别是discount、order、paygate,拆分以后会变成discount、order、paygate三个仓库。

第一次尝试

我初次拿到这个任务的时候想,这个很简单啊,把trade复制三份然后分别改名为trade-order、trade-paygate、trade-discount,并把多余的删除,看起来像这样:

仓库拆分第一步似乎已经完成,接下来看看历史记录有没有丢失:

1.单个文件提交历史是否完整—右键order_readme.txt->git->show history(idea集成的查看文件git历史功能),很完整,没有问题。

2.新仓库提交历史是否完整—右键trade-order->git->show history,初看没什么问题,再看似乎不够完美,trade-order包含了拆分之前所有的提交历史,虽然不影响使用,但提交历史多了同样影响效率,必须再优化一波。

 

第二次尝试

第一次拆分之后的trade-order之所以包含所有提交历史是因为我选择的拆分策略是将原来的仓库复制出来然后删除多余的项目,对于提交历史并没有特殊处理,git的提交历史在.git目录下,真实的仓库.git目录接近900兆,这次的目标是将多余的提交历史剔除,靠人工剔除不现实,需要寻觅一款趁手的工具来行使清道夫的职责。

网络上对于git仓库拆分大致有三类工具,分别是subtree、filter-branch、filter-repo,filter-repo虽属后起之秀,似乎有取而代之前二者的趋势,同时前二者也有不少的追捧着,一时间不好抉择。

机缘巧合下看到了github官方的一篇文章https://docs.github.com/cn/get-started/using-git/splitting-a-subfolder-out-into-a-new-repository,里面提到的拆分工具也是filter-repo,我也就选择跟风一次,毕竟只是临时用到的一个工具,没必要花太多时间去选型,走不通了立马切换都来得及,毕竟试错的成本很低,这里顺便啰嗦一句,如果是一个技术框架、中间件的选型可不能这么草率,不能简单的说大厂都用了我们就用,还是要结合实际情况去斟酌,比如公司技术栈、团队人员配比、运维熟悉度等多纬度综合考虑,毕竟是要长期运行且替换的代价巨大。

关于git-filter-repo的下载安装请前往推荐阅读2中的地址自行获取,这里就不啰嗦,下面我们直接开始。

1.打开 Git Bash

2.克隆要拆分的仓库

git clone https://xxx/trade

3.将当前工作目录更改为您克隆的仓库

cd trade

4.要从仓库中的其余文件过滤出该子文件夹,请运行 git filter-repo,提供以下信息:

--path FOLDER-NAME:项目中您要从其创建单独仓库的文件夹。

git filter-repo --path order/

5.将仓库改名为trade-order

现在,该仓库应仅包含order目录下的内容。

验证下提交历史:

1.单文件提交历史没有问题,如下图

2.仓库整体提交历史没有问题,只包含order目录下文件的提交历史,没有把其他的带过来,如下图

这次应该是稳了,我跟同事炫耀我的劳动成果,迫切的希望得到他们的赞许,结果换来的却是另一个新问题:“这个结构是不是能优化下,现在仓库是两级trade-order/order,能不能只保留order这一级。”

第三次尝试

虽然上面的“trade-order/order“看起来也能用,但是多一级无用目录的确有点丑陋,而且会徒增新同学的困惑,说干就干,继续优化。

使用--subdirectory-filter指令保留order/下内容并将order提升为根目录

 git filter-repo --subdirectory-filter order/

现在目录变成了下面这样

trade-order/

    .git/

    doc/

       order_readme.txt

最后只需要将trade-order改名为order即可大工告成,提交历史也完整的保留了下来。

 

推荐阅读

1.https://docs.github.com/cn/get-started/using-git/splitting-a-subfolder-out-into-a-new-repository

2.https://github.com/newren/git-filter-repo

3.https://htmlpreview.github.io/?https://github.com/newren/git-filter-repo/blob/docs/html/git-filter-repo.html#EXAMPLES

文中只是提及了git-filter-repo的部分指令,更多有意思的玩法请前往推荐阅读3中的EXAMPLES自行解锁。

最后献图一张,下雨天拍到一只出来放风的小蜗牛

  

  

 

  

抛砖系列之git仓库拆分工具git-filter-repo的更多相关文章

  1. 抛砖系列之redis监控命令

    前言 redis是一款非常流行的kv数据库,以高性能著称,其高吞吐.低延迟等特性让广大开发者趋之若鹜,每每看到别人发出的redis故障报告都让我产生一种居安思危,以史为鉴的危机感,恰逢今年十一西安烟雨 ...

  2. git解决本地建立git仓库 连接远程git仓库出现拒绝合并问题

    (git解决本地建立git仓库 连接远程git仓库出现拒绝合并问题) 第一步在本地创建仓库 在本地创建一个文件夹,cd 进入创建的文件夹之后 git init 创建仓库 ,ls -a 能够看到 .gi ...

  3. git 仓库拆分方案对比

    此文已由作者张磊授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 前言 git 拆分仓库在网上已有的案例上来看,分为 submodule 和 subtree. 还有基于这两个方 ...

  4. 如何将硕大笨重的git仓库拆分成灵活轻巧的模块小仓库

    方法1.拆分一个子目录为独立仓库 参考链接:https://segmentfault.com/a/1190000002548731 以前是用 filter-branch 来实现,这个需求太常见了,有人 ...

  5. Git 仓库拆分

    方案对比 subtree 使用命令 git subtree split -P dirPath -b branchName 将目标文件夹的代码都保存到指定分支.试了下,该方案虽然保留了 commit,但 ...

  6. git仓库拆分

    例如: # 这就是那个大仓库 big-project $ git clone git@github.com:tom/big-project.git $ cd big-project # 把所有 `co ...

  7. 将在本地创建的Git仓库push到Git@OSC

    引用自:http://my.oschina.net/flan/blog/162189 在使用git 处理对android的修改的过程之中总结的.但不完善 Git push $ git push ori ...

  8. git 仓库迁移,git remote 更改源

    git仓库迁移 我们有时候需要迁移git仓库,但又想保留每次commit的记录,所以我们只需要更改git remote [源]的问题即可 首先查看你的remote的地址 git remote -vv ...

  9. 抛砖系列之-MySQL中的数据类型JSON

    今天介绍一个MySQL中的数据类型-JSON,相信大家对JSON都不陌生,在日常工作中使用到的频率也很高,话不多说,直接开始. 何谓JSON 看下RFC文档对于JSON的描述 1.基于 JavaScr ...

随机推荐

  1. 五种方式实现 Java 单例模式

    前言 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 这种模式涉及到一个单一的类,该类负责创建自 ...

  2. golang的defer踩坑汇总

    原文链接:http://www.zhoubotong.site/post/50.html defer语句用于延迟函数调用,每次会把一个函数压入栈中,函数返回前再把延迟的函数取出并执行.延迟函数可以有参 ...

  3. Pyinstaller打包pikepdf失败的问题排查

    问题 最近在项目里用到了pikepdf这个库,用于实现pdf水印插入的一个小功能,源码调试阶段运行一切OK但是在出包时报了如下异常. Traceback (most recent call last) ...

  4. Python教程——常用的os操作详情

    Python自动的os库是和操作系统交互的库,常用的操作包括文件/目录操作,路径操作,环境变量操作和执行系统命令等. 文件/目录操作 获取当前目录(pwd): os.getcwd() 切换目录(cd) ...

  5. NC202492 仓库选址

    NC202492 仓库选址 题目 题目描述 牛能在某小城有了固定的需求,为了节省送货的费用,他决定在小城里建一个仓库,但是他不知道选在哪里,可以使得花费最小. 给出一个 \(m \times n\) ...

  6. 6 分钟看完 BGP 协议。

    上一篇文章见 万字长文爆肝路由协议! 上面我们聊 RIP .OSPF 协议都是基于 AS 即自治系统内的协议,可以把它们认为是域内路由协议:而下面我们要聊的就是 AS 之间的协议了,这也叫做域间路由协 ...

  7. 攻防世界MISC—进阶区1-10

    1.something_in_image zip中的文件用010 Editor打开后直接搜索flag,即可找到flag 2.wireshark-1 zip内是pcap文件,打开后根据题目知道要寻找登录 ...

  8. 简记清空C语言输入残留内容

    为了在命令行程序中实现和用户的交互,我们编写的程序的运行过程中往往涉及到对标准输入/输出流的多次读写. 在C语言中接受用户输入这一块,有着一个老生常谈的问题:"怎么样及时清空输入流中的数据? ...

  9. JUC源码学习笔记2——AQS共享和Semaphore,CountDownLatch

    本文主要讲述AQS的共享模式,共享和独占具有类似的套路,所以如果你不清楚AQS的独占的话,可以看我的<JUC源码学习笔记1> 主要参考内容有<Java并发编程的艺术>,< ...

  10. 在CentOS上安装MPI以及MPI入门编程笔记

    一.准备工作 更新yum库 yum update 下载相关依赖包 yum install wget -y yum install gcc gcc-c++ gcc-fortran kernel-deve ...