绝大多数git push失败是远程仓库明确拒绝更新,主因包括权限不足、非快进冲突、分支保护规则拦截、大文件超限或历史含敏感文件;须依据remote端具体错误信息精准排查,而非重试。

绝大多数 git push 失败,不是网络卡了,而是远程仓库明确拒绝了你的更新请求。 Git 本身不“失败”,它只是严格执行规则:比如不允许覆盖他人提交、不接受非快进(non-fast-forward)更新、或被预接收钩子(pre-receive hook)拦截。排查要从「远程为什么拒收」出发,而不是反复重试。
remote: Permission denied 或 403 错误
这是权限链断裂的典型信号,不是密码输错了那么简单。
- 用
ssh -T git@github.com测试 SSH 连通性;若失败,说明密钥未加载或公钥没加到 GitHub/Gitee 账户里 - 用 HTTPS 推送时,
git config --get credential.helper查看凭据管理器是否启用;Windows 上建议运行git credential-manager reject https://github.com清除旧凭证再重推 - 检查远程 URL 是否写错:
git remote get-url origin;常见错误是把git@gitlab.com:user/repo.git写成https://gitlab.com/user/repo(漏了.git后缀) - 企业私有仓库还可能受 SSO 或 OAuth scope 限制,需确认 token 是否带
repo权限
! [rejected] main -> main (non-fast-forward)
本地分支落后于远程,Git 拒绝覆盖——这是最常被误认为“冲突”的情况,其实根本还没到合并那步。
- 错误本质是:远程
main的最新 commit 不在你本地分支历史中(比如同事先 push 了 README.md) - 别急着
git push --force-with-lease,先执行git pull origin main拉取并自动快进合并 - 如果 pull 后出现冲突,说明真有内容重叠:编辑标记为
的文件 → <code>git add .→git commit→ 再git push - 注意:
git pull默认是git fetch + git merge;若想避免 merge 提交,可用git pull --rebase,但需确保没共享该分支给他人
remote: GH006 / protected branch update failed
GitHub/GitLab 的分支保护规则已生效,直接推送会被拦截,和你有没有权限无关。
- 错误里带
GH006(GitHub)或Hook declined(GitLab)基本可锁定为保护分支 - 去仓库 Settings → Branches → Branch protection rules,检查是否启用了 “Require pull request reviews” 或 “Include administrators”
- 合规做法是:推送到新分支(如
git push origin feature/login),再在 Web 界面创建 PR;管理员可临时关闭保护,但不推荐 - IDE(如 JetBrains)里点 Push 有时会静默失败,建议终端执行
git push看原始报错,避免被 UI 层掩盖关键信息
fatal: The remote end hung up unexpectedly 或 early EOF
这类错误往往出现在推送大量文件或大文件时,表面是网络断开,实则是服务端主动终止了连接。
- 单文件超 100MB?GitHub 会直接拒绝;Gitee 是 50MB;检查是否误提交了日志、模型、视频等:
git ls-tree -r --long HEAD | awk '$4 > 100000000' | cut -d' ' -f4,6 - 即使文件已删,只要历史里存在过,
git push仍会尝试传输整个对象图;用git filter-repo --invert-paths --path bigfile.zip彻底清理(需 force push) - HTTP 协议下增大缓冲区:
git config http.postBuffer 524288000(500MB),但治标不治本;更稳妥的是改用 Git LFS 管理大文件 - 弱网环境优先改用 SSH 协议(
git remote set-url origin git@github.com:user/repo.git),比 HTTPS 更稳定
真正棘手的不是某条命令报错,而是错误信息指向多个可能原因——比如 failed to push some refs 本身不说明问题,必须结合前一行的 remote: 输出才能定位。别跳过那行字,它才是 Git 给你的第一手线索。











