赞
踩
强烈推荐一个大神的人工智能的教程:http://www.captainai.net/zhanghan
最近遇到一个git文件过大的问题,针对这个问题进行了研究,在此与大家共享。
一、问题
我们需要改造一个别的团队开发的系统;开始的时候将代码以及和代码相关的一些东西放到了我们的gitLab上;团队进行了相关改造;在第一次拉git的时候就感觉很慢,当时也没留意;后来开发完成提测往服务器上部署时,运维写脚步从git上拉,发现需要5分钟左右,这时发现git上拉下项目竟然达到200多M;针对git文件过大进行了研究。
二、解决思路
1、将本git上和代码不相关的东西迁移到其他git工程中;
2、将相关代码迁移到新的git工程中;
三、相关验证
1、验证两种方案验证顺序:
第一种思路(将git中非代码部分迁移到其他git工程中)的优点是开发人员都不需要做变动是首选方案;第二种方案是备选方案;
2、验证场景以及注意事项说明:
(1)在做实验前将git进行备份,防止操作失误后代码丢失;
(2)git代码管理服务是gitLab;
(3)演示项目介绍:
gitLab初始化项目各个文件大小示意图(大文件mybatis-generator-gui-0.0.81.zip;正常代码 zh-boot):
3、验证第一种思路(将git中非代码部分迁移到其他git工程中)
(1)将git上的大文件删除(大文件mybatis-generator-gui-0.0.81.zip),只留68k的代码就可以了,但是发现文件还是这么大;查看一下大文件发现.git还是这么大。
(2)为什么那?突然想起了git的机制,git为了实现可以回滚所以每次操作步骤都做了记录;自然之前删除的大文件也在历史中;
(3)在百度后发现普遍说的一种方式可以做;
a.显示10个最大的文件id列表(最大的文件在最下面)
git verify-pack -v .git/objects/pack/pack-*.idx | sort -k 3 -g | tail -10
结果如下:
- 6ca04e6a75ac4b08e052ed34129d5409b44da4f7 blob 3360985 3066990 74503381
- 59c543c3bd41ea928b6f110d9f8d37254977cf62 blob 3658840 3388676 100771642
- 59c543c3bd41ea928b6f110d9f8d37254977cf62 blob 3658840 3388676 84926187
- 9b01e9abea6a3636a0ade1cf4a889e83b177e32b blob 4598259 4580245 73721111
- 9b01e9abea6a3636a0ade1cf4a889e83b177e32b blob 4598259 4580245 89566566
- fe5de1d7e2ae18cbbe72339d59906a4a0e2dc571 blob 4865948 4866558 199142126
- 146b41346c4c4ae764d54e5423c4707562b00490 blob 7822670 7212799 61725098
- 146b41346c4c4ae764d54e5423c4707562b00490 blob 7822670 7212799 77570371
- 8c115dd9823d57f7e79b1b11c385f987cb55c189 blob 10902635 10111415 188376770
- 37d9dd20adba18ed8ad0acdbcb7079ec6a984927 blob 80721029 79217509 107499086
b.根据文件id查询文件路径
git rev-list --objects --all | grep 37d9dd20adba18ed8ad0acdbcb7079ec6a984927
结果如下:
37d9dd20adba18ed8ad0acdbcb7079ec6a984927 mybatis-generator-gui-0.0.81.zip
c.移除文件
git log --pretty=oneline --branches -- mybatis-generator-gui-0.0.81.zip
结果如下:
- 079952b172af04b121345b731025a681d92f8a25 up
- 0b5cd2661e9612e5e046da3939dd9cd34936821a init
d.删除文件的历史记录
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch --ignore-unmatch mybatis-generator-gui-0.0.81.zip' --prune-empty --tag-name-filter cat -- --all
结果如下:
- Rewrite 0b5cd2661e9612e5e046da3939dd9cd34936821a (77/334) (68 seconds passed, remaining 226 predicted) rm 'mybatis-generator-gui-0.0.81.zip'
- Rewrite 1bb147ec94579b8686c433bc5f9fa63371599b1f (77/334) (68 seconds passed, remaining 226 predicted) rm 'mybatis-generator-gui-0.0.81.zip'
- Rewrite 2382457f5ac6dfabec05dd30e5f80a5df398972a (79/334) (69 seconds passed, remaining 222 predicted) rm 'mybatis-generator-gui-0.0.81.zip'
- Rewrite 72b16e5e96d832df163510c780ff08b43cecc43f (333/334) (298 seconds passed, remaining 0 predicted)
- Ref 'refs/heads/dev' was rewritten
- Ref 'refs/heads/master' was rewritten
- Ref 'refs/remotes/origin/master' was rewritten
- Ref 'refs/remotes/origin/dev' was rewritten
- WARNING: Ref 'refs/remotes/origin/master' is unchanged
- image-pro -> image-pro (7103278a5ff3e92fa4f1d918cc507bd0eac43585 -> 6fc04e8465918b4ead17176c868eff40f20620d8)
e.提交
git push --force --all
执行结果如下:
这个错是个什么意思那?在gitLab上最终查找到了原因,是gitLab为了安全,在保护的分支上禁止了强制推送功能(强制推送的意思是强制将本地的代码覆盖服务器的代码);无论是什么权限都无此权限;详情如下图:
如何解决这个问题那?设置---》保护分支---》取消保护分支 后然后推送就解决该问题了
f.清除本地缓存
- rm -Rf .git/refs/original
- rm -Rf .git/logs/
- git gc
- git prune
(4)当然这样一步一步手动执行慢的很,让运维帮忙写了个自动化脚本(一次删除最大的10个,可以修改个数),这样很快就将大文件的记录删除完了,git立马小了下来。
- #!/bin/bash
-
-
- COMM=`git verify-pack -v .git/objects/pack/pack-*.idx | sort -k 3 -g | tail -10 >1.txt`
-
- for value in `cat 1.txt |awk '{print $1}'`
- do
- git rev-list --objects --all | grep "${value}" >2.txt
- a=`cat 2.txt |awk '{print $2}'`
- git log --pretty=oneline --branches -- ${a}
- git filter-branch --index-filter "git rm --cached --ignore-unmatch ${a}" -- --all
- git push --force
- rm -Rf .git/refs/original
- rm -Rf .git/logs/
- git gc
- git prune
- done
(5)当然关闭保护分支是十分危险的(哪个阿猿不小心强推上去就完蛋了),进行清理完后将保护分支再次开启:
(6)效果:经过删除大文件的记录,git大小从原来的364M降到了60M(纯代码是这么大,因为本系统代码未做前后端分离一些静态资源在里面占用空间大,后续会把静态资源挪到新工程中由前端同事来维护)。
4、第二种思路(将相关代码迁移到新的git工程中)操作比较简单,在此不再赘述。
四、结论
当然如果感觉第一种思路(将git中非代码部分迁移到其他git工程中)比较麻烦,且开发人员不多的情况下,可以简单粗暴使用第二种思路(将相关代码迁移到新的git工程中)然后让开发人员更换到新的git上即可。
1.不讲究是发现的源动力;
2.实践出真知。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。