最近做系统拆分,原来有一个业务在其他业务部门的代码仓库内,需要把这个业务从他们代码仓库拆出来。

于是fork过来后,发现这个git仓库体积太大了,足足 1.5G ,明明代码部分其实就到顶也就 9M,只保留我们自己业务部分的代码,其实大小也就只有1.2M。但是历史的提交,都在.git文件夹内,于是就有了这个奇观。

因为当初做 CICD 的时候,用的是一种很奇怪的方式实现的。之前在CD部署的过程,是把npm run build 出来的静态资源文件,再一次提交到了当前仓库内,于是随着公司业务的不断发展,终于变成了今天这个体积。还好,现在有了新的CICD流程,这种不合理的构建流程算是废弃了。但是还有如下这些问题要解决。

  • 给仓库减肥瘦身
  • 同时保留仓库的历史提交记录

先看看瘦身成果:

result

对比瘦身前:

old

BFG

工欲善其事必先利其器。调研一波,选了工具 BFG

bfg

Mac下直接homebrew安装 brew install bfg

准备工作

  1. 克隆镜像仓库(分身)

    1
    
     git clone --mirror your-repo.git
    
  2. 克隆仓库本体

    1
    
     git clone  your-repo.git
    
  3. 安装 ggrep,因为我们会用到支持 perl的命令 -P,但是Mac上的grep版本未集成,于是装一个 gnu-grep。

    1
    
        brew install grep
    

装好后,再加到 .zshrc 里面。 export PATH ="/usr/local/opt/grep/libexec/gnubin:$PATH"

我们有了本体也有了分身,就好办事了。

瘦身

首先,我们需要知道该删掉什么东西。

1.找出该删什么文件。

之前编译后的静态资源都在这里:

bfg

那么我们只要找出来这些内容就好。也有一种删除文件夹都操作,但是我一直失败不成功,于是找了github上的这个 issue提供的方法。 先CD到本体仓库

1
 git rev-list --all --objects -- public/b_static | git cat-file --batch-check='%(objectname) %(objecttype) %(rest)' | ggrep -Pe '^\w+ blob' | cut -d' ' -f1 > ./to-delete.txt

这里就是遍历出了文件夹下的所有需要删除的 object id,并输出到当前目录下。

id

2.瘦身 cd 到刚刚的分身仓库。上一步拿到了肃清名单,现在就要根据名单开始排队枪毙了(bushi

1
          bfg --no-blob-protection --strip-blobs-with-ids ../本体/to-delete.txt ./分身

3.推回原仓库(失败了)

id

–force 也不行(不知道这个命令后果到话不推荐尝试哈)

4.曲线救国 查了一些stackoverflowissueissuegitlab,看来是有一些保护措施,拒绝了我的重写。 于是我打算,另建一个项目仓库,然后把这些推到新仓库内。 在分身的目录下执行

1
git remote rename origin backup | git remote add origin 新仓库.git | git push --set-upstream origin master | git push --all origin  | git push --tags origin

这里就包含了切换origin、push 所有分支和tag。

后记

最终,副本干掉了原来本体,本质上本体和副本有着相同的记忆,相同的能力,总让我想起十多年前看的科幻小说「副本」,挺有意思的,推进给大家。

「副本」

-EOF-