误推 master 该 revert 还是 reset?撤销与补 MR 流程

前两天开发完一个功能,习惯性 git commit、git push------刷新远程,提交直接落在了 master。CI 已经跑了一分钟,群里有人问谁合的。

一句话结论:已 push 到共享 master → git revert;只在本地、还没 push → git reset。


一、revert 和 reset 怎么选

git revert git reset
做法 新增反向 commit,原 commit 仍在 移动分支指针,可抹掉 commit
远程 安全,不改写公共历史 需 force push,影响他人
适用 master / 共享分支 本地或未 push 的分支
情况 用什么
已 push 到 master git revert
本地 commit,未 push git reset --soft/mixed
刚 push、无人 pull、负责人确认 极少数 reset + --force-with-lease(非常规,慎用)
commit 含密钥 revert 当前代码 + 必须 git-filter-repo 清历史 + 轮换密钥(revert 删不掉历史里的密钥)

二、已 push:revert 撤回 + 处理 SOP

别慌,按顺序来:

步骤 做什么
1. 停 不要立刻 force push,先看 CI 和同事有没有 pull
2. 查 git log origin/master -5
3. 撤 git revert HEAD(多个 commit 见下)→ git push origin master
4. 告 通知团队 pull,别在误提交上继续开发
5. 补流程 需要 MR 记录时,走第三节 Case 2
6. 防 配分支保护 + pre-push hook
bash 复制代码
git log --oneline -5
git revert HEAD                 # 单个 commit
git push origin master

# 多个误提交:一次性 revert 再提交(比逐个 revert 少冲突)
git revert --no-commit HEAD~2..HEAD
git commit -m "Revert mistaken commits on master"
git push origin master

冲突:手动改完冲突文件 → git add <file> → git revert --continue。


三、补走 MR 流程:三种 merge 场景

图例:A = 误推的功能 commit;B/C = 分支上后续 commit;R = revert;M = MR 合并。

Case 操作 结果
1 拉分支,master 不 revert,直接 merge 无效------分支与 master 都有 A,提示 Already up to date
2 拉分支 → master revert → MR merge 标准做法,代码回到误推后状态,历史留 Review
3a master 仍含 A,分支上又有 B、C,直接 merge 能,只合入 B、C 增量
3b master 已 revert(有 R),分支含 A、B、C,再 merge 能,A+B+C 一并合回

最常见走 Case 2;分支上若还继续提交了 B、C,按 3a 或 3b 处理。

顺序不能反:

text 复制代码
正确:先拉分支(含 A)→ master revert(产生 R)→ MR 合回(产生 M)
错误:先 revert 再拉分支 → 分支没有功能 commit,合不回来
错误:只拉分支不 revert → Case 1,merge 无效

Case 2 完整流程(补规范标准做法,历史上会多 R 和 M,但比 force push 安心):

bash 复制代码
git checkout master && git pull
git checkout -b feature/order-fix    # ① 从含误提交的 master 拉分支
git push -u origin feature/order-fix

git checkout master
git revert HEAD                      # ② 单个;多个见第二节
git push origin master

# ③ 提 MR:feature/order-fix → master

MR 合并后 master 代码与误推后一致。分支若还有 B、C(Case 3),合入后会比当初误推时更多:

text 复制代码
Case 2:master: ... ── A ── R ── M     feature: ... ── A
Case 3:master: ... ── A ── R ── M     feature: ... ── A ── B ── C

四、还没 push:用 reset

bash 复制代码
git reset --soft HEAD~1    # 撤销 commit,改动留暂存区
git reset HEAD~1           # 改动留工作区
git reset --hard HEAD~1    # 彻底丢弃(慎用)

若还想补 MR 流程:git branch feature/xxx 带走 commit → master 上 reset 回远程 → push feature → 提 MR。


五、预防:靠门禁,不靠口头约定

远程(团队必配) :Gitee / GitHub 保护 master------禁止 direct push,必须 PR/MR + Review。配好后直推会被拒绝。

本地兜底 :.githooks/pre-push 拦截 master 直推:

bash 复制代码
#!/bin/sh
for p in master main; do
  b=$(git symbolic-ref HEAD 2>/dev/null | sed 's|.*/||')
  t=$(git rev-parse --abbrev-ref @{u} 2>/dev/null | sed 's|.*/||')
  [ "${t:-$b}" = "$p" ] && echo "禁止 push 到 $p,请走 feature + MR" && exit 1
done
bash 复制代码
git config core.hooksPath .githooks && chmod +x .githooks/pre-push

习惯 :开功能先 git checkout -b feature/xxx;push 前看 git branch --show-current。CI 侧 master 只跑测试、不自动发布。


六、参考内容

相关推荐
kuroomi2 小时前
Git入门
git·kubernetes
daliucheng2 小时前
lazygit 上手:日常 git 操作一篇讲完
git
codigger4 小时前
大厂git提交规范
git·程序员
挖掘狂人4 小时前
六条分支,一条主干:我的 Git 分支管理心得
git·后端·程序员
Brookty5 小时前
Git与GitHub系统学习|本地Git工作模型:终端与进程、CWD、HEAD/Index/工作树及Git对象
git·github
2301_7671139820 小时前
点过“不再询问”就要检查:Claude Code权限文件也可能存着密钥
git·信息安全·claude code
江屿风1 天前
【Git-组件】【Git入门:从文档灾难到版本掌控】流食般投喂
运维·笔记·git·组件·版本控制
程序员沉梦听雨1 天前
【Git】fork工作流与上游同步
git
高调的涵涵4 天前
删了1.2GB,.git仍是1.2GB
git
程序员沉梦听雨4 天前
【Git】git-submodule子模块管理
git