git 仓库缩减空间

39 阅读3分钟

第一步:安装 BFG 命令行工具

BFG 依赖 Java 环境,所以确保电脑上已经安装了 Java。然后去官网下载 jar 包,例如 bfg-1.14.0.jar。然后在命令行创建别名:

sh
复制代码
alias bfg='java -jar /xxxx/bfg-1.14.0.jar'

如果是 Mac 的话,可以直接用 brew 来安装:

sh
复制代码
brew install bfg

第二步:下载镜像仓库

命令是:

sh
复制代码
git clone --mirror git://example.com/your-repo.git

git clone 命令实现版本库克隆,主要有如下三种用法:

  1. git clone <repository> <directory>
  2. git clone --bare <repository> <directory.git>
  3. git clone --mirror <repository> <directory.git>

这里采用第三种,即带 --mirror 参数的。你可能会问,这三种有什么区别呢?

  • 用法1将 <repository> 指向的版本库创建一个克隆到 <directory> 目录。目录 <directory> 相当于克隆版本库的工作区,文件都会检出,版本库位于工作区下的 .git 目录中。
  • 用法2和用法3创建的克隆版本库都不含工作区,直接就是版本库的内容,这样的版本库称为裸版本库。一般约定俗成裸版本库的目录名以.git为后缀,所以上面示例中将克隆出来的裸版本库目录名写做 <directory.git>
  • 用法3区别于用法2之处在于用法3克隆出来的裸版本对上游版本库进行了注册,这样可以在裸版本库中使用 git fetch 命令和上游版本库进行持续同步。

如果仓库较大,建议下载完了之后,先用下面的命令备份一下,方便等会操作失误重做。

sh
复制代码
cp -r your-repo.git your-repo-backup.git

第三步:执行清理命令

根据需要,运行 bfg 命令,例如清理所有超过 10M 的文件:

sh
复制代码
bfg --strip-blobs-bigger-than 10M your-repo.git

清理前 100 大的文件:

sh
复制代码
bfg --strip-biggest-blobs 100 your-repo.git

指定文件或按照通配符清理文件:

sh
复制代码
bfg --delete-files "node.exe" your-repo.git
bfg --delete-files "*.zip" your-repo.git

保护指定分支(默认是master),这个命令非常有用,表示哪些分支的最新提交后的文件不要删除:

sh
复制代码
bfg --protect-blobs-from master,feat/latest --delete-files "*.zip" your-repo.git
bfg --protect-blobs-from master,dev,stage --strip-biggest-blobs 100 your-repo.git

当然,如果你不想在任何分支中看到这个文件的话,可以这么写:

sh
复制代码
bfg --delete-files "*.zip" --no-blob-protection your-repo.git

bfg 非常棒的地方是,每次命令都会生成日志,放在跟 your-repo.git 仓库平级的 your-repo.git.bfg-report 目录下,有个 deleted-files.txt 可以清晰的看到哪些文件被删除了,例如:

第四步:更新 Git 历史

确定第三步想要清理的命令都执行完了,运行下面的命令对仓库历史进行改写,运行速度会比较慢:

sh
复制代码
cd your-repo.git
git reflog expire --expire=now --all && git gc --prune=now --aggressive

第五步:提交到远程仓库

到目前为止,所有的操作还只是本地的,需要把瘦身过的仓库提交到远程:

sh
复制代码
cd your-repo.git
git push --mirror

这个时候,仓库的历史才被真正改写了,重新 clone 之后,将获得瘦身后的仓库。

不过在多人协作的时候,你要告诉所有协作者删除本地旧仓库,重新 clone 新仓库,如果某些小伙伴一不小心又把本地旧仓库 push 上去,你的工作都白做了...

所以为了彻底防止上述情况发生,也可以重新建一个新仓库,用下面的命令改写 origin 地址,push 到新仓库,通知所有人下载这个新仓库即可:

sh
复制代码
cd your-repo.git
git remote set-url origin your-new-repo.git
git push --mirror

命令

// 印项目中前五个大的文件
git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5 | awk '{print$1}')"
//找出项目中大于20M的文件
jva -jar bfg-1.14.0.jar --strip-blobs-bigger-than 20M Springboot-Notebook.git
//删除项目中文件/文件夹
 java -jar bfg.jar --delete-files 清理的文件名 本地项目git地址
 
 
 java -jar bfg.jar --delete-folders 清理的文件夹名字 本地项目git地址
 
//清理无效文件 要在.git目录中执行命令
git reflog expire --expire=now --all && git gc --prune=now --aggressive