一、问题描述

我在master分支将dev分支合并进来了,需要撤销这一次的合并,要怎么操作呢,直接执行git commit revert
提示如下:

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

二、为什么需要-m参数呢

因为合并必然涉及两个分支,撤销合并就需要选择保留哪个分支; 当A与B合并成D,撤销D就需要告知是保留父分支A还是保留父分支B
-m 参数用于指定合并提交的父提交,告诉 Git 在撤销合并时应该以哪个父提交为基准。合并提交通常有两个父提交:

  • -m 1 表示第一个父提交(合并之前当前分支的状态)。
  • -m 2 表示第二个父提交(被合并进来的分支的状态)。

需要明确选择保留哪个父提交的内容。

三、-m 1与 -m 2的这两个父提交的区别

  1. 第一个父提交(-m 1):
    这是合并时所在分支的最新提交,也就是当前分支的状态(合并时 HEAD 所指向的提交)。
  2. 第二个父提交(-m 2):
    这是被合并进来的分支的最新提交,也就是合并时的目标分支的状态(通常是另一个分支的 HEAD 提交)。

合并提交的两个父提交的作用
合并提交的两个父提交用于表示合并的来源和目标:

  • 第一个父提交(-m 1):
    当前分支的合并基础。通常是你执行 git merge 时 HEAD 所在的分支。
  • 第二个父提交(-m 2):
    被合并的分支的最新提交。通常是你在 git merge 中指定的分支。
    举例:
    假设你在分支 main 上执行以下命令:

举例:
假设你在分支 main 上执行以下命令:

git merge feature-branch

合并完成后产生的提交(假设哈希为 abcdef)有两个父提交:

  1. 第一个父提交(-m 1):
    这是 main 分支在合并之前的最新提交(git merge 时 HEAD 所在的提交)。
    第二个父提交(-m 2):
  2. 这是 feature-branch 分支的最新提交(被合并的分支)。
    合并后,新提交 abcdef 会记录这两个父提交。

四、一般在撤销合并时选择哪一个父提交?

在撤销合并提交时,通常我们需要保留当前分支的内容(第一个父提交,-m 1),并撤销被合并分支(第二个父提交)的更改。

常见场景:

  1. 合并后发现问题,需要撤销合并:
    如果你在分支 main 上合并了 feature-branch,发现合并有问题,想回到合并前的状态,通常需要保留 main 分支的内容(第一个父提交)。
    使用 git revert -m 1 ,表示保留第一个父提交的内容,撤销第二个父提交的改动。
  2. 特殊情况:
    如果你需要保留被合并分支的内容(feature-branch),而丢弃当前分支的内容,则需要使用 -m 2。这种情况很少见,通常在合并误操作时才会需要。

如何选择父提交?

  1. 默认选择第一个父提交(-m 1):
  • 在绝大多数情况下,-m 1 是正确的选择,因为你通常希望保留当前分支的内容,而撤销被合并分支的更改。
  • 例如:
git revert -m 1 <merge-commit>
  1. 特殊情况下选择第二个父提交(-m 2)
  • 这种情况非常少见,通常发生在合并的方向搞错了,导致需要撤销当前分支的内容而保留被合并分支的内容。
  • 如果需要这样操作,则使用:
git revert -m 2 <merge-commit>

五、撤销合并的影响

  1. git revert 不会删除合并提交本身:
    它只是创建一个新的提交,用来撤销合并提交的改动,但合并提交仍然保留在提交历史中。
    这对于协作开发非常重要,因为它不会破坏其他人的提交历史。
  2. 如果你想完全移除合并提交:
    可以使用 git reset,这会修改提交历史,但通常需要强制推送,可能对团队协作产生影响。
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐