避免将 master 合并到开发分支中

app*_*eak 6 git git-merge

我一直在监视从每个冲刺开始的两个分支 -ReleaseMaster

Master分支是开发人员创建新分支(特定于任务)、实现更改并创建合并到Master.

Release分支是特定于冲刺的,始终可提交给生产。Master我们只将提交给并由 QA 验证的分支合并到Release分支中。

这种方法最适合我们,因为我们Release定期提交并实现和验证了特定功能,因此我们确切地知道下一个版本中会发生什么。

一切进展顺利,直到我遇到以下问题;

  1. DeveloperA 已经创建了任务特定分支,比如taskA来自 的Master
  2. 他曾多次承诺成立taskA分支机构。
  3. 与此同时,其他开发者 BtaskB从 中创建了他的分支Master并向 提交了多项更改taskBtaskB合并到 中Master
  4. DeveloperA 将合并MastertaskA分支并进一步继续他的任务,并将更多更改提交到taskA分支!
  5. 最终他将把taskA分支合并到Master.

现在我只想将taskA分支合并到Release分支,但随着 DeveloperA 在步骤#4 中合并到他的分支中,我taskB也将分支合并到分支中,我会自动将分支更改合并到分支中!我不想要这样。taskAMastertaskBRelease

避免合并MasterDeveloper分支的最佳方法是什么?就我的情况而言,正确的方法是什么?

Sch*_*ern 4

我认为你的策略太复杂并且容易出现问题。复杂之处在于尝试将功能分支分别集成到发布版和主版中。由于功能是在 Master 上开发的,因此每个功能分支都将利用早期的功能和错误修复。当您尝试将功能分支单独合并到Release时,Release可能没有集成它所依赖的早期功能和错误修复。问题、冲突、复杂化。

如果您从 Master 中创建功能分支,将它们合并到 Master 中,然后定期将 Master 合并到 Release 中,那就简单多了。合并流程是Features -> Master -> Release。从不功能 -> 发布。实际上,应该有中间测试和暂存分支来保存当前处于最终用户测试中的版本(这是在功能分支单元测试之上),以及为下一个版本做好准备的内容。功能 -> 主控 -> 测试 -> 登台 -> 发布。


也就是说,让我们用图表来解决你的问题。

DeveloperA 已从 Master 创建了特定于任务的分支,例如 taskA。他已多次提交给taskA 分支。

A - B [master]
     \
      C - D [taskA]
Run Code Online (Sandbox Code Playgroud)

与此同时,其他开发人员B从Master创建了他的分支taskB,并对taskB提交了多个更改,并将taskB合并到Master中。

          F - G    
         /     \
A - B - E ----- H [master]
     \
      C - D [taskA]
Run Code Online (Sandbox Code Playgroud)

DeveloperA会将Master合并到taskA分支并进一步继续他的任务,并将更多更改提交到taskA分支!

          F - G    
         /     \
A - B - E ----- H [master]
     \           \
      C - D ----- I - J - K [taskA]
Run Code Online (Sandbox Code Playgroud)

最终他会将taskA分支合并到Master中。

          F - G    
         /     \
A - B - E ----- H --------- L [master]
     \           \         /
      C - D ----- I - J - K
Run Code Online (Sandbox Code Playgroud)

现在我只想将taskA分支合并到Release分支,但是当DeveloperA在步骤#4中将Master合并到他的分支时,taskB也被合并到taskA分支中,我将taskB分支更改自动合并到Release分支中!我不想要这样。

你有几个选择。你可以git cherry-pick只能将taskA中的提交提交到Release中,从而避免合并提交。这就是 C、D、J 和 K。如果 J 或 K 依赖于 taskB 中的任何内容(或 Master 中不在 Release 中的任何其他内容),您将遇到冲突或(希望如此)测试失败。这是一个混乱的手动过程。

第二个选择,不是使用合并来从 Master 获取更新的功能分支,而是在 master 之上进行 rebase。当taskA的开发人员决定从master更新时,如果他们运行git rebase master而不是运行git merge master,他们就会得到这个。

          F - G    
         /     \
A - B - E ----- H [master]
     \           \
      C - D       C1 - D1 [taskA]
Run Code Online (Sandbox Code Playgroud)

C 和 D 将在 master 的新位置之上重新修补。开发人员必须处理任何冲突和测试问题。然后他们可以继续工作并在完成后合并到 master 中。

          F - G    
         /     \
A - B - E ----- H ----------------- L [master]
     \           \                 /
      C - D       C1 - D1 - J1 - K1 [taskA]
Run Code Online (Sandbox Code Playgroud)

这种方法使分支保持良好和干净,没有中间合并。您可以挑选整个分支来发布,而不必挑选中间合并。如果taskA依赖于任何尚未合并到Release中的东西,您仍然会遇到冲突和测试失败,但至少隔离功能的过程更简单。


因为您的工作流程要求您集成功能分支两次,并且可能以不同的顺序,所以肯定会发生冲突。如果功能必须再次无序地合并到发布版本中,那么将功能合并到主版本中确实没有意义。

我强烈鼓励您更改流程,这样您只需将功能分支集成一次即可集成到 Master 中。Release 只是 Master 的早期版本。如果功能分支尚未准备好发布,请不要合并它。一般来说,这是一种很好的开发实践,它提高了开发人员正在使用的代码的质量(即 Master),并且避免了开发人员不得不处理一堆不稳定的半成品功能。

有时您会想要对发布应用热修复程序,这很好。有时您会想从 Master 中删除某个功能,这也很好。这些应该是特殊任务,而不是正常的工作流程。

  • [Gitflow工作流程](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow)仅供参考。 (2认同)