由于 QA 分支可能由许多开发人员和 QA 专家共享,因此重写历史记录会产生大量成本。 (也不容易做到,因为分支由合并组成。)
相反,您可以恢复 functionality_1 的合并。这也有一些复杂性,尤其是当您修复了functionality_1 并希望将其重新引入QA 时。我将暂时完成该过程。
但是由于所有执行此操作的方法 (1) 都有上述成本,并且 (2) 还可能涉及解决冲突,您可能需要考虑另一种选择:是否可以修改您的工作流程以最小化或消除这样做的需要?涉及所有工作流设计考虑因素超出了此答案的范围,但是如果可以避免这种情况,则可以省去麻烦。
无论如何,要恢复合并,您需要一个解析为合并提交的表达式。这可能是合并提交 ID,或者类似于 QA~3 的东西,假设您提到的三个合并是 QA 分支上的三个最新提交。
git revert -m1 QA~3
将在 QA 分支上创建一个新提交,这会“撤消”合并引入 QA 分支的更改。 (当我这么说时,我做出了某些假设,但它们应该适用于您描述的工作流程。)
... M1 -- M2 -- M3 -- !M1 <--(QA)
所以这部分很简单,但简单地再次合并 functionality_1 不会重新引入您恢复的更改,因为从 git 的角度来看,它们已经在 QA 中进行了说明。当需要重新引入funcitonality_1 时,您将有两种选择:
(1) 还原!M1,然后合并functionality_1的剩余部分;如果此后没有其他内容被合并到 QA,那么只需 QA 将解析为 !M1,您可以说
git revert QA
或者
(2) "force rebase" functionality_1,从新的提交重新创建分支,然后将重新创建的分支合并到QA。为此,您需要能够识别“可从”functionality_1 到“可从”QA 直到 M1 的所有更改。如果您不想更改提交拓扑,则需要知道分支点(即引入此类更改的第一个提交的父级)。那你会说
git rebase -f P functionality_1
其中P 是解析为父提交的表达式。
这是 functionality_1 分支的历史重写,因此如果您将各个分支保留在删除状态,您将不得不强制推送它(其他所有人都必须从上游变基条件中恢复;请参阅git rebase 文档)。
但这会使合并按预期进行。