那么,$ git revert -m 1 g 将会保留 master 分支上的修改,撤销 dev 分支上的修改。
撤销成功之后,Git 将会生成一个新的 Commit,提交历史就成了这样:
其中 G 是撤销 g 生成的 commit。通过 $ git show G 之后,我们会发现 G 是一个常规提交,内容就是撤销 merge 时被丢弃的那条线索的所有 commit 的「反操作」的合集。
Recover a Reverted Merging
上面的提交历史在实践中通常对应着这样的情况:
工程师在 master 分支切出了 dev 分支编写新功能,开发完成后合并 dev 分支到 master 分支并上线。上线之后,发现了 dev 分支引入了严重的 bug,而其他人已经在最新的 master 上切出了新的分支并进行开发,所以不能简单地在 master 分支上通过重置(git reset )来回滚代码,只能选择 revert 那个 merge commit。
但是事情还没有结束。工程师必须切回 dev 分支修复那些 bug,于是提交记录变成了这个样子:
工程师返回 dev 分支通过 j,k 两个 commit 修复了 bug,其他工程师在 master 上有了新的提交 i。现在到了 dev 分支的内容重新上线的时候了。
直觉上来说,还是和之前一样,把 dev 分支合并到 master 分支就好了。于是:
得到的提交记录变成了这样:
m 是新的 merge commit。需要注意的是,这不能得到我们期望的结果。因为 d 和 e 两个提交曾经被丢弃过,如此合并到 master 的代码,并不会重新包含 d 和 e 两个提交的内容,相当于只有 dev 上的新 commit 被合并了进来,而 dev 分支之前的内容,依然是被 revert 掉了。