核心问题是历史提交中残留的大文件未被清除。git平台会扫描整个commit历史,只要任一blob超100mb即拒绝push;仅删除本地文件无效,须用git-filter-repo等工具重写历史并配合git gc清理,再强制推送,长期应启用git lfs管理大文件。
mac 上 git 提交失败、仓库越变越大,核心问题往往不是“现在”加了什么大文件,而是“过去”提交过的大文件还卡在历史里。gitee、github 等平台会扫描整个 commit 历史,只要有一个 blob 超过 100mb,push 就会被拦下——删了本地文件也没用。
一、快速定位哪个文件惹的祸
先别急着删,得知道是哪个(或哪些)文件占了大头。在项目根目录运行:
-
git verify-pack -v .git/objects/pack/*.idx | sort -k3 -n | tail -10—— 列出体积最大的 10 个对象 -
git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k3 -n | tail -1 | awk '{print $1}')"—— 把最大那个对象反查出对应路径,比如build/firmware.bin或release/sdk-v2.3.0.zip
如果报错里已提示文件名(如 xxx.elf size 168MB),就直接跳到下一步。
二、区分情况:文件还在暂存区,还是已进历史
情况 A:只 add 过,还没 commit
这是最简单的情况。执行:
-
git restore --staged path/to/big-file.bin(取消暂存) - 把该路径加进
.gitignore,例如:build/*.bin、**/*.zip、logs/*.log - 再
git add .gitignore && git commit -m "ignore build artifacts"
情况 B:已经 commit 过,哪怕只一次
当前快照里删了没用,必须重写历史。推荐用 git-filter-repo(官方维护、macOS 友好):
- 安装:
brew install git-filter-repo - 备份(强烈建议):
git clone --mirror . ../myrepo-backup.mirror - 清除指定文件:
git filter-repo --force --invert-paths --path build/firmware.bin - 如要清整个目录:
git filter-repo --force --invert-paths --path build/ --path release/
三、清理本地残留 + 强制推送
filter-repo 执行完后,旧对象还在 .git 里躺着,需手动清理:
-
git gc --prune=now --aggressive(压缩并彻底删除无用对象) -
git reflog expire --expire=now --all(清空引用日志,避免恢复误操作) -
git push --force-with-lease origin main(强制推送重写后的历史)
注意:强制推送会影响协作成员,务必提前同步,并让他们执行 git fetch && git reset --hard origin/main 来对齐新历史。
四、长期预防:用 Git LFS 管理真正需要的大文件
如果项目确实需要版本化大文件(如设计稿、模型权重、固件镜像),别硬塞 Git,改用 Git LFS:
-
git lfs install(全局启用) -
git lfs track "*.bin"或git lfs track "assets/model.pth" -
git add .gitattributes(这步不能漏!) - 之后再
git add && git commit && git push,LFS 会自动上传实体文件到远程 LFS 服务器,Git 仓库只存轻量指针
这样既满足版本管理需求,又不会拖垮克隆速度和仓库体积。











