会丢掉本地未推送的提交;git reset --hard origin/branch-name 无条件抹除当前分支上所有未推送到远程的提交及工作区、暂存区修改,操作前需用 git log origin/branch-name..HEAD 确认将丢失的内容。

git reset --hard origin/branch-name 会丢掉本地未推送的提交
直接用 git reset --hard origin/branch-name 是最常用的覆盖方式,但它会无条件抹掉本地当前分支上所有未推送到远程的提交——包括你刚写完还没 git push 的代码。这不是“同步”,是“强覆盖”。
- 适用场景:确认本地改动全部废弃,比如误改了主干分支、或想彻底回归到远程最新状态
- 执行前务必检查:
git status和git log --oneline -n 5,看有没有需要保留的提交 - 如果本地有未提交的修改(working directory dirty),
git reset --hard会失败并报错error: Your local changes to the following files would be overwritten...,得先git stash或git checkout -- .
git fetch + git reset 更安全,能看清差异再动手
比起一步到位的 git reset --hard,分两步走更可控:git fetch 拉取远程引用,再手动决定是否重置。这样你能看到本地和远程 HEAD 的差别,避免误操作。
-
git fetch origin branch-name—— 只拉这个分支的最新信息,不触碰本地工作区 -
git log --oneline HEAD..origin/branch-name—— 查看远程有而本地没有的提交(即你将丢失的内容) -
git log --oneline origin/branch-name..HEAD—— 查看本地有而远程没有的提交(即你即将丢掉的) - 确认无误后,再执行
git reset --hard origin/branch-name
git pull --force 不是合法命令,别被误导
网上有些文章写 git pull --force,这是无效的。git pull 本身不接受 --force 参数,运行会报错 unknown option: --force。它本质是 git fetch + git merge(或 git rebase),没法跳过冲突或强制覆盖。
- 想“强制拉取并覆盖”,只能靠
git fetch+git reset --hard组合 - 如果当前分支设置了 upstream(比如用
git branch --set-upstream-to=origin/main配置过),git reset --hard @{u}可以替代写死的origin/branch-name,更通用 - 注意:
@{u}是 shorthand for upstream,不是所有旧版 Git 都支持,Git 2.0+ 没问题
覆盖后 push -f 要谨慎,尤其多人协作时
用 git reset --hard 覆盖本地分支后,如果还要推回远程,就得 git push -f(force push)。这会改写远程分支历史,对其他协作者是破坏性操作。
- 仅在自己独占的分支(如 feature/xxx 开发中)或明确通知团队的前提下使用
- 禁止对
main、develop等共享主干分支执行git push -f - Git 服务器(如 GitHub/GitLab)可能开启
denyNonFastforwards或 protected branches,此时git push -f会被拒绝,需管理员临时解除保护
远程分支覆盖本地这事,关键不在命令多难记,而在搞清“谁的内容会被丢”——是本地未推送的提交,还是远程已存在的历史。每次执行前花 10 秒看一眼 git log origin/branch-name..HEAD,比事后找回 commit 强得多。


















