Git 仓库过大问题分析处理

背景

近期需要对一个项目进行一些小更改,仓库本身是很小的,但是在 git clone 项目的时候却等待了很久。如图:

不禁产生了疑惑,10M体积左右的仓库为何会产生200多M的数据?

原因分析

通过执行命令 du -d 1 -h 可以分析出当前项目各个文件的体积:

可以看出是 .git 文件占了主要的占比,进入目录详情查找发现,是有一个 .pack 文件特别大。

通过查找相关资料发现:

  • 当使用 git addgit commit 命令的过程中,Git 不知不觉就会创建出来 blob 文件对象,然后更新 index 索引,再然后创建 tree 对象,最后创建出 commit 对象,这些 commit 对象指向顶层 tree 对象以及先前的 commit 对象。
  • 而上述创建出来的对象,都以文件的方式保存在 .git/objects 目录下。所以,当在使用的过程中,提交了一个体积特别大的文件,就会被 Git 追踪记录在 .git/objects 文件夹下面。
  • 此时,如果再次删除这个体积特别大的文件,其实 Git 只会记录我们删除的这个操作,但并不会把文件从 .git 文件夹下面真正的删除,即 .git 文件夹完全不会变小。

解决方案

  1. 识别出体积最大的几个文件(demo数量为5)
shell 复制代码
git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5 | awk '{print$1}')"

我们发现基本都是些字体、图片等静态文件。可以和当前目录文件进行对比,看哪些是已经废弃的,可以进行删除操作。

  1. 将该文件从历史记录的所有 tree 中移除
shell 复制代码
git filter-branch --force --index-filter 'git rm -rf --cached --ignore-unmatch 你的大文件名' --prune-empty --tag-name-filter cat -- --all

public/font/PingFangSC-Regular.otf 为例,删除前后对比如下:

  1. 重复2的操作即可,确保删除的文件是已失效
  2. 提交修改
shell 复制代码
# 真正删除
rm -rf .git/refs/original/
git reflog expire --expire=now --all
# 清理无效文件
git gc --prune=now 
git gc --aggressive --prune=now
git push --force

# 让远程仓库变小
git remote prune origin

总结

避免项目中直接存放大文件,使用对象存储/CDN的方式引用这些静态文件。

相关推荐
玖釉-4 分钟前
解决PowerShell执行策略导致的npm脚本无法运行问题
前端·npm·node.js
Larcher38 分钟前
新手也能学会,100行代码玩AI LOGO
前端·llm·html
徐子颐1 小时前
从 Vibe Coding 到 Agent Coding:Cursor 2.0 开启下一代 AI 开发范式
前端
小月鸭1 小时前
如何理解HTML语义化
前端·html
FrankYoou1 小时前
git stash push 命令作用及使用场景
git
jump6801 小时前
url输入到网页展示会发生什么?
前端
诸葛韩信1 小时前
我们需要了解的Web Workers
前端
brzhang2 小时前
我觉得可以试试 TOON —— 一个为 LLM 而生的极致压缩数据格式
前端·后端·架构
yivifu2 小时前
JavaScript Selection API详解
java·前端·javascript
这儿有一堆花2 小时前
告别 Class 组件:拥抱 React Hooks 带来的函数式新范式
前端·javascript·react.js