一、背景
git库擅长管理文本型的文件,二进制文件一版不建议用git管理。
现在我们已经用git管理的二进制文件,并且已经有了上百个提交,多个分支,且存储的二进制文件的总和已经相当庞大(可能几十个G,上百G)。
这给我们的git管理带来了以下3问题。
1. 下载时间长。简单的git clone会把整个库clone下来,例如这个库100G(夸张点),我们的下载速度100M/s,clone整个库大概就需要1000s(约20分钟)。
2. 浪费的我们的存储。试问我们的pc/服务器能够储存几个这样的库。
3. 二进制的提交记录毫无意义。
由于这种种原因,我们不得不给.git进行瘦身。
二、解决方案。
1. 在本地对git log进行压缩。如图所示的压缩方式。
branch_A | 说明 | branch_A_new |
patch 101 | 保留最新的提交,并cherry-pick到branch_A_new中。 | patch 101~ |
patch 100 | 把patch压缩成一个。patch1-patch99的数据就是成为了无效数据(即commit/tree/blob,我们没有办法获取到) | patch 1~ |
patch 99 | ||
... | ||
patch 2 | ||
patch 1 | ||
init git | 第一个提交保留不变 | init git |
2. 把branch_A_new强制push到服务器中。
git push -f origin branch_A_new:branch_A
3. 在服务器端的该xx.git库中执行git -c清理git库。
#查看git库中悬空对象(dangling objects)(没有分支跟踪的commit/tree/blob),执行结果会返回悬空对象。可反复使用查看。
git fsck --unreachable --no-reflogs
#应用git gc删除悬空对象(dangling objects)
git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc
#此命令可来源:
file - How to remove unused objects from a git repository? - Stack Overflow
4. 查看xx.git库的大小。
#查看瘦身后的xx.git的大小,发现已经瘦身成功。
du -hs xx.git
三、对xx.git库副作用
1. git log信息被裁剪
2. commit的号的哈希值被修改。
3. tag所能到达的commit/tree/blob 是无法清理。如需清理,只能先删除tag。