问题描述;
当执行git revert一个merge commit的时候,会要求指定-m参数:
$ git revert <commit-id>
error: Commit <commit-id> is a merge but no -m option was given.
fatal: revert failed
下面我们讨论一下-m参数的含义;以下面的操作序列为例子:
假设:
- 在commit 0a91e4d基础上拉出两个分支:master和develop。
- 在master上有两个commit: e1ba385和35cea02
- 在develop上有两个commit: 9f9f581和905400a
- 然后在master上执行merge develop: 生成 merge commit: 905400a,把develop的commitmerge过来。
- 然后在调用一个git revert -m X 1dcac04生成c165798
首先对于普通commit来说,revert是把这个commit的内容丢弃,而对于merge commit来说,revert操作会把这个merge引发的所有commit都丢弃。
在前面例子中:merge commit涉及4个commit:
- develop分支上的9f9f581, 905400a
- master分支上的e1ba385,35cea02
revert就要考虑把哪个分支上的commit丢弃,-m参数就是这个作用,看参数定义:
-m parent-number, --mainline parent-number
Usually you cannot revert a merge because you do not know which side of the merge should be considered the
mainline. This option specifies the parent number (starting from 1) of the mainline and allows revert to reverse
the change relative to the specified parent.
所以-m是指定mainline,即指定主分支,就是保留主分支,然后丢弃其他分支。
查看一个merge commit的parent commit信息:
$ git show 1dcac04
commit 1dcac04XXXX
Merge: 35cea02 905400a
Author: XXX
Date: <DATE>
Merge branch 'develop'
这里parent-number=1,就是35cea02,那就是指定master分支,而
如果parent-number=2,就是905400a,那就是指定develop分支。
所以:
- git revert -m 1 1dcac04:选择1/35cea02/master为主线,丢弃非主线(develop)的commits(9f9f581, 905400a),最后只留下master分支的历史。
- git revert -m 2 1dcac04:选择2/905400a/develop为主线,丢弃非主线(master)的commits(e1ba385,35cea02),最后只留下develop分支的历史。