GitHub推送仓库失败:删除本地大文件后强制推送仍被远端拒绝的解决方法
核心报错逻辑:你仅在当前工作区删掉大文件、生成删除类commit的操作,根本没把大文件从过往的提交记录里删干净。GitHub的服务端校验会逐个扫描你要推送的所有提交节点,只要某段历史里存过超过100MB的单文件,哪怕最新版本已经删了,依然会触发pre-receive hook拦截。之前两次强制推送被拒,就是因为你推送的整条提交链路里还带着那个违规的大文件。
第一步:定位历史里的所有超标大文件
先执行以下命令,扫描本地提交记录中所有超过GitHub100MB单文件限制的内容:git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | awk '/^blob/ {if ($3 > 104857600) print $3/1024/1024 "MB", $4, $2}'
执行完会直接输出所有超标文件的大小、完整存储路径、对象ID,把这些文件路径全部记下来,别漏。
第二步:重写提交历史,彻底移除超标文件
对每一个扫描出来的超标文件路径,执行以下Git自带的历史重写命令(不需要额外装工具):git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch 你记录的大文件完整路径' --prune-empty --tag-name-filter cat -- --all
如果有多个超标文件,就把命令里的路径替换成对应文件的路径,重复执行即可,直到所有超标文件都从提交历史里被剔除。
第三步:清理本地残留的Git缓存
重写历史后,本地.git目录还会存着旧版本的大文件对象,不清理的话推送时这些残留文件依然会被打包传上去:rm -rf .git/refs/original/git reflog expire --expire=now --allgit gc --prune=now --aggressive
第四步:执行强制推送
确认本地所有提交历史里已经没有任何超标大文件的痕迹后,执行推送:git push origin master --force
实操注意点
- 整个流程中不要中途拉取旧的远端仓库历史做合并,否则已经被移除的大文件痕迹会重新回到本地提交链路里,之前的操作就白做了
- 如果推送时依然提示pre-receive hook拒绝,说明本地还有没清理干净的超标文件,回到第一步重新扫描,把所有超100MB的文件全部移除后,再重复清理、推送流程
- 后续提交时可以定期跑第一步的扫描命令检查,避免把超大文件直接提交进历史链路
内容的提问来源于stack exchange,提问作者user3398585

