【经验分享】git项目.git/objects/pack很大,clone很久,object文件清理

目录

问题现象:

解决办法:

目前实践方法2,步骤如下:

1.识别出最大的三个文件

2.查询大文件的文件名称:

3.将文件从tree中移除

4.清理和回收空间

5.提交修改远程仓库


问题现象:

gitlab项目12G,但实际项目就几百兆,后本地排查,发现pack文件过大,特此记录一下,object文件清理问题。

找了一下原因,.git/objects/pack 文件过大,可能是由于开发过程中上传过大文件,虽然现已删除,但仍然保存着git记录中。

就比如每次npm run build生成dist,需要打包到服务器,这个可能就上传到记录中了。

git项目越来越大的原因:

git addgit commit 的过程中,保存修改了的文件的 blob,更新索引,创建 tree 对象,最后创建 commit 对象,这些 commit 对象指向了顶层 tree 对象以及先前的 commit 对象。这三类 Git 对象 ── blobtree 以及 commit ── 都各自以文件的方式保存在 .git/objects 目录下。

所以,当你提交了一个体积特别大的文件后,会记录在 objects 文件夹下,删除一个文件,只是记录了删除这个操作,但并不会把文件从 .git 文件夹删除。 当你直接从项目中删除该文件,.git 文件夹完全不会变小(理论上还会变大一点,因为多记录了一次删除操作。。。)

解决办法:

1.新建一个只有master分支的当前版本的新项目,原项目做备份或删除;

2.彻底删除历史记录,清理object文件大小。

补充一点, 如果你想以后也不会再上传这个文件或文件夹, 请把这个文件或文件夹添加到.gitignore文件里, 然后再push你的项目

目前实践方法2,步骤如下:

1.识别出最大的三个文件

进入项目根目录,在git bash 中执行

bash 复制代码
git verify-pack -v .git/objects/pack/pack-*.idx | sort -k 3 -n | tail -3

命令解析:

verify-pack 命令用于显示已打包的内容,我们用它来找到那些大文件。

-v(verbose)参数是打印详细信息。

--objects:列出该提交涉及的所有文件ID

执行结果:

bash 复制代码
f4bcfa14220885922ca311a9b97ab6a087269057 blob   1194049978 1193418168 7030313773
9e91faabd113ac69a6534c50a8dc3718f556b20c blob   1237993230 1237347387 10317735659
c7d414a597a838e9174fc68ae4fbe78aa8084b91 blob   1237993230 1237347335 9080388324

2.查询大文件的文件名称:

执行命令:

bash 复制代码
git rev-list --objects --all | grep f4bcfa14220885922ca311a9b97ab6a087269057

命令解析:

rev-list 命令用来列出Git仓库中的提交,我们用它来列出所有提交中涉及的文件名及其ID。 该命令可以指定只显示某个引用(或分支)的上下游的提交

--objects:列出该提交涉及的所有文件ID

--all:所有分支的提交,相当于指定了位于 /refs 下的所有引用

执行结果:

bash 复制代码
f4bcfa14220885922ca311a9b97ab6a087269057 dist-aidmav3.1.5-2020091502.zip

3.将文件从tree中移除

执行命令:

bash 复制代码
git filter-branch --index-filter 'git rm --cached --ignore-unmatch  dist-aidmav3.1.5-2020091502.zip'

命令解析:

filter-branch命令可以用来重写Git仓库中的提交。

--index-filter参数用来指定一条Bash命令,然后Git会检出(checkout)所有的提交, 执行该命令,然后重新提交。

4.清理和回收空间

虽然上面我们已经删除了文件, 但是我们的repo里面仍然保留了这些objects, 等待垃圾回收(GC), 所以我们要用命令彻底清除它, 并收回空间.

执行命令:

bash 复制代码
$ rm -rf .git/refs/original/

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

$ git gc --prune=now

# Counting objects: 2437, done.
# Delta compression using up to 4 threads.
# Compressing objects: 100% (1378/1378), done.
# Writing objects: 100% (2437/2437), done.
# Total 2437 (delta 1461), reused 1802 (delta 1048)

$ git gc --aggressive --prune=now

# Counting objects: 2437, done.
# Delta compression using up to 4 threads.
# Compressing objects: 100% (2426/2426), done.
# Writing objects: 100% (2437/2437), done.
# Total 2437 (delta 1483), reused 0 (delta 0)

命令解析:

git-reflog 管理reflog信息

--expire=<time> 剪除比指定时间更早的条目。如果未指定此选项,则从配置设置中获取到期时间,而配置设置gc.reflogExpire又默认为90天。--expire=all不论年龄大小,都能修剪; --expire=never关闭修剪可及条目。

expire 命令修剪旧的reflog条目

--all 处理所有引用的reflog

git gc 清理不必要的文件并优化本地存储库

--aggressive 通常git gc运行速度很快,同时提供良好的磁盘空间利用率和性能 此选项将导致git gc更积极地优化存储库,但花费更多时间。这种优化的效果是持久的,所以这个选项只需要偶尔使用。

--prune=<date> 修剪比日期更旧的松散对象(默认为2周前,可由配置变量覆盖gc.pruneExpire)。--prune =不管年龄大小,都修剪松散的物体,并且如果另一个进程同时写入存储库,则会增加腐败风险; 请参阅下面的"注意事项"。--prune默认打开

详细学习《git gc》《git reflog

现在你再看看你的.git目录文件大小是不是变小了。

5.提交修改远程仓库

执行命令:

bash 复制代码
git push origin master --force

git remote prune origin

参考学习:

git目录下object文件过大清理_git object 特别大-CSDN博客

彻底删除git中的大文件 - 简书

https://www.cnblogs.com/shines77/p/3460274.html

最后

如果说

友友们之间的点赞

展现的是相互之间的支持,善意和友情

那么

你对我文章的认真阅读

则是对我的劳动成果的

默默地承认和支持

每一次创文的过程

都是我锻炼自己逻辑思维能力和语言组织能力的过程

也是我

不断深悟生活,思考人生的过程

每一篇文章的形成

都是我心血的结晶

能有幸被你阅读

欢迎点赞,评论,互关!~~

相关推荐
deja vu水中芭蕾2 小时前
git push origin HEAD:refs/for/分支名
git
海岛日记6 小时前
git常用操作
git
喝鸡汤6 小时前
一起学Git【番外篇:如何在Git中新建文件】
git
“αβ”6 小时前
Windows下使用git配置gitee远程仓库
git
谢家小布柔11 小时前
Git图形界面以及idea中集合Git使用
java·git
winner888113 小时前
git merge 冲突 解决 show case
java·git·git merge·git冲突
玩电脑的辣条哥17 小时前
怎么给git动图扣除背景?
git·抠图
谢家小布柔18 小时前
git中的多人协作
git
isolusion19 小时前
git分支管理及策略
git
isolusion20 小时前
git仓库的基本概念和流程以及一些基本命令
git