目录

git revert 遇到merge

[TOC]

git revert遇到merge时的问题

git中比较常用的"后悔药"可能有三个,

1
2
3
git commit --amend
git reset
git revert

以上三个都是非常有用的命令,这里不详细讲了。单说git revert遇到merge commit的情况。这个命令是针对某一次commit进行反做,这次commit可以是最后一次commit,也可以是中间的任意一次commit。什么是反做呢?反做就是完全相反的操作。

  • 改了的文件改回来
  • 新加的文件删除
  • 删除的文件加回来

这个命令有一个特殊情况,就是反做的commit是一次merge,这时会遇到下边的错误。

1
2
3
git revert 83e2776
error: commit 83e2776adb7a47617fbd181228906e52ada396ac is a merge but no -m option was given.
fatal: revert failed

问题的缘起

为什么呢?因为此时git不知道要做什么。merge commit是两个分支的汇合点。本质上这两个分支地位是完全相等的。虽然从下边的图看来,似乎master是你想要的。但是话说回来,master也仅仅是个名字而已,与其他分支并无区别。另外,这个merge也不一定发生在master分支。

还有一个错觉,master分支是一条横线贯穿前后,而new branch则是分出去又回来的。这当然是一个错觉,git不是这样工作的。在git看来,两条时间线完全一样,没区别。

如何解决

解决方法正如错误提示中提示的那样——指定父节点即可。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ git log -2
commit d607cb1b05a0fde3ded3078b0284d5c3a6440978 (HEAD -> master)
Author: chenfeiyang <30@qq.com>
Date:   Fri Apr 2 22:40:20 2021 +0800

    ddsd

commit 83e2776adb7a47617fbd181228906e52ada396ac
Merge: 7f68def abc78f0
Author: chenfeiyang <30@qq.com>
Date:   Fri Apr 2 22:39:46 2021 +0800

    Merge branch 'test'

通过以上操作,我们可以看到,我们要revert的commit 83e2776,有两个父节点,7f68def abc78f0。我们想保留的是master分支上的修改,新的分支有问题,不要了,需要继续改一下。

1
2
3
$ git revert 83e2776 -m 1
[master ede1c4c] Revert "Merge branch 'test'"
 1 file changed, 1 insertion(+), 1 deletion(-)

我们再来用log查看一下,

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ git log -3
commit ede1c4ce3d3dc0b40ab83a28b838509f4152b6c9 (HEAD -> master)
Author: chenfeiyang <309905109@qq.com>
Date:   Fri Apr 2 22:58:23 2021 +0800

    Revert "Merge branch 'test'"

    This reverts commit 83e2776adb7a47617fbd181228906e52ada396ac, reversing
    changes made to 7f68def67118944cb5bee085c6bdc9ddd0279086.

commit d607cb1b05a0fde3ded3078b0284d5c3a6440978
Author: chenfeiyang <309905109@qq.com>
Date:   Fri Apr 2 22:40:20 2021 +0800

    ddsd

commit 83e2776adb7a47617fbd181228906e52ada396ac
Merge: 7f68def abc78f0
Author: chenfeiyang <309905109@qq.com>
Date:   Fri Apr 2 22:39:46 2021 +0800

    Merge branch 'test'

可以看到我们要反做的commit 83e2776还在。确实,这也是为什么我们可以对已经上传到服务器的commit进行revert的原因。我们没有改变历史,我们新加了一个commit ede1c4ce。

这等价于:你发现这次merge有问题,不想要新分支merge进来的东西了,你记得所有的修改,于是把代码又改回去,重新提交了一个commit。