Git 取消合并(不是上次合并)
Git cancel merge (not the last merge)
以下是我们使用 git 的方式。
每个功能都在一个单独的分支中开发。然后,每个服务器都有它的分支 (production = Master, QA=QA)
因此,每次开发人员验证功能时,我们都会将其合并到 QA 分支,我们的 QA 专家会在那里进行验证。
这是一个场景:
周一,第一名开发人员在 QA 中合并功能 1 (merge1)
星期二在质量检查 (merge2) 中排名第二的开发人员合并功能2
第三名开发人员在星期三的 QA 中合并了功能 3 (merge3)
星期五,QA 专家决定功能 2 和功能 3 很好,但我们必须修复功能 1。
所以我的问题是,在Git中是否可以只取消merge1,而保留其他的?
非常感谢
由于 QA 分支可能由许多开发人员和 QA 专家共享,因此重写历史将花费大量成本。 (也不容易做到,因为分支由合并组成。)
相反,您可以还原 functionality_1
的合并。这也有一些复杂性,尤其是当您修复了 functionality_1
并想将其重新引入 QA
时。我将暂时完成该过程。
但是因为执行此操作的所有方法 (1) 都有如上所述的成本,并且 (2) 也 可能 涉及冲突解决,您可能需要考虑另一种选择:是是否可以修改您的工作流程以尽量减少或消除这样做的需要?涉及所有工作流设计考虑因素超出了此答案的范围,但如果可以避免这种情况,则可以避免麻烦。
无论如何,要恢复合并,您需要一个解析为合并提交的表达式。这可能是合并提交 ID,或者类似 QA~3
的东西,假设您提到的三个合并是 QA
分支上的三个最新提交。
git revert -m1 QA~3
将在 QA 分支上创建一个新提交,其中 "undoes" 合并引入到 QA
分支的更改。 (我这么说是在做出某些假设,但它们应该适用于您描述的工作流程。)
... M1 -- M2 -- M3 -- !M1 <--(QA)
所以这部分很简单,但是简单地再次合并 functionality_1
不会重新引入您还原的更改,因为从 git 的角度来看,它们已经在 [=16= 中说明了].当需要重新引入 funcitonality_1
时,您将有两个选择:
(1) 还原!M1
,然后合并functionality_1
的余数;如果此后没有其他内容被合并到 QA
,那么 QA
将解析为 !M1
,您可以说
git revert QA
或者
(2) "force rebase" functionality_1
,从新提交重新创建分支,然后将重新创建的分支合并到 QA
。为此,您需要能够识别 "reachable from" functionality_1
之前 "reachable from" QA
直到 M1
的所有更改。如果您不想更改提交拓扑,则需要知道分支点(即引入此类更改的第一个提交的父级)。然后你会说
git rebase -f P functionality_1
其中 P
是解析为父提交的表达式。
这是 functionality_1
分支的历史重写,因此如果您将单个分支保留在删除状态,则必须强制推送它(其他所有人都必须从上游恢复变基条件;参见 git rebase
文档)。
但这将使合并行为符合预期。
以下是我们使用 git 的方式。
每个功能都在一个单独的分支中开发。然后,每个服务器都有它的分支 (production = Master, QA=QA)
因此,每次开发人员验证功能时,我们都会将其合并到 QA 分支,我们的 QA 专家会在那里进行验证。
这是一个场景:
周一,第一名开发人员在 QA 中合并功能 1 (merge1)
星期二在质量检查 (merge2) 中排名第二的开发人员合并功能2
第三名开发人员在星期三的 QA 中合并了功能 3 (merge3)
星期五,QA 专家决定功能 2 和功能 3 很好,但我们必须修复功能 1。
所以我的问题是,在Git中是否可以只取消merge1,而保留其他的?
非常感谢
由于 QA 分支可能由许多开发人员和 QA 专家共享,因此重写历史将花费大量成本。 (也不容易做到,因为分支由合并组成。)
相反,您可以还原 functionality_1
的合并。这也有一些复杂性,尤其是当您修复了 functionality_1
并想将其重新引入 QA
时。我将暂时完成该过程。
但是因为执行此操作的所有方法 (1) 都有如上所述的成本,并且 (2) 也 可能 涉及冲突解决,您可能需要考虑另一种选择:是是否可以修改您的工作流程以尽量减少或消除这样做的需要?涉及所有工作流设计考虑因素超出了此答案的范围,但如果可以避免这种情况,则可以避免麻烦。
无论如何,要恢复合并,您需要一个解析为合并提交的表达式。这可能是合并提交 ID,或者类似 QA~3
的东西,假设您提到的三个合并是 QA
分支上的三个最新提交。
git revert -m1 QA~3
将在 QA 分支上创建一个新提交,其中 "undoes" 合并引入到 QA
分支的更改。 (我这么说是在做出某些假设,但它们应该适用于您描述的工作流程。)
... M1 -- M2 -- M3 -- !M1 <--(QA)
所以这部分很简单,但是简单地再次合并 functionality_1
不会重新引入您还原的更改,因为从 git 的角度来看,它们已经在 [=16= 中说明了].当需要重新引入 funcitonality_1
时,您将有两个选择:
(1) 还原!M1
,然后合并functionality_1
的余数;如果此后没有其他内容被合并到 QA
,那么 QA
将解析为 !M1
,您可以说
git revert QA
或者
(2) "force rebase" functionality_1
,从新提交重新创建分支,然后将重新创建的分支合并到 QA
。为此,您需要能够识别 "reachable from" functionality_1
之前 "reachable from" QA
直到 M1
的所有更改。如果您不想更改提交拓扑,则需要知道分支点(即引入此类更改的第一个提交的父级)。然后你会说
git rebase -f P functionality_1
其中 P
是解析为父提交的表达式。
这是 functionality_1
分支的历史重写,因此如果您将单个分支保留在删除状态,则必须强制推送它(其他所有人都必须从上游恢复变基条件;参见 git rebase
文档)。
但这将使合并行为符合预期。