git revert
git revert
git revert <commit> 的作用是:创建一个“反向提交”,撤销指定提交的更改,但保留原有历史。
它不会改写历史,而是在当前 HEAD 上追加一个反向修改的新提交,这是它与 git reset 最大的区别。
和 reset 的根本区别
| 命令 | 是否改写历史? | 是否保留历史记录? | 是否适合多人协作(远程分支)? |
|---|---|---|---|
git reset |
✅ 会改写 | ❌ 会丢弃之后的提交 | ❌ 不推荐 |
git revert |
❌ 不改写 | ✅ 所有提交都保留 | ✅ 非常安全 |
实例演示
假设提交历史如下:
A -- B -- C -- D (main)
想撤销提交 C:
git revert C
结果变成:
A -- B -- C -- D -- E (main)
其中:
E是 Git 自动生成的一个反向提交,它的效果是「把C做的事反过来」;- 历史不会断裂,也不会改变任何提交 ID;
- 适合远程协作、线上代码回滚等场景。
基本命令格式
git revert <commit>
常见变体:
| 命令 | 功能 |
|---|---|
git revert HEAD |
撤销最近一次提交 |
git revert HEAD~2 |
撤销倒数第 3 次提交 |
git revert a1b2c3d |
撤销某个具体提交 |
git revert --no-commit <commit> |
创建反向更改,但不提交(类似 --soft) |
什么是“反向提交”
假设某次提交 C 改了 file.txt 内容如下:
- int x = 1;
+ int x = 2;
那执行 git revert C 生成的新提交会做:
- int x = 2;
+ int x = 1;
本质上是:基于 C 的 diff,生成一个“反向 diff”并作为新提交记录下来。
多个提交一起回滚
可以这样:
git revert A..D
含义是:从 A(不含)到 D(含)这些提交依次反转
或:
git revert C D
多个提交逐个反转。
注意:
- 多次 revert 可能导致冲突;
- 建议加
--no-commit自己处理冲突后再手动提交。
常见选项
| 选项 | 含义 |
|---|---|
--no-commit |
执行反转但不自动提交 |
--edit(默认) |
打开编辑器修改 commit 信息 |
--no-edit |
不打开编辑器,直接使用默认信息 |
--mainline <n> |
用于revert 合并提交,指定主分支父节点(较复杂) |
特别注意:revert 合并提交
git revert -m 1 <merge-commit-id>
其中 -m 1 表示使用第一个父提交作为“主线”,只撤销合并带来的差异。
合并提交结构复杂,不建议轻易 revert,除非你明确知道合并时的父子结构。
推荐使用场景
| 场景 | 是否推荐用 revert |
|---|---|
| 线上分支出 bug,要撤销提交 | ✅ 强烈推荐 |
| 本地提交还没推送 | ❌ 用 reset 更合适 |
| 团队协作,不能改历史 | ✅ 必须用 revert |
| 想保留历史但取消效果 | ✅ 用 revert |
示例操作
git log --oneline
# 输出:
# f123456 修复登录bug
# e789abc 添加登录表单
# d456def 初始化项目
git revert e789abc
# 生成一个新提交,反转“添加登录表单”的更改
总结对比:git revert vs git reset
| 特性 | git reset |
git revert |
|---|---|---|
| 是否改历史 | ✅ 会 | ❌ 不会 |
| 是否保留提交记录 | ❌ 不会 | ✅ 会 |
| 是否适合团队协作 | ❌ 否 | ✅ 是 |
| 典型用途 | 回退本地提交 | 安全撤销线上提交 |
| 是否可恢复 | 一定条件下可用 reflog |
永远保留历史 |
命令速查表
| 操作 | 命令 |
|---|---|
| 撤销最近提交 | git revert HEAD |
| 撤销某个提交 | git revert <commit-id> |
| 撤销多个提交 | git revert A..D |
| 只反转但不提交 | git revert --no-commit <commit> |
| 回滚合并提交 | git revert -m 1 <merge-commit> |

浙公网安备 33010602011771号