应使用 git push --force-with-lease origin main,它通过比对本地缓存与远程当前 sha 值校验安全性,仅当无人改动远程分支时才允许推送;必须先执行 git fetch origin 更新本地引用,否则校验失效,等同于危险强推。

别用 git push -f,真要强推就用 git push --force-with-lease,且必须先 git fetch origin;否则不是“安全强推”,是“假装安全的误操作”。
强制推送命令怎么写才对
正确写法只有两种常用形式:
-
git push --force-with-lease origin main—— 明确指定远程名和分支名,最推荐 -
git push --force-with-lease origin feature/login:feature/login—— 本地分支名和远程分支名不同时必须显式写出映射
错误写法包括:git push -f origin main(绕过保护)、git push --force-with-lease origin(漏掉分支名,Git 会报错)、git push --force-with-lease(没指定远程,直接失败)。
注意:--force-with-lease 不接受简写(比如 -f),也不能省略分支名——它不是“开关”,而是带校验逻辑的操作。
为什么 --force-with-lease 会失败并提示 ! [rejected] main -> main (stale info)
这不是命令出错,是保护机制生效了:你本地缓存的 origin/main 提交哈希,和远程当前真实值不一致。
常见原因有:
- 你很久没运行
git fetch origin,本地引用已过期 - 同事在你
fetch后、push前推送了新提交 - CI/CD 流水线自动触发了一次推送(比如自动合并 PR)
此时不能硬加 --force,而应先执行 git fetch origin,再用 git log origin/main..main 看差异,确认是否真要覆盖——如果发现同事的新提交对你本地重写历史有影响,就得协商或改方案。
哪些分支能用强制推送,哪些绝对不能碰
能用(但依然要谨慎)的场景极少:
- 个人项目仓库,且你确认远程无他人访问
- 刚创建的临时分支(如
ci-build-123),纯脚本生成,无人基于它开发 - 本地做完
git rebase -i或git filter-branch,且远程该分支尚未被任何人拉取过
绝对不能碰的分支:
-
main、develop、release/*这类受保护分支(GitHub/GitLab 默认开启 protected branch,--force和--force-with-lease都会被平台直接拒绝) - 任何 CI 已构建过、PR 已关联过、或他人
git clone过的分支
哪怕你有管理员权限,绕过平台限制强行推送,也会导致 PR 记录断裂、CI 缓存失效、合作者 git pull 报错甚至丢提交。
误操作后别人怎么恢复本地分支
一旦你强推成功,其他人的本地分支就和远程不一致了。他们不能直接 git pull,因为 Git 默认拒绝非快进合并。
安全恢复方式只有一种:
- 先备份自己本地未提交的修改(如有)
- 运行
git fetch origin拉取最新远程状态 - 运行
git reset --hard origin/main(把本地分支头强制对齐到远程最新)
注意:git reset --hard 会丢弃本地所有未提交 + 未推送的更改,所以执行前务必确认——这也是为什么强推前必须同步团队、检查 CI 状态、并提醒所有人暂停对该分支的操作。
真正难处理的不是命令怎么写,而是“谁动了这个分支”“有没有人正在基于它调试”“CI 是否已缓存旧版本”——这些信息不会出现在终端里,得靠人去确认。











