git revert 用法实战:撤销一个 commit 或 merge
git revert
1 区别
• 常规的 commit (使用 git commit 提交的 commit)
• merge commit
2 首先构建场景
master上的代码

dev开发分支上,添加一个a标签,并commit这次提交

切到master上,再次进行改动和提交

将dev的代码合到master后,当前的分支图如下所示:

merge commit 和普通 commit 的不同之处在于:
merge commit 包含两个 parent commit,代表该 merge commit 是从这两个 commit 合并过来的
使用 git log 查看历史提交记录

也可以使用git show查看这个merge的详细信息

这代表该 merge commit 是从 81eb85d 和 eod12f6 两个 commit 合并过来的
而常规的 commit 则没有 Merge 行

3 revert 常规 commit
使用 git revert 即可(commit id是希望删除的Commit ID值)
git 会生成一个新的 commit,会将将定的 commit 内容从当前分支上撤除。

4 revert merge commit

但如果直接使用 git revert ,git 也不知道到底要撤除哪一条分支上的内容
这时需要指定一个"主线",主线的内容将会保留,而另一条分支的内容将被 revert
从前面git show的命令中,可以看到,merge commit 的 parent 分别为
• 81eb85d(代表master分支)
• eod12f6(代表dev分支)


我们需要保留master分支的内容(主线),将dev分支的内容移除,操作如下:
git revert -m <主线> <commit ID>
git revert -m 1 c0702d261f7be5e93d1b6646d91bec9dabde2a19
因为左边的第一个(81eb85d)式主线,所以,主线为1
代码去掉了上次合并内容:

分支图如下:

5 revert之后的重新合并
假设A在自己分支dev上开发功能,并合并到了master,之后 master 上又提交了一个修改 g,这时提交历史如下:

突然大家发现A的分支存在严重的bug,需要revert掉,于是就把这次合并revert掉了,记为H

然后A回到自己的分支dev上,修改好了bug,直觉上只需要再次merge到master了就可以,像这样

但是这不能得到期望的结果,这样合并的结果,并不会包含 c、d的代码,只有 i 的代码 (因为 c 和 d 两个提交曾经被丢弃过)
所以,如果想恢复整个dev分支 所做的修改,应该先把 H revert 掉:

其中 H" 是对 H 的 revert 操作生成的新 commit,把之前撤销合并时丢弃的代码恢复了回来,然后再 merge 佳怡的分支dev,就可以把解决 bug 写的新代码合并到 master 分支
6 git reset 和 git revert区别
| revert | 再当前版本的基础上新增一个版本,不影响以前的代码 | 在版本四想要回退时![]() |
| reset | 该命令会强行覆盖当前版本和要回退的版本之间的其他版本(不太建议) | 在版本四想要回退时![]() |
希望去掉最新的一次commit

分支图如下,

git log 查看历史记录

执行:git reset a7961ff9760e49e5736f7b43794f44ed18b09ce5
从分支图上,可以看到最新的commit记录会被强行覆盖而失去了

上一次修改的内容,会变成待提交的状态



