如有错误和建议请评论告知。
Git 版本库如何瘦身?
随着git仓库的使用,仓库的体积越来越大,主要是.git
文件夹记录了所有的历史记录。它能否“瘦身”呢?又该如何操作呢?
查看仓库的存储统计信息
$ git count-objects -vH
count: 91
size: 888.88 KiB
in-pack: 1250
packs: 1
size-pack: 112.77 MiB
prune-packable: 0
garbage: 0
size-garbage: 0 bytes
由结果可知松散对象占用不大(count
和size
),冗余打包数量为0(prune-package
),垃圾文件占用为0(garbage
和size-garbage
)。但是打包文件占用过大(size-pack
),这意味着项目历史过长或者有较多的大文件。
清理无用的文件
上面的情景无需执行这一步。
git gc --prune=now
优化size-pack打包体积
查出问题根源
1.识别大文件/历史对象
# 列出仓库中占用空间最大的文件(按大小排序)
git rev-list --objects --all |git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' |grep '^blob' | sort -k3 -n -r | head -n 20# 或使用可视化工具(需安装 git-extras)
git big-files -n 20
2.分析pack文件内容
# 查看打包文件的详细内容(显示每个对象大小)
git verify-pack -v .git/objects/pack/*.idx | sort -k3 -n -r | head -n 20
清理历史大文件
https://nyakku.moe/posts/2020/06/12/use-git-filter-repo-clean-git-history.html
使用 git filter-repo 重写历史
https://github.com/newren/git-filter-repo
# 安装(需 Python 环境)
$ pip3 install git-filter-repo
Collecting git-filter-repoDownloading git_filter_repo-2.47.0-py3-none-any.whl.metadata (31 kB)
Downloading git_filter_repo-2.47.0-py3-none-any.whl (76 kB)
Installing collected packages: git-filter-repo
Successfully installed git-filter-repo-2.47.0
-----------------------------------------------
# 用法1: 删除指定文件(如 bigfile.zip)
git filter-repo --path bigfile.zip --invert-paths
-----------------------------------------------
# 用法2: 清理指定文件夹(如临时目录)
git filter-repo --path tmp/ --invert-paths
-----------------------------------------------
# 用法3: 删除超过 1MB 的文件
# 克隆新仓库并拉取所有分支
git clone <原仓库URL> new-repo
cd new-repo
git fetch --all# 清理所有分支的大文件(明确指定 --all)
git filter-repo --strip-blobs-bigger-than 1M --all# 修复 origin/HEAD
git remote set-head origin main# 强制推送所有分支和标签
git push origin --force --all
git push origin --force --tags# 协作者操作(需重新克隆或强制重置)
git clone <新仓库URL> # 推荐协作者直接重新克隆
# 或
# 若有未推送的更改
# 备份当前分支
git checkout -b backup-branch
# 拉取新历史并强制重置
git fetch origin
git checkout main
git reset --hard origin/main
# 删除旧分支引用(可选)
git for-each-ref --format='%(refname)' refs/original/ | xargs -n1 git update-ref -d
# 基于新历史 rebase
git rebase --onto origin/main <旧提交起点>
# 清理本地无效引用
git fetch --prune
替代方案:使用 git filter-branch
# 删除历史中的文件(效率较低,慎用)
git filter-branch --force --index-filter \"git rm --cached --ignore-unmatch bigfile.zip" \--prune-empty --tag-name-filter cat -- --all
https://juejin.cn/post/7419123474700697627?searchId=2025021213351465C8FE56E6C970C1C49B
https://juejin.cn/post/7261814990843265061?searchId=2025021213351465C8FE56E6C970C1C49B
优化存储结构
强制垃圾回收并重新打包
# 清理无效对象并重新打包(关键)
git reflog expire --expire=now --all
git gc --prune=now --aggressive
深度压缩仓库
# 调整打包参数(牺牲时间换空间)
git config --global pack.depth 50 # 增加打包深度
git config --global pack.window 250 # 增大窗口大小
git repack -a -d --depth=50 --window=250
验证结果
# 查看新的 size-pack
git count-objects -vH# 检查仓库整体体积
du -sh .git
后续维护
- 添加
.gitignore
,避免提交临时文件/大文件(如*.log
,*.zip
) - 使用 Git LFS 管理大文件(1 G免费空间),如果必须存储大文件(如图片/视频),用 Git LFS 替代直接提交:
git lfs install
git lfs track "*.psd"
git add .gitattributes
- 定期执行维护命令
# 每月优化一次
git gc --auto
git prune