解决 Git 提交大文件导致 Push 被拒绝的问题

为什么会出现这个情况?

  1. 因为这个代码是二开的,从别的代码仓库下载zip的方式下载的
  2. 并且里面没有.gitignore
  3. 在我们远程仓库没有创建好的情况下我现在本地仓库已经提交了几次代码了,导致提交了jar包上去
  4. 现在要往新建出远程仓库第一次推送的时候出现了这次的问题
  5. 所以本次演示的删除 Git 提交历史中的大文件
  6. 如果是删除未提交的文件直接使用git rm --cached即可

在使用 Git 推送代码到远程仓库(比如 Gitee)时,经常会遇到这样的问题:

shell 复制代码
remote: Find the desired index: <hash>, size: 108.596MB, exceeds quota 100MB
error: failed to push some refs to 'https://gitee.com/your-repo.git'
! refs/heads/master:refs/heads/master [remote rejected] (pre-receive hook declined)

这是因为 Git 历史中存在大文件,超出了远程仓库的限制。本文将详细讲解如何排查并解决此问题。

一、问题分析

  1. 大文件导致 push 被拒绝
    Gitee/GitHub 等平台对单个文件大小有限制(Gitee 默认 100MB)。如果历史提交中存在大文件,就算你在最新提交里删除了,也无法直接 push。
  2. 普通 git rm --cached 不起作用
    仅删除工作区或暂存区的文件,并不会删除 Git 历史里的大文件。

二、排查大文件

在 Windows PowerShell 中,可以使用如下命令找出仓库中最大的文件:

shell 复制代码
git rev-list --objects --all | `
  git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | `
  Where-Object { $_ -match "^blob" } | `
  Sort-Object {[int]($_.Split(" ")[2])} -Descending | `
  Select-Object -First 20

输出示例:

注意:这里显示的文件大小是字节数。你可以找到所有超出远程限制的文件。


三、删除大文件

1. 使用 git rm --cached 删除最新提交的文件

从 Git 暂存区(索引)中删除指定文件,但保留工作目录中的文件

shell 复制代码
git rm --cached path/to/largefile
git commit -m "remove large file from latest commit"

这种方法只能删除最新提交中的大文件,历史提交中仍然存在。


2. 删除 Git 历史中的大文件

使用 git filter-branch

⚠️ 警告:这会重写 Git 历史,如果其他人已经克隆了仓库,会导致冲突。确保你是唯一开发者或者团队同意重写历史。

shell 复制代码
# 执行 filter-branch 删除历史中的大文件
git filter-branch --force --index-filter `
"git rm --cached --ignore-unmatch im-admin/ruoyi-admin/target/im-admin.jar" `
--prune-empty --tag-name-filter cat -- --all

2.1 git filter-branch时 有uncommitted changes解决方案

⚠️ 注意:

  • Windows 下需要确保暂存区没有文件被 staged,否则会报错。
  • 删除完成后,需要强制 push:
  • 如果暂存区有文件被 staged 就会出现如下图所示报错
  1. 查看当前仓库的状态
shell 复制代码
 git status
  1. 将暂存区(staging area)中的 .DS_Store 文件撤回到未暂存状态 ,也就是取消 git add.DS_Store 的操作,但不会删除工作目录中的文件。
shell 复制代码
git restore --staged .DS_Store
  1. 最后使用 git filter-branch 对Git 历史中的大文件进行删除
  1. 删除成功后再次推送就能成功推送了
shell 复制代码
git push origin master --force

四、预防措施

  1. 添加 .gitignore 忽略临时文件和 target 目录
git 复制代码
# Maven
**/target/
*.jar

# macOS
.DS_Store
  1. 使用 Git LFS 管理大文件(可选)
    对于必须提交的大文件(>100MB),可以使用 Git LFS 来管理。
shell 复制代码
git lfs install
git lfs track "*.jar"

五、总结

  • Push 被拒绝原因:仓库历史中存在大文件。
  • 排查方法 :使用 git rev-list + git cat-file 查找最大文件。
  • 解决方法
    1. 删除暂存区大文件:git rm --cached
    2. 删除历史大文件:git filter-branchgit filter-repo
  • 预防措施 :使用 .gitignore、Git LFS。

通过以上方法,你就可以清理 Git 仓库中的大文件,顺利推送到远程仓库。

相关推荐
豆角焖肉11 分钟前
Maven进阶与搭建私服
java·maven
爱莉希雅&&&14 分钟前
elasticsearch+kibana+logstash+filebeat链路部署流程
大数据·elasticsearch·搜索引擎·kibana·logstash·filebeat
John_ToDebug17 分钟前
Git Stash 完全指南:临时保存工作区的艺术
人工智能·git·agent
大不点wow22 分钟前
Java序列化与反序列化:让对象走出JVM
java·开发语言·jvm
止语Lab25 分钟前
好的 DX 不等于少写代码——三种语言的摩擦力设计课
后端
吃饱了得干活25 分钟前
别再手动解析 LLM 输出了!LangChain 四种结构化输出方案对比
后端·python·langchain
噢,我明白了26 分钟前
Java中日期和字符串的处理
java·开发语言·日期
程序员天天困30 分钟前
Arthas trace 命令怎么用?一行定位最慢那行代码
jvm·后端
Huiturn31 分钟前
GPT 5.6 连续编码 10 小时,纯 Python 啃下 Word 二进制格式——doc2docx 实现拆解
后端
dkbnull33 分钟前
Spring Boot请求处理组件对比详解
java·spring boot