Git中分支和合并的最佳实践

56

我们有一个由4个开发人员组成的团队,最近转向使用Git。 我们想学习关于分支和合并工作流的最佳实践。

我们正在使用Git Flow的轻量级版本。 我们有一个dev、staging和master分支,它们之间都是线性的。

  • staging从master分支分出
  • dev从staging分支分出

此外,我们还使用特性和热修复分支来处理新功能和错误修复。

我有以下问题:

  1. 我们应该从dev还是master分支分离特性分支?
  2. 当特性分支准备好时,我们应该将特性分支合并到dev中,然后将dev合并到staging中,还是将特性分支合并到staging中,然后再将特性分支合并到master中?

我认为我们应该从master分支分离,并将特性分支合并到更高级别的分支上,因为在dev中可能存在一些我们不想要合并到staging和master中的内容。

您的观点是什么? 有哪些最佳实践?


1
可能是具有开发、暂存和生产分支的Git的重复问题。 - Liam
5
在我看来,这不是一个重复的问题。紧密相关?是的。重复?不是。这个问题基于 Git Flow 模型,而链接的问题引用了一篇类似但不完全相同的工作流程文章。 - Sascha Wolf
https://git-scm.com/docs/merge-strategies - Channa
3个回答

44
虽然Git Flow是一个优秀的分支模型,但你所提出的问题是更大问题的症状:Git Flow对于小型消费者Web产品团队来说过于繁重(我假设你正在开发消费者Web产品,如果你在编写核电站控制室,请忽略此假设)。
我建议你考虑采用极简单的分支模型进行持续部署(CD):

Master -> Branch

现在设置CD非常容易:

  1. 使用TravisCodeShip,Jenkins或类似系统,在每次提交代码时在每个分支上运行完整的构建和测试套件
  2. 设置Travis/Codeship/Jenkins,以便在通过测试的情况下将每次提交到主分支的代码部署到生产环境。
  3. 为每个新功能从master创建一个新分支。
  4. 在分支上编写新功能并进行测试。
  5. 将功能分支合并到master中,并观察其上线。

有很多常见的反对意见,可以总结为“但如果我引入了错误怎么办?!”答案是“你会修复它的!”。如果您编写测试,监视生产站点,进行代码审查,练习成对编程,使用功能标志,并保持功能小,则从CD获得的好处将在任何一天都超过偶尔出现的问题。

我鼓励你尝试一下。这将使你的思维解放,专注于真正重要的事情:构建一个伟大的产品!如果你不相信我,可以看一下这个来自Github的精彩演示


1
谢谢,这是梦想目标。但是经理们希望将代码部署到测试、预发布和生产环境中。不确定这如何符合简单性。 - Gaui
2
它实际上非常适合。无论您在分支上放置什么,都可以通过任意数量的测试:您可以在自己的计算机上进行测试并合并,或者将其放在“暂存区”并让10人的QA团队对其进行两周的测试。您需要为每个功能使用适当的测试级别。单行消息更改不应该经过与新购物车结帐流程相同的测试过程。CD允许您做到这一点,使您的分支保持简单。 - quarterdome
4
这似乎是较小团队的最佳解决方案,正如您所提到的。没有必要让过程变得复杂。感谢分享幻灯片。 - Adam
1
对于@Airborne的言论,另一个观点是:似乎最好的解决方案是拥有更小(且跨职能)的团队。没有必要复杂化流程。 - Matruskan
我喜欢这个答案,但第一反应是退缩。什么?我们需要所有这些分支、进程和锁定,以便不会发布错误。但我认为这种流程发生是因为你的“ifs”部分中的内容被跳过了。正是每隔 x 周进行单块构建的做法让人感到害怕。 - redOctober13
很容易被可能会让漏洞溜走的想法困住并感到恐慌,但这是学习过程中自然的一部分。你必须学会喜欢失败,或者至少容忍它,才能有所进步。尽力编写有效的测试,记住安全编码的原则,如果出了问题,假设你一直在定期提交代码,Git 的整个意义就在于你可以回滚以找出问题所在。 - Twisted Code

30

这完全取决于你想如何工作和团队协商。话虽如此。

  1. 一个功能从dev分支开始进入自己的分支。从master分支,你只应该分支hotfixes,因为master分支应始终是软件的稳定版本
  2. 当一个功能分支完成后,它应该被合并到dev分支,然后在某个时候,你应该从dev(包括一些功能)中创建你的下一个发布的分支到一个新的'release/*'分支,一旦稳定并经过充分测试就会被合并到主分支上。

Atlassian页面上,你可以找到这种工作流程的非常好的解释

这种工作流程的整个思想是,有一个稳定的版本分支,在其中你可以工作并立即修复任何错误,如果需要,你有足够的信心保持其稳定性,并且不会发生任何新的功能或重构而不会被注意到。

此外,每个新功能都可以在自己的分支中进行隔离和自由开发,没有来自其他功能的干扰。然后,你将把你的功能合并到dev分支中,再从那里合并到master分支中以发布下一个版本。

我唯一建议你的是学习如何在另一个功能合并到dev时,每次在dev分支之上重新拉取你的功能分支,以避免在合并时解决冲突,而是在你知道自己更改内容的特性分支中进行独立处理。

貌似此前也有人问过这个问题


如果您没有(预定义的)发布版本,并且不希望将dev中的所有内容都放入stagingmaster中,该怎么办?岂不是最好的方法是从主分支中分离出功能分支,在其中独立地处理该功能,然后将其合并到dev中。如果可以,请将功能分支合并到staging中。如果被接受,请将功能分支合并到master中并部署到生产环境。如果我们将功能分支合并到dev,然后将dev合并到staging,可能会有一些我们不想要的功能。此外,如果某些内容在staging上,而不应该进入master,那就有问题了。 - Gaui
通常情况下,开发工作是可以称之为“你的下一个版本发布”的。在一个项目中,我做了类似你说的事情,最终结果还不错,但在合并时却需要大量重构工作,主要是因为你可能会将来自早期版本的功能合并到主分支上,而代码库已经发生了很大变化。因此,如何安排工作取决于你自己,但我的猜测是,在某个时候你将能够如此安排:好的,这些功能应该在下一次发布时发布,然后就需要将其合并到“dev”分支上,或者直接使用主分支上的发布分支,而不是使用“dev”。 - Pablo Carranza

16
我们采用了一种名为Git Flow的工作流程,但与其从dev分支功能,我们从当前版本分支它们。这使我们能够以不同的速度处理不同的问题。如果它们在QA中成功,则进入发布版。
关于分支和部署:
- dev分支会自动部署到测试服务器。 - 当前版本分支会自动部署到预发布服务器。 - master分支由发布管理员手动部署到生产服务器。
工作流程如下:
  1. 在每个发布/冲刺的开始,从 master 创建一个发布分支,例如 release/2015-may
  2. release/2015-may 创建一个 dev 分支。
  3. 在开发新功能时,从发布分支创建并将其命名为 feature/ISSUE_NUMBER
  4. 开发功能。
  5. 当准备好进行测试时,请将其合并到 dev 分支。
  6. 如果被接受,请将其合并到当前发布分支中。
  7. 如果未被接受,请返回第4步。
  8. 当发布准备就绪时,请将其合并到 master

在发布已部署到生产环境后,如果发现了关键性错误,则从 master 分支创建一个热修复分支(例如 hotfix/ISSUE_NUMBER),将其合并回 master 并重新部署。


但是,如果同时启动了2个或更多新功能,这种方法将如何处理?例如,发布/2015年5月-> dev->然后feature/1和feature/2。那么,如果feature/1和feature/2都合并到dev中,只有feature/1被接受,会怎样呢? - Kamalakannan J
@KamalakannanJ 只有 feature/1 才会合并到 staging/release。 - Gaui
那么我们必须直接将 feature/1 合并到 staging/release 中吗?而不是通过 dev-> staging/release? - Kamalakannan J
是的,首先将功能合并到dev分支。如果在dev上被接受,那么你就可以将该功能合并到staging/release分支中。 - Gaui

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接