☰
GitHub 100MB限制突破指南:Git LFS完整实操
2026/10/22 19:19:41 网站建设 项目流程

朋友,你在 GitHub 上传大文件时,是不是碰到过remote: error: File xxx.zip is 150.00 MB; this exceeds GitHub's file size limit of 100 MB这种报错?或者仓库明明没多大,但网页端怎么都传不上去?

我先把结论摆出来:GitHub 单文件硬限制是 100MB,想突破它,唯一安全可靠的路子是 Git LFS。这篇文章不绕弯子,从限制原理、LFS 工作方式、完整操作流程到报错排查,一次讲清楚。不管你是刚接触 Git 的新人,还是被大文件搞到头秃的开发者,都能按步骤操作。

1. 先把 GitHub 的文件限制摸清楚

1.1 硬性限制:单文件 100MB,仓库 1GB 警告线

GitHub 平台对仓库文件体积有一套明确的限制规则,不了解这些规则就盲目 push,大概率会在最后一步被拒。

  • 单个文件大小警告线:50MB。超过 50MB 的文件,GitHub 网页端会给出警告提示,建议你使用 Git LFS。
  • 单个文件大小硬上限:100MB。任何超过 100MB 的文件,无论通过网页、命令行还是 API,都无法正常 push。这个限制是为了防止极端情况下拖垮 Git 服务端性能。
  • 推荐仓库总大小:1GB 内。GitHub 会向超出 1GB 的仓库发送邮件提醒,强烈不建议把仓库做成“网盘”,Git 的设计初衷是管理源码,不是存储大素材。

需要特别注意的是,100MB 限制针对的是单个文件大小,不是单个提交的总大小。你完全可以一次性提交 50 个 80MB 的文件,只要每个文件不超过 100MB,Git 层面不会被拒绝。但这么做会让仓库体积急剧膨胀,后续的 clone 和 fetch 对服务器和协作者都是灾难。

1.2 为什么普通 git add 会因为大文件失败

很多人在本地执行git add largefile.bin时毫无反应,等到了git push阶段才收到服务器拒绝。这是 Git 的工作机制决定的——Git 在本地完成所有快照,服务器在 push 时才做校验。

具体流程是这样的:

  1. git add把文件写入本地对象库(.git/objects),此时没有任何大小限制。
  2. git commit生成提交记录,同样只在本地操作。
  3. git push时,Git 客户端把对象打包发送到 GitHub 服务器。
  4. 服务器端校验每个 blob 对象的大小,若超过 100MB,直接返回错误,整个 push 过程失败。

所以排查问题时,请以git push阶段的报错为准。本地看不见报错是正常的,不代表文件没问题。

2. Git LFS 才是大文件上传的正路

2.1 Git LFS 的工作原理

Git LFS(Large File Storage)是 GitHub 官方支持的大文件解决方案,核心思路很简单:把大文件的真实内容从 Git 仓库中抽离,存放到独立的 LFS 存储区,Git 仓库里只保存一个指向该文件的指针文件。

指针文件通常只有几百字节,内容是文件哈希和大小信息,格式如下:

version https://git-lfs.github.com/spec/v1 oid sha256:4d7a214f1f4c1b8a2e3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d size 157293522

当别人 clone 你的仓库时,Git 只下载指针文件(毫秒级),LFS 客户端再根据指针文件从 LFS 存储区拉取真实内容。这样仓库本体始终保持轻量,大文件既不撑爆 GitHub 配额,也不拖慢 Git 操作。

这个方案有个重要好处:LFS 文件也会被追踪版本历史。你每次修改大文件,LFS 存储区都会保留旧版本,配合 Git 的 checkout、reset 等操作,完全无缝。

2.2 安装并初始化 Git LFS

LFS 不是 Git 自带功能,需要单独安装客户端。

在 macOS 上用 Homebrew:

brew install git-lfs

在 Windows 上,推荐从 Git LFS 官网下载安装包,安装完成后使用命令行验证:

git lfs version

看到类似git-lfs/3.4.1 (GitHub; windows amd64; go 1.21.5)的输出就算成功。

安装完成后,执行全局启用:

git lfs install

这条命令会修改你的 Git 全局配置,在~/.gitconfig中加入 LFS 相关的过滤器配置。输出Updated Git hooks即表示成功。

2.3 选择要跟踪的大文件类型

LFS 不是自动拦截所有大文件,它只处理你在.gitattributes中明确指定的文件类型或路径。这是一把双刃剑——配置精确能避免误伤,配置遗漏则大文件照样超限。

.gitattributes文件放在仓库根目录,声明需要 LFS 管理的文件模式。比如:

*.zip filter=lfs diff=lfs merge=lfs -text *.psd filter=lfs diff=lfs merge=lfs -text *.bin filter=lfs diff=lfs merge=lfs -text *.tar.gz filter=lfs diff=lfs merge=lfs -text models/** filter=lfs diff=lfs merge=lfs -text

这里的关键是filter=lfs diff=lfs merge=lfs -text这三个属性。filter=lfs让 Git 在 add/checkout 时调用 LFS 过滤器;diff=lfs让 Git 对 LFS 文件使用二进制 diff 策略;-text表示不要做换行符转换,避免二进制文件被破坏。

也可以用git lfs track命令生成上述规则:

git lfs track "*.psd" git lfs track "*.zip"

执行后会自动修改或创建.gitattributes。但我建议你还是手动打开看一眼,确认没有意外覆盖已有规则。

3. 实操:把超过 100MB 的文件推到 GitHub

3.1 完整操作流程

直接给你一份可以照抄的操作清单,我默认你已经完成 LFS 安装并创建了空仓库。

第一步:初始化仓库并安装 LFS 钩子

git init git lfs install

第二步:在推送前声明要跟踪的大文件

git lfs track "*.zip" git add .gitattributes

这一步很多人会漏掉。.gitattributes本身必须作为普通文件提交,否则其他协作者 clone 仓库后,LFS 规则不被触发,后续 push 依然会失败。

第三步:正常添加大文件并提交

git add release.zip git commit -m "Add release package"

此时git status会显示release.zip被识别为 LFS 文件。可以执行git lfs ls-files确认:

git lfs ls-files

输出示例:

4d7a214f1f * release.zip

第四步:创建远程仓库并推送

git remote add origin git@github.com:yourname/yourrepo.git git push -u origin main

如果一切正常,push 阶段会看到 LFS 上传进度:

Uploading LFS objects: 100% (1/1), 157 MB | 5.4 MB/s, done.

到这里,超过 100MB 的文件就成功推上去了。

3.2 .gitattributes 文件的维护

.gitattributes是 LFS 方案的命脉,维护不善会引发各种奇怪问题。给你几个实测下来的管理要点:

第一,规则顺序很重要。Git 匹配规则时,越靠后的规则优先级越高。如果你写了这样的规则:

* filter=lfs diff=lfs merge=lfs -text *.txt filter= -text

那么*.txt会被排除掉 LFS 跟踪。如果你想让所有二进制文件走 LFS,同时排除部分目录,最好把排除规则放最后。

第二,新增的大类型要及时补充规则。我踩过一个很实际的坑:项目里放了*.zip和*.tar.gz,只给*.zip配置了 LFS,某次构建产物变成了.tar.gz,结果 push 时直接被服务器拒绝。解决办法是建立仓库内部规则,构建物 push 前,先git lfs track检查一遍。

第三,不要轻易删除已提交的 LFS 跟踪规则。如果你把某条规则从.gitattributes中移除,历史提交中的 LFS 文件指针会保留,但新提交的同类文件又会走普通 Git 存储。对于已经存在的大文件,GitHub 依然会拒绝普通的 push。这就是为什么很多人的仓库删了.gitattributes之后反而无法推送。

3.3 如果 LFS 配额不够怎么办

GitHub 免费账户的 LFS 存储配额是1GB 带宽 + 1GB 存储。这里的“带宽”是拉取流量,按每月计算;“存储”是所有历史 LFS 文件的去重后总量。一旦超出配额,git push会报batch response: This repository is over its data quota。

有几种应对思路,按推荐顺序排列:

思路一:删除不需要的 LFS 历史文件。获取当前所有 LFS 文件列表:

git lfs ls-files --all

找到确实无用的文件(比如旧的安装包),从 Git 历史中彻底清理掉,LFS 存储才会释放。如果你只是从当前分支删除,历史里还保留,配额不会生效。

思路二:拆分仓库。把大文件集中到一个独立的“资产仓库”中,主仓库通过 Git 子模块或直接引用该仓库的存档链接。这样主仓库可以正常用免费配额,资产仓库单独管理。

思路三:升级付费档。不是广告,但坦白说,如果团队长期需要存放大文件,GitHub 付费方案提供的 LFS 数据包确实能解决根本问题。费用按数据包购买,不算太贵,但对个人项目而言,多数人更愿意先试前两种方案。

4. 常见报错与排查手册

4.1 遇到 “this exceeds GitHub's file size limit of 100 MB”

这条报错在 push 时出现,几乎可以断定:你有一个文件超过 100MB,但它没有被 LFS 追踪。

排查步骤:

  1. 在本仓库中执行git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | awk '$1=="blob" && $3>100000000 {print $4}',找出超过 100MB 的 blob 文件名。
  2. 如果该文件是必须保留的,用git lfs track "文件名或通配符"添加规则,然后重新提交。
  3. 如果文件确实不该存在于仓库(比如误提交的日志文件),需要从历史中删除,而不是仅做一次新的提交。

这里最容易犯的错误是:你执行了git rm largefile.bin并提交,以为就清理干净了。实际上,只要历史提交里还有这个大文件,push 依旧会被拒。GitHub 校验的是整个仓库的对象,不限当前分支的 HEAD。

4.2 如何在本地彻底移除误提交的大文件

需要清理历史中的大文件时,推荐使用git filter-repo。先安装它:

pip install git-filter-repo

假设误提交的文件名是wrong_big_file.zip,执行:

git filter-repo --invert-paths --path wrong_big_file.zip

该命令会重写整个仓库历史,删除所有包含该文件的提交中的对应文件。执行完成后,强制推送:

git remote add origin git@github.com:yourname/yourrepo.git git push --force --all

使用git filter-repo前请务必备份本地仓库。这个工具会移除原有的origin远程配置,而且由于历史被改写,所有协作者的本地仓库都需要重新 clone。

4.3 遇到 “batch response: This repository is over its data quota”

这个报错说明 LFS 配额超限,需要先清点 LFS 使用情况。

git lfs env git lfs ls-files --all

查看哪些文件占用了大量空间。处理办法前面提过删除历史或拆分仓库,不再赘述。这里补一个实操小技巧:GitHub 仓库设置页面的 “Data usage” 面板会显示 LFS 存储和带宽的月度用量。查看用量有助于判断是存储超限还是流量超限。如果只是带宽超限,往往要等到下月 1 日自动重置。

4.4 本地已经配置了 LFS,但 push 时 LFS 上传卡死

LFS 上传走的是独立的 HTTPS 连接,经常遇到卡在Uploading LFS objects: 0%的情况。可能原因和排查方向如下:

  • 网络代理设置异常。检查环境变量HTTPS_PROXY、HTTP_PROXY是否指向了不可用的代理。
  • DNS 解析问题。LFS 默认通过github.com获取上传地址,解析失败会导致连接挂起。
  • 认证失效。如果使用 HTTPS 方式 clone 仓库并且开启了双重验证,LFS 上传需要提供有效的 access token,而不是普通密码。执行git config --list | grep lfs检查相关配置。

切换到 SSH 方式 clone 往往能绕过 HTTPS 相关的认证问题:

git remote set-url origin git@github.com:yourname/yourrepo.git

4.5 clone 仓库时提示 “LFS: No such file or directory”

这个出现在git clone阶段,说明远程仓库有 LFS 文件,但本地未安装 Git LFS 客户端。

解决办法很简单:

git lfs install git lfs pull

如果 clone 已经完成但 LFS 文件缺失,直接进入仓库执行git lfs pull即可补拉。

5. 我的一些体会和建议

Git 本身是文本版本管理工具,强行走大文件路子,路只会越走越窄。GitHub 的 100MB 限制背后是大量开源项目多年踩坑后的经验总结,不是随便拍脑袋定的数字。如果你发现自己频繁需要上传大文件,我建议你停下来想想这个文件是否真的应该进 Git 仓库,而不是急着找工具绕开限制。

有几个比较实用的判断经验,你可以直接套用:

  • 编译产物(.class、.o、.exe),原则上不进 Git 仓库,走 CI 构建或外部制品存储。
  • 数据集和媒体素材(.psd、.mp4、.csv大数据),如果团队确实需要版本管理,Git LFS 是合理选择。
  • 依赖包和二进制库(.jar、.dll、.so),优先使用包管理器锁定版本,而不是直接把二进制塞进仓库。

还有一个小技巧,我实际用下来帮助很大:建立.gitignore与.gitattributes的联动规则。比如你需要在仓库里保留*.zip但不想让生成目录下的临时 zip 被上传,可以这样做:

*.zip filter=lfs diff=lfs merge=lfs -text build/*.zip !filter

这样既保证正式发布的 zip 由 LFS 管理,同时让构建目录内的临时文件走普通 Git 流程或直接忽略。

最后提醒一句:如果你从别的仓库迁移并想要保留大文件历史,请务必在迁移前就规划好 LFS 配额。GitHub 对新建仓库的初始 LFS 存储只有 1GB,迁移超过这个体量的大型资源库,大概率会立刻触发配额问题。先清理再迁移,远比迁移后抢救来得轻松。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询