在以下所有提交中删除合并并取消合并的功能

问题描述

我是git的新手,无法在互联网上找到有关该问题的答案,但很可能已经有人问了。

因此,假设我的认分支为develop。我从开发创建了一个分支,称为feature/test,对该分支进行了一些提交,然后将其合并到develop

 ---1---2---3---4---M---5---6---7--- (develop)
             \     /                
              A---B    (feature/new)

合并M之后,我将继续进行开发,并进行几次提交。

但是现在我想从分支之后的所有提交中取消合并功能分支,就像分支develop从未合并feature/new一样。

这就是我想要的东西:

 ---1---2---3---4---5'---6'---7'--- (develop)
             \                     
              A---B    (feature/new)

如您所见,M之后的所有提交均被修改以撤消已删除的合并带来的修改

是否可以这样做,应该使用哪个命令?

谢谢

解决方法

有很多方法可以做到这一点。

要获取您在图片中描述的历史记录,需要重写历史记录。您应该注意,如果此仓库与他人共享,并且您要重写的历史记录已经共享(推送到远程),则正确进行此操作需要一些协调-因为重写共享历史记录会导致错误情况,如果解决方法不正确,将导致您的工作被撤消。

也就是说,为避免重写历史记录,您将使用git revert(或等效名称)。还原合并 也会产生费用,无论您是否与他人共享历史记录,这些费用都将适用。

因此,一般而言,最好避免合并分支,以免以后需要“取消合并”。但是无法改变过去,您必须充分利用现有的选择。

要决定是否应该重写历史记录,我将参考“从上游基础恢复中”一节中的git rebase文档(https://git-scm.com/docs/git-rebase)。您可能还会查看关于合并(https://git-scm.com/docs/git-revert)的git revert文档。然后根据您的决定执行以下操作之一:

重写历史记录

所以:做您所要求的最简单的方法是

git rebase --onto develop~4 develop~3 develop

这将获取您想要保留的提交,为它们计算补丁,并将这些补丁应用于新的父对象;一些细节:

表达式develop~4develop~3特定于您的示例。

develop~4指的是从develop指向的提交开始,通过跟随“第一父级”指针四次找到的提交。这导致4。通过将其作为--onto参数,您可以告诉rebase应该从此处开始应用它计算的补丁。

类似地,develop~3导致M,因此这是“上游”。这意味着MM可以到达的任何提交(通过父指针)都不会被用来创建补丁。 (如果您不使用--onto,则upsteram也会在应用补丁的位置起作用;但是在这里我们确实使用了--onto,所以没关系。)

应用补丁程序时,可能会发生冲突。这是因为567中的某些内容可能会编辑也由M编辑过的行(或与{ {1}},这会导致git不确定是否存在问题)。任何可靠的方法来执行您要执行的操作都会产生相同的冲突,因此,如果合并从未发生过,您只需弄清楚“应该”进行的更改是什么。

如果M存在于远程中,并且如果develop已被推送到该远程中,则默认情况下git将拒绝推送此更改的结果(因为它删除了M从分支历史中)。您可以使用M命令的--force-with-lease选项覆盖它。 (有些人说使用push选项,但是虽然输入起来更容易,但也不太安全。-f不会检查您不知道的新提交是否已推送到-fdevelop。)

没有重写历史记录

如果您不能(或不想)协调历史记录重写,那么您必须接受您推送的任何历史记录都是不可变的。在这种情况下,您可以还原合并。

--force-with-lease

git revert -m 1 develop~3 选项告诉git您“恢复到”合并的哪个父母;因此说出-m,就可以有效地撤消分支中的更改。

就像历史记录重写方法一样,这可能会发生冲突并需要手动解决冲突。最终结果将是

-m 1

其中1 -- 2 -- 3 -- 4 -- M -- 5 -- 6 -- 7 -- !AB <--(develop) \ / A --- B <--(feature/new) 撤消了!ABA(已在B合并的更改)的更改。

由于MA仍在B的历史中,如果您以后想重新合并它们,这并非易事。您必须先还原develop,或者使用!AB来重写rebase -f的历史记录,然后再进行修改。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...