git revert如何撤销合并提交

什么是git revert

在正式开始之前,我们先简单介绍下revert命令:revert允许我们“回滚”之前的一次或多次提交。

当我们执行git revert <commit_id>时,git会创建一个新的commit,在这个新commit中,git通过打一个反向补丁的方式来撤销<commit_id>这次提交中的内容。

相比于使用reset命令撤销提交,revert会创建一个新的commit,这使得git的提交线更加清晰,因此在多人协作中我更推荐使用revert命令。

不过上面介绍的revert用法有一个前提,就是<commit_id>不能是一个合并提交(合并提交是指合并两个分支时产生的那个提交)。那如果我们真的想revert一个合并提交又该怎么做呢?

背景介绍

为了更好地说明,首先我们使用git init创建一个空的git仓库,并进行一次初始化提交:

接着使用git checkout -b dev创建一个dev分支,然后马上切换回默认的master分支。

在默认的master分支下,我们分别进行了两次提交:第一次创建了master.txt文件并在其中写下“master分支第一次提交”,第二次在master.txt文件中再写下“master分支第二次提交”。

接着再切换到dev分支,还是进行两次提交:第一次创建dev.txt并写下“dev分支第一次提交”,第二次在dev.txt文件中再写下“dev分支第二次提交”

然后切换回master分支,并合并dev分支。

现在,我们的git实验仓库里应该有master.txt和dev.txt两个文件,内容分别为:

master.txt:

master分支第一次提交
master分支第二次提交

dev.txt:

dev分支第一次提交
dev分支第二次提交

git的提交线看上去是这样:
在这里插入图片描述

假设这时我们想撤销这次合并,如果直接使用git revert 67a7b26e(67a7b26e是合并master和dev分支那次提交的id前几位)会得到下面的错误提示:

error: commit 67a7b26e40962a8fe6e2ff087f6c39217d7ceb5d is a merge but no -m option was given.
fatal: revert failed

问题分析

在不考虑冲突的情况下,合并提交的内容来源于多个被合并的分支。

当我们想要revert一个合并提交时,git并不能确定我们想要保留哪个分支的内容,所以就会报错并阻止revert操作。

解决方法

此时需要使用-m(或–mainline,二者是等价的)选项指定我们想保留哪个分支。

-m参数后面跟一个从1开始的数字,代表哪个分支是我们想保留的,除该分支的内容外,其他被合并分支上的内容会被撤销。

那么,如何知道每个分支对应的数字是什么呢?

我们可以使用show命令来查看,比如这里是git show 67a7b26e,它的输出中会包括下面的内容:

Merge: f3480f7 2ef1836

其中f3480f7是master分支上一次提交,2ef1836是dev分支上一次提交,所以这种情况下master对应1,dev对应2。

如果我们想保留master分支上的内容,撤销合并进来的dev分支,可以使用git revert -m 1 67a7b26e

执行后可以发现合并进来的dev分支上的修改已经全部消失了,此时的提交线是这样的:
在这里插入图片描述

注意事项

从提交线可以看出,当我们revert一个合并提交时,只是回滚了内容,但分支合并的记录还是存在的。

那么这会有什么影响呢?

假设我们又在dev分支上进行了提交:创建一个dev1.txt并写下“这是dev分支在revert -m之后的修改”,然后切换到master分支并执行git merge dev

我们会发现此时git仓库中只有dev1.txt,也就是dev分支在上一次合并之后的修改才被合并到了master分支中。

其实这也可以理解,虽然我们revert了上一次合并,但因为合并记录还在,所以对于git而言,dev分支的前两次提交已经被合并到了master分支上,那么本次执行merge就只会合并dev分支上增量部分。

如果我们还是想保留dev分支上的前两次提交,可以再对使用git revert -m 1 67a7b26e产生的提交进行一次revert操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值