git push卡在“writing objects”阶段本质是本地打包、压缩、计算delta,非网络传输;主因包括小文件多时压缩策略不当、远程分支被force-push导致全量重传、ssh未启用连接复用、http.postbuffer过小或分支状态未同步。

git push 本身不慢,慢的是你没配对协议、没调参数、没理清分支状态。 大多数人卡在“等30秒没反应”,其实问题不在网络带宽,而在 Git 每次推送前的协商、压缩、对象传输策略没对齐当前仓库特征。
git push 为什么卡在“Writing objects”阶段
这个阶段不是在传文件,而是在打包(pack)、压缩、计算 delta 差异。尤其当本地有大量小文件变更、或最近一次 push 后远程已有新提交时,Git 会重新扫描整个对象图做增量判断。
- 默认
core.compression是 1(轻量压缩),但小文件多时设为3反而更快——CPU 开销低,网络传输省流量 - 大仓库建议启用多线程打包:
git config --global pack.threads 0(自动匹配 CPU 核数) - 如果远程分支近期被他人 force-push 过,
git push会退化成全量重传;用git push --force-with-lease能避免误判,但前提是本地先git fetch - SSH 协议下未启用连接复用,每次 push 都要握手建连;在
~/.ssh/config加上ControlMaster auto和ControlPersist 600可降 30%+ 延迟
git push -u origin feature/x 为什么会失败或变慢
这个命令本质是两件事:推分支 + 设置上游(upstream)。失败往往不是权限或网络问题,而是本地分支没 commit,或远程同名分支已存在但没追踪关系。
- 执行前先确认:
git status显示 “Your branch is up to date” 才安全;若显示 “Your branch is behind”,说明远程有新提交,必须先git pull或git fetch && git merge - 如果远程已有
feature/x,但本地是新建分支且未关联,直接git push -u origin feature/x会报错refusing to update checked out branch(仅限裸仓库)或静默失败(非裸仓库) - 更稳妥的做法是显式指定 refspec:
git push origin feature/x:feature/x,再手动git branch --set-upstream-to=origin/feature/x - 某些企业 Git 服务(如 Gitee 私有版)对首次推送的分支名做过滤,含下划线或大写字母可能被拦截,错误信息常藏在 HTTP 响应头里,需加
-v查看:git push -v origin feature/x
如何让 git push 不再“猜分支”和“等超时”
Git 默认行为是“按需协商”,但团队协作中,分支命名规范、推送目标固定时,完全可以固化流程减少交互开销。
- 用
git push origin HEAD替代写死分支名,适用于 CI 脚本或临时分支场景;它自动取当前分支名,避免拼错 - 设置默认推送行为:
git config --global push.default current,这样git push就只推当前分支到同名远程分支,不用每次输 origin 分支名 - HTTP 协议下超时常见于大包传输,调大
http.postBuffer(如524288000)并禁用 SSL 验证缓存(http.sslVerify false)可缓解,但后者仅限内网可信环境 - 频繁向多个远程推送?别写循环脚本,用
git remote set-url --add配置多个 push URL,一次git push全发出去
真正拖慢 git push 的,从来不是代码量,而是你没看清它在协商什么、压缩什么、传什么。每条配置背后都有明确作用域——改错地方,不如不改。











