git push --force-with-lease 是带远程 sha 校验的安全强制推送,执行前比对本地缓存与服务器最新分支哈希,不一致则中止以防止覆盖他人提交,须配合 git fetch origin 使用。

别直接用 git push -f,它会静默炸掉别人刚推上去的提交——90% 的线上事故都从这里开始。
git push --force-with-lease 是什么,为什么必须用它
它不是“温和版 -f”,而是带校验的强制推送:执行前会比对本地缓存的远程分支 SHA 和服务器当前 SHA。如果两者不一致(说明别人 push 过),就中止操作,报错 failed to push some refs; remote tip is behind。
这个机制防的是「协作场景下误覆盖他人工作」,不是防你自己反复改历史。
- 必须在
git fetch origin之后立刻用,否则本地缓存过期,--force-with-lease就退化成--force - GitHub / GitLab 上 protected branches 默认拦截所有 force push,包括
--force-with-lease,得先临时解除保护(需管理员权限) - CI/CD 流水线里慎用——某些平台 fetch 行为不透明,可能让 lease 检查失效
VSCode 里根本点不出强制推送按钮
VSCode 的源代码管理面板默认禁用 --force 类操作,这是硬编码的安全限制,不是设置没开。
图形界面只允许 fast-forward 推送;一旦出现 Updates were rejected because the tip of your current branch is behind,你就必须切终端。
- 推荐做法:在 VSCode 内置终端执行
git push --force-with-lease origin main(把main换成你的分支名) - 快捷键方案可行但有坑:Windows PowerShell 不支持
$(git rev-parse --abbrev-ref HEAD)命令替换,建议把终端设为bash或zsh - 别信“右键 → Push Force”之类的插件——多数只是包装
-f,绕过 lease 校验,反而更危险
强制推送前必须做的三件事
跳过任何一步,都可能让远程仓库进入不可逆损坏状态。
- 运行
git status确认工作区干净,没有未提交修改(否则reset --hard会丢代码) - 运行
git fetch origin同步远程最新状态,再用git log --oneline origin/main..main看本地到底改了哪些 commit - 如果本地有未提交改动,先
git stash;重写历史后,再git stash pop恢复,而不是直接git merge origin/main(那会引入重复提交)
被拒绝后不要立刻 -f,先看清楚错在哪
常见错误信息 ! [rejected] main -> main (non-fast-forward) 并不等于“必须强制推”。它只是告诉你:远程有你本地没有的提交。
这时候该做的是拉取、合入或协调,而不是一把 -f。
- 如果是自己在其他机器上 push 过,用
git pull --rebase整理本地历史再推 - 如果是别人推了新提交,且你本地改的是同一功能,优先沟通,而不是覆盖
- 只有确认远程那些提交可废弃(比如测试分支、个人 fork),才考虑
--force-with-lease
真正危险的不是命令本身,而是人按下回车前没看清 git log --graph --oneline --all 输出的分叉结构。











