git文件过大,怎么办?

强烈推荐一个大神的人工智能的教程:http://www.captainbed.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.实践出真知。

发布了291 篇原创文章 · 获赞 2657 · 访问量 536万+

猜你喜欢

转载自blog.csdn.net/u012829124/article/details/89043903