git仓库整理实战

4 篇文章 0 订阅
2 篇文章 0 订阅

你的硬盘空间被谁偷走了?

我们经常被问到:你们项目代码量有多大?这时候你可能会去机器上执行:

$ du -sh 项目名

来看一下你的项目文件夹占用了多大的空间,然后自豪的指着结果说:看!我们一个月写了五百兆!

但是,这是真的吗?你了解500m的代码有多少吗?

今天我们从一个空仓开始,研究一下你这‘500m’是怎么来的。

首先,我们创建一个带workspace的空仓,然后看一下大小:

$ git init gc_test;
$ cd gc_test
$ du -sh ./
100K    ./

只是100k,空仓嘛,可以接受。
向workspace中添加两个大文件呢?

$ cp ~/redis-2.8.3.tar.gz ./
$ cp ~/workspace.tar.gz ./
$ ll
total 15452
drwxrwxr-x  3 git git     4096  729 11:07 ./
drwxrwxr-x 12 git git     4096  729 10:51 ../
drwxrwxr-x  7 git git     4096  729 10:51 .git/
-rw-rw-r--  1 git git  1046106  729 11:07 redis-2.8.3.tar.gz
-rw-rw-r--  1 git git 14761335  729 11:07 workspace.tar.gz

在add之前,我们看一下.git的大小:

$ du -sh ./.git/
96K ./.git/

加入版本管理:

$ git add ./*
$ du -sh ./
31M ./
$ du -sh ./.git/
16M ./.git/

当你add之后,我们发现,仓库占的空间增加了一倍

接下来提交

$ git commit -m 'first commit'
[master(根提交) 71ea434] first commit
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 redis-2.8.3.tar.gz
 create mode 100644 workspace.tar.gz
$ du -sh ./
31M ./
$ du -sh ./.git/
16M ./.git/

如何将空间释放回来

是不是删除了以后空间就会被完全释放呢?

$ git rm redis-2.8.3.tar.gz workspace.tar.gz
rm 'redis-2.8.3.tar.gz'
rm 'workspace.tar.gz'
$ du -sh ./
16M ./
$ du -sh ./.git/
16M ./.git/
$ git commit -m 'remove redis and workspace'
[master 9dd3d25] remove redis and workspace
 2 files changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 redis-2.8.3.tar.gz
 delete mode 100644 workspace.tar.gz
$ du -sh ./
16M ./
$ du -sh ./.git/
16M ./.git/

哈哈,然而并没有!
现在我们也可以执行一个git命令来查看他的空间占用的详情

$ git ls-tree -l -r HEAD ./

我们看到仓库是workspace中啥也没有,那就是.git本身占了 16MB!

执行下面的命令,查找历史提交中删除了哪些文件,从中我们可以找到大文件的线索。即我们可以看到历史提交中删除了哪些大文件,这些大文件仍然保存在历史中。

$ git log --pretty="==== COMMIT %h ====" --stat --diff-filter=D --all
==== COMMIT 9dd3d25 ====

 redis-2.8.3.tar.gz | Bin 1046106 -> 0 bytes
  workspace.tar.gz   | Bin 14761335 -> 0 bytes
   2 files changed, 0 insertions(+), 0 deletions(-)

执行下面命令获取要删除的文件列表,并在每一行的前面自动添加 git 删除命令。

$ git log --pretty="==== COMMIT %h ===="   --stat --diff-filter=D --name-only --all |  sort -u | grep -v "^==== COMMIT" | grep -v "^$" |   sed -e 's/^\(.*\)$/git rm -r --cached --ignore-unmatch "\1"/g'  > /tmp/remove-trash-files.sh
$ cat /tmp/remove-trash-files.sh
git rm -r --cached --ignore-unmatch "redis-2.8.3.tar.gz"
git rm -r --cached --ignore-unmatch "workspace.tar.gz"

执行下面的命令对仓库的所有分支和所有 tags 执行过滤。从输出中我们可以看出部分提交中发现了垃圾数据,执行了清理动作。

$ git filter-branch --index-filter 'sh /tmp/remove-trash-files.sh' --tag-name-filter cat -f -- --all
Rewrite 9dd3d252adc1a640796c1a3811d255569712f3b7 (2/2)
WARNING: Ref 'refs/heads/develop' is unchanged
WARNING: Ref 'refs/heads/master' is unchanged

现在仓库是不是变小了呢?我们来看一下:

$ du -sh ./
16M ./

嗯?咋回事儿,为什么仓库没有变化呢,是不是我们上面哪儿有问题?
这其实是由于git对历史数据的保护造成的,在本地仍然有一些关联引用和reflog,在关联着这些数据,如果不删了这些关联数据和log,空间是不会被释放的。
1、删除ref中的备份引用:

$ git show-ref | awk '{print $2}' | grep refs/original/ | xargs -I{} git update-ref -d {}

2、清空reflog:

$ git reflog expire --expire=now --all

最后,还要执行gc进行垃圾回收,将所有松散对象都清除,否则这些松散对象仍然会被保留一段时间(gc好像是定期清除的,具体多长时间,怎么设置,可以通过帮助文档了解到)

$ git gc --prune=now --aggressive

现在我们来看一下仓库变成多大了:

$ du -sh ./
140K    ./

这个方法适合bare仓吗?应该是适合的,不过我没试~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李少辉-开发者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值