避免将 master 合并到开发分支中
Posted
技术标签:
【中文标题】避免将 master 合并到开发分支中【英文标题】:Avoid merging master into development branch 【发布时间】:2015-03-29 22:19:54 【问题描述】:从每个 sprint 开始,我一直在监视两个分支 - Release
和 Master
。
Master
分支是开发人员创建新分支(特定于任务)、实施更改并创建合并到 Master
的拉取请求的地方。
Release
分支是特定于 sprint 的,它始终可以提交给生产。我们只将提交给Master
并由QA 验证的分支合并到Release
分支中。
这种方法最适合我们,因为我们会定期提交 Release
,并实施和验证特定功能,因此我们确切知道下一个版本会发生什么。
在我遇到以下问题之前一切顺利;
-
DeveloperA 已从
Master
创建了特定于任务的分支,例如 taskA
。
他已经多次提交给taskA
分支。
平均而言,其他开发人员B 从Master
创建了他的分支taskB
,并对taskB
提交了多项更改,并将taskB
合并到Master
。
DeveloperA 会将Master
合并到taskA
分支并继续他的任务,并将更多更改提交到taskA
分支!
最终他会将taskA
分支合并到Master
。
现在我只想将taskA
分支合并到Release
分支,但是taskB
也被合并到taskA
分支中,因为DeveloperA 在步骤#4 中将Master
合并到他的分支中,我得到taskB
分支自动更改为Release
分支!我不想要那个。
避免将Master
合并到Developer
分支的最佳方法是什么?在我的情况下,应该遵循的正确方法是什么?
【问题讨论】:
即使在您的工作流程中也不应该出现此问题。请详细说明此工作流程中使用的命令。解决方法之一是在 taskA 合并到 master 之后将 taskB 重新设置为 master。 你最后提到了一个Developer分支,你的意思是Release吗? @Schwern 不,我的意思是它是开发分支。主要问题是 taskA 包含 taskB 更改,所以我不能只将 taskA 合并到 Release 分支。 @applefreak 您在问题的其他任何地方都没有提到开发人员或开发分支。你能澄清一下吗?你的意思是像taskA和taskB这样的任务/功能分支吗? @Schwern 的开发分支我的意思是 taskA 或 taskB 分支。很抱歉造成混乱。 【参考方案1】:我觉得你的策略太复杂了,容易出问题。复杂之处在于试图将功能分支分别集成到 Release 和 Master 中。因为功能是在 Master 上开发的,所以每个功能分支都将利用早期的功能和错误修复。当您尝试将功能分支单独合并到 Release 中时,Release 可能没有集成它所依赖的早期功能和错误修复。问题、冲突、并发症。
如果你从 Master 中创建功能分支,将它们合并到 Master,并定期将 Master 合并到 Release,这会简单得多。合并流程是 Features -> Master -> Release。从不功能 -> 发布。实际上,应该有中间测试和暂存分支来保存当前处于最终用户测试中的版本(这是在功能分支单元测试之上),以及为下一个版本准备的内容。功能 -> 主 -> 测试 -> 暂存 -> 发布。
也就是说,让我们把你的问题画出来。
DeveloperA 已从 Master 创建了特定于任务的分支,例如 taskA。他已经多次提交给taskA分支。
A - B [master]
\
C - D [taskA]
意思是当其他开发者 B 从 Master 创建他的分支 taskB 并提交对 taskB 的多个更改并将 taskB 合并到 Master 中。
F - G
/ \
A - B - E ----- H [master]
\
C - D [taskA]
DeveloperA 将 Master 合并到 taskA 分支并继续执行他的任务,并将更多更改提交到 taskA 分支!
F - G
/ \
A - B - E ----- H [master]
\ \
C - D ----- I - J - K [taskA]
最终他会将taskA分支合并到Master中。
F - G
/ \
A - B - E ----- H --------- L [master]
\ \ /
C - D ----- I - J - K
现在我只想将 taskA 分支合并到 Release 分支,但是由于在步骤#4 中,由于 DeveloperA 将 Master 合并到他的分支中,taskB 也被合并到 taskA 分支中,所以我将 taskB 分支更改自动到 Release 分支!我不想那样。
你有几个选择。您可以 git cherry-pick
仅将 taskA 中的提交放入 Release,避免合并提交。那是 C、D、J 和 K。如果 J 或 K 依赖于 taskB 中的任何内容(或 Master 中不在 Release 中的任何其他内容),您将遇到冲突或(希望)测试失败。这是一个混乱的手动过程。
第二个选择,而不是使用合并从 Master 获取更新的功能分支,rebase 在 master 之上。当 taskA 的开发者决定从 master 更新时,如果他们运行 git rebase master
而不是 git merge master
,他们就会有这个。
F - G
/ \
A - B - E ----- H [master]
\ \
C - D C1 - D1 [taskA]
C 和 D 将在 master 的新位置上重新修补。开发人员必须处理任何冲突和测试问题。然后他们可以继续工作并在完成后合并到 master 中。
F - G
/ \
A - B - E ----- H ----------------- L [master]
\ \ /
C - D C1 - D1 - J1 - K1 [taskA]
这种方法使分支保持整洁,没有中间合并。您可以挑选整个分支来发布,而不必挑选中间合并。如果 taskA 依赖于尚未合并到 Release 中的任何内容,您仍然会遇到冲突和测试失败,但至少隔离功能的过程更简单。
因为您的工作流程需要您两次集成功能分支,并且可能以不同的顺序进行,所以您肯定会遇到冲突。如果它们只是不得不再次无序地合并到 Release 中,那么将它们合并到 Master 中确实没有意义。
我强烈建议您更改流程,以便您只需将功能分支一次集成到 Master 中。 Release 只是 Master 的早期版本。如果一个特性分支还没有准备好发布,不要合并它。总的来说,这是一种很好的开发实践,它提高了开发人员正在使用的代码的质量(即 Master),并且避免了开发人员不得不处理一堆不稳定的半成品功能。
有时您会希望对 Release 应用热修复,这很好。有时你会想从 Master 中删除一个特性,这也很好。这些应该是特殊任务,而不是正常的工作流程。
【讨论】:
Gitflow workflow仅供参考。 @Basilevs 是的,Gitflow 符合我在这里所倡导的。 谢谢@Schwern 你有很好的观点,但大多数我已经想到了——例如“如果一个特性分支还没有准备好发布,不要合并它。” - 问题是 QA 将如何测试?我们每晚从 Master 构建以供 QA 测试,而您错过了我只想将“已测试和已验证”分支合并到 Release 的要点。 TaskA 永远不会依赖于先前的任务,如果是,它们将被合并到 Release。如果我们错过了,我们很容易在回归中抓住它们。我也在考虑使用 Rebase,但仍在尝试使流程健壮。 @applefreak 在我继续之前,请澄清一些“TaskA 永远不会依赖于先前的任务”。我想您的意思是 TaskA 永远不会依赖于以前的任务未合并到 Release。你如何保证这一点?您将所有内容合并到 Release 中的顺序是否与将它们合并到 Master 中的顺序相同? 谢谢@Schwern 这是新问题 - ***.com/questions/29377952/…以上是关于避免将 master 合并到开发分支中的主要内容,如果未能解决你的问题,请参考以下文章
自动 - 在将分支合并到 master 时增加 master 上的补丁版本
将分支代码合并到master和将master代码合并到dev
在 Artifactory Release Staging 之后使用 Jenkins 将 git develop 分支合并到 master