Git 推送失败:远程仓库提示文件超过 100MB 限制的解决方案
Git 推送失败:远程仓库提示文件超过 100MB 限制的解决方案
Git 推送失败:远程仓库提示文件超过 100MB 限制的解决方案
问题背景
今天在使用 Git 向 Gitee 推送代码时,遇到了一个令人头疼的错误:
remote: File [28d27cabaf49d93bd17ccbb80e92d4ffa7a31032] size 275.109MB, exceeds quota 100MB
remote: Please remove the file[s] from history and try again
error: failed to push some refs to 'https://gitee.com/xxxx/xxxx.git'
原因是本地仓库的历史中曾经提交过两个超过 100MB 的大文件(分别是 grafana-enterprise_12.4.0_…tar.gz 和 prometheus-3.10.0.windows-amd64.zip),虽然我后来删除了文件并重新提交,但 Git 的历史中仍然保留着这些大文件的记录,导致推送时被 Gitee 的预接收钩子拒绝。
踩坑记录
第一次尝试:直接删除文件后重新提交(失败)
我以为只要把文件删掉,再提交一次删除操作就能解决问题。于是:
# 手动删除文件后
git add .
git commit -m "删除大文件"
git push
第二次尝试:回退提交(失败)
我尝试回退到添加大文件之前的提交:
git reset --mixed HEAD~1 # 撤销最后一次提交
git add .
git commit -m "重新提交(不含大文件)"
git push
还是失败!这是因为虽然当前分支的最新提交已经不包含大文件,但大文件所在的提交对象仍然存在于本地仓库的对象数据库中,并且由于它仍被某些历史引用(比如它可能是更早的提交),推送时依然会被打包进去。
正确的解决方法:彻底重写历史,永久删除大文件记录
要彻底解决这个问题,必须重写整个仓库的历史,从所有提交中移除这两个大文件。可以使用 git filter-branch 或更现代的工具 git filter-repo。
步骤一:找到大文件的具体路径
根据错误信息中的对象 ID(28d27cab…),通过以下命令查找对应的文件路径:
git rev-list --objects --all | grep 28d27cabaf49d93bd17ccbb80e92d4ffa7a31032
本例中找到了两个文件:
- software/grafana-enterprise_12.4.0_22325204712_windows_amd64.tar.gz
- software/prometheus-3.10.0.windows-amd64.zip
步骤二:使用 git filter-branch 重写历史
执行以下命令,从所有分支和标签中删除这两个文件:
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch software/grafana-enterprise_12.4.0_22325204712_windows_amd64.tar.gz software/prometheus-3.10.0.windows-amd64.zip" \
--prune-empty --tag-name-filter cat -- --all
参数说明:
- –index-filter:在每次提交的暂存区执行命令,比 --tree-filter 更快。
- git rm --cached --ignore-unmatch:从暂存区删除文件,如果文件不存在则忽略。
- –prune-empty:删除因移除文件而变空的提交。
- –tag-name-filter cat:更新标签指向重写后的提交。
- – --all:处理所有分支和标签。
命令执行后会重写整个历史,过程中会显示每个被重写的提交。
步骤三:清理本地仓库
重写历史后,原来的大文件对象仍然存在于 Git 的对象数据库中,需要彻底清理:
git reflog expire --expire=now --all
git gc --aggressive --prune=now
步骤四:强制推送到远程
由于历史已被重写,需要使用强制推送覆盖远程分支:
git push origin master --force
步骤五:通知协作者
如果仓库有其他协作者,他们需要重新克隆仓库,或者执行以下命令同步:
git fetch --all
git reset --hard origin/master # 注意这会丢弃本地所有未推送的修改
预防措施
- 使用 .gitignore:对于不需要版本控制的大文件,提前添加到 .gitignore 中。
- 使用 Git LFS:对于需要版本管理的大文件(如二进制包、图片等),配置 Git LFS(Large File Storage)。
- 提交前检查:可以使用 git diff --stat 或 git status 查看即将提交的文件大小,避免误提交大文件。
总结
| 操作 | 命令 |
|---|---|
| 查找大文件对象对应的路径 | git rev-list --objects --all | grep <对象ID> |
| 从历史中彻底删除文件 | git filter-branch --force --index-filter "git rm --cached --ignore-unmatch <文件路径>" --prune-empty --tag-name-filter cat -- --all |
| 清理无效对象 | git reflog expire --expire=now --all && git gc --aggressive --prune=now |
| 强制推送 | git push origin <分支名> --force |
标签:Git, Gitee, 大文件, 错误解决, filter-branch
更多推荐
所有评论(0)