应使用 git push --force-with-lease 替代 --force,它通过比对本地远程引用与真实远程状态来防止覆盖他人提交;仅限私有分支重写历史时使用,严禁用于 main 等协作主干分支。

别直接用 git push --force,尤其在团队协作分支上——它会无条件覆盖远程提交,哪怕别人刚推了新代码。 安全替代方案是 git push --force-with-lease,它只在确认“没人动过远程分支”时才允许强推。
为什么 git push --force 会丢代码?
Git 的默认推送策略是“快进(fast-forward)”,即只允许远程分支指针向前移动,不覆盖已有提交。而 --force 直接绕过这个检查,用本地分支的提交历史完全替换远程分支的历史。
- 常见错误场景:你本地基于旧版
main做了rebase,但同事已在你上次git fetch后推送了新提交;--force会直接抹掉同事的提交 - 错误提示不会出现——它静默成功,但后果严重:CI 流水线失败、PR 记录断裂、他人本地
git pull后出现重复冲突 - 即使你刚执行过
git pull,也不能保证安全:pull 和 push 之间存在时间窗口,别人仍可能抢在你之前推送
git push --force-with-lease 怎么检查“别人有没有改”?
它依赖本地存储的远程引用(比如 origin/main 在 .git/FETCH_HEAD 或 reflog 中的记录),和当前远程真实状态做比对。只有两者一致,才允许推送。
- 命令格式:
git push --force-with-lease origin main - 如果失败,典型报错是:
! [rejected] main -> main (stale info)—— 这不是故障,是保护生效 - 此时必须先
git fetch origin,再用git log origin/main..main看差异,确认是否真要覆盖 - 注意:
--force-with-lease不等于“绝对安全”:如果你已手动更新过origin/main(比如刚git pull过),它就不再校验远程最新状态,可能放行覆盖操作
什么情况下该用 --force-with-lease?
仅限于你明确重写了本地历史,且该分支尚未被他人基于开发的场景,例如:
- 私有功能分支(如
feature/login)做完git rebase -i整理提交后,首次推送到远程 - 修复 commit message 或 author 信息后,用
git commit --amend修改了最近一次提交,需同步到远程 - 清理本地实验性分支的混乱历史,准备正式共享前
- 绝对不要用于
main、develop等多人协作主干分支,哪怕加了--force-with-lease
Linux 下配置 Git 避免误用 --force
可以在 Linux 终端中设置 Git 别名或 hook 来降低风险:
- 设别名强制走安全路径:
git config --global alias.pf 'push --force-with-lease',之后用git pf origin main - 禁用裸
--force(需 Git 2.30+):git config --global push.default upstream+git config --global push.forceIfIncludes false - 更彻底的做法:在
~/.gitconfig中加一行[push] default = upstream,让git push默认拒绝无上游分支的推送,倒逼你先-u - 注意:这些配置不能阻止别人在其他机器上误操作,团队规范和权限控制(如 GitHub 的 branch protection)才是最后一道防线
真正危险的从来不是命令本身,而是对“远程分支是否干净”的误判。每次敲下 --force-with-lease 前,花三秒执行 git fetch origin 并确认输出里没有新提交,比任何配置都管用。


















