重置与回退提交Reset & Revert
你可能会说
误加调试代码的提交已经和同事共享了,我想撤掉它、保留后来的改动,怎么做?
reset 移动当前分支指针并按模式处理改动;revert 追加一条抵消旧改动的新提交例如 main 上的 B 是正常改动,C 误加了调试入口:若 C 还只在本地,可用 reset 移动分支指针;--soft 保留暂存内容,默认的 --mixed 重置暂存区但保留工作区文件,--hard 会一并覆盖已跟踪文件的工作区改动。若 C 已推到共享分支、同事可能已经基于它工作,通常用 revert 追加一条抵消 C 的提交,保留原提交与后续历史;若后续改动和 C 重叠,revert 也可能需要解决冲突。
也常被叫作ResetRevert撤销提交
什么时候用
- 尚未共享、确定要移回前一提交时,可用 reset;先检查暂存区和工作区$ git reset --hard HEAD~1HEAD is now at 3f9c2ab 调整导航间距
- 想保留改动、只重做提交时,用 reset --soft 回到提交前$ git reset --soft HEAD~1改动仍在暂存区,可重新整理后再提交
- 共享分支上要抵消某条提交时,优先评估 revert,并检查它是否产生冲突$ git revert a1b2c3d[main 9e8f7a6] Revert "误加调试代码"
- reset --hard 会覆盖目标提交之后已跟踪文件的暂存和工作区状态,执行前先检查git status 显示有未提交改动reset --hard 会连这些改动一起丢弃
什么时候不用
- 未与协作者约定就重置共享分支并强推,改写同事可能依赖的历史reset 已推送的提交后强推,同事本地出现分叉共享历史不要改写,用 revert
- 没看清参数就用 reset --hard,连未保存的改动一起丢掉未提交的两小时改动随 reset --hard 一起消失执行前先 git status 确认
- 不看目标提交和后续改动就 revert,忽略它可能需要人工解决冲突没打招呼就 revert 了同事的提交对方继续基于被撤销的改动开发,产生无谓冲突
- 撤销后不重新运行验证,以为历史回到过去功能也回到过去reset ✓→页面报错
组成结构 · Anatomy
HEAD
回到这里
reset 移动分支指针,让该提交不再位于当前分支后续历史中;其改动是否保留取决于模式。revert 保留原提交,再追加抵消它的提交。
常见变体 · Variants
reset --soft--soft
git reset --soft HEAD~1
撤销提交但保留改动,方便重新整理后再提交
reset --hard--hard
git reset --hard HEAD~1
把分支移回前一提交,并覆盖之后已跟踪文件的暂存与工作区状态;执行前先检查
revertrevert
git revert a1b2c3d
已推送的提交要撤销,不改写共享历史
典型使用场景
本地 B、C 提交和调试入口
a1b2c3d (HEAD → main) 误加调试入口 · C
3f9c2ab 调整导航间距 · B
81a0b11 创建页面
要撤销C · 调试入口
需要保留B · 导航调整
先用 git log / git show 确认目标提交和它包含的改动。
reset --soft 移动分支但保留暂存改动
HEAD -> 3f9c2ab 调整导航间距
分支指针移回 B
暂存区保留 C 的改动
工作区文件保留 C 的改动
reset 会按参数更新分支、暂存区和工作区;--hard 会覆盖已跟踪文件的工作区改动,使用前先检查。
共享历史中用 revert 追加抵消提交
3f9c2ab B · 调整导航间距
a1b2c3d C · 误加调试入口
9b8c7d6 D · 同事更新帮助说明 (HEAD, origin/main)
抵消 Cgit revert a1b2c3d
得到 E在 D 后追加 Revert C
不移走共享的 C 或同事的 D;如果后续改动与 C 重叠,revert 也可能要求手动解决冲突。
复查保留导航与同事提交、移除调试入口
| B | 导航调整仍在 |
| C | 原提交保留在历史 |
| D | 同事的帮助说明仍在 |
| E | 抵消 C 的调试入口 |
运行页面并检查相关路径;revert 若与后续改动重叠,还需解决冲突。
延伸阅读 · 权威出处
