你如何维护开发代码和生产代码?

150

如何在维护代码时遵循最佳实践和经验法则?将只有生产就绪的代码放在开发分支中是一种良好的实践吗?还是未经测试的最新代码应该在开发分支中可用?

你们如何维护你们的开发代码和生产代码?

编辑 - 补充问题 - 在向开发分支提交代码时,您的开发团队是否遵循“尽快提交并经常提交即使代码包含小错误或不完整”协议或“仅提交完美代码”协议?


我之前回答过一个类似的问题(或者说,同一领域/方向的问题),因此您可能想查看这个问题:[有哪些好的策略可以使部署的应用程序支持热修复?] (https://dev59.com/NUXRa4cB1Zd3GeqPq1VA) - Till
@revo:等一下……我的2008年的回答已经过时了吗? :) 我想确实是这样。已经过去十多年了:我已经编辑了我的回答。 - VonC
12个回答

131

2019年更新:

现在,这个问题常常会在使用Git的情境下出现,并且10年来使用分布式开发工作流程(主要通过GitHub协作)显示了一般最佳实践:

  • master是随时准备好部署到生产环境的分支:下一个发布版本,合并了特定功能分支的master
  • dev(或集成分支,或“next”)是测试下一个要发布的功能分支的分支
  • maintenance(或hot-fix)分支是当前发行版演进/错误修复的分支,可能会合并回dev和/或master
那种工作流程(其中你不将dev合并到master,而是仅将特性分支合并到dev,然后如果选择,再合并到master,以便能够轻松删除未准备好进行下一个发布的特性分支)在Git存储库本身中实现,使用gitworkflow(一个单词,在这里说明)。请查看rocketraman/gitworkflow获取更多信息。与基于主干的开发相比,这种方法的历史记录在Adam Dymitruk的这篇文章的评论和讨论中有所提及。

https://github.com/rocketraman/gitworkflow/raw/master/docs/images/topicgraduation.png

注意:在分布式工作流中,您可以随时提交,并将一些WIP(正在进行的工作)推送到个人分支,而不会出现问题:在将它们合并到特性分支之前,您可以重新组织(git rebase)您的提交。 (来源:Gitworkflow:任务导向的入门指南

原始答案(2008年10月,已经超过10年)

这完全取决于您发布管理的顺序性质。

首先,您的主干中是否真的包含了下一个版本的所有内容?您可能会发现当前开发的一些功能:

  • 太复杂,仍需要优化
  • 没有准备好
  • 有趣但不适用于此下一个版本

在这种情况下,主干应包含任何当前的开发工作,但是在下一个版本之前定义一个发布分支可以作为合并分支,其中只合并适用于下一个版本的代码(经过验证),然后在同步阶段进行修复,并最终冻结以进入生产环境。

当涉及到生产代码时,您还需要管理补丁分支,同时要记住:

  • 第一组补丁实际上可能会在第一次生产之前开始(这意味着您知道您将无法及时解决一些错误,但您可以在单独的分支中启动这些错误的工作)
  • 其他补丁分支将从明确定义的生产标签开始

当涉及到开发分支时,您可以有一个主干,除非您需要进行其他并行的开发工作,例如:

  • 大量重构
  • 测试新的技术库,这可能会改变您在其他类中调用事物的方式
  • 开始一个新的发布周期,需要合并重要的架构更改。

现在,如果你的开发-发布周期非常顺序化,你可以像其他回答建议的那样去做:一个主干和几个发布分支。这适用于小型项目,其中所有开发都肯定会进入下一个版本并且可以被冻结,作为发布分支的起点,在此处可以进行补丁。这是名义上的过程,但是一旦你有了更复杂的项目...它就不再足够。


回答 Ville M. 的评论:

  • 请记住,“dev”分支并不是“每个开发人员一个分支”(这会触发“合并疯狂”,因为每个开发人员都必须合并其他人的工作才能看到/获取他们的工作),而是针对每个开发任务有一个“dev”分支。
  • 当这些任务需要合并回主干(或任何其他您定义的“主”或发布分支)时,这是开发人员的工作,而不是 - 我重复一遍,不是 SC 管理员(他不知道如何解决任何冲突的合并)。项目领导者可能监督合并,意思是确保它按时开始/结束。
  • 无论您选择谁来实际执行合并,最重要的是:
    • 拥有单元测试和/或组装环境,可以部署/测试合并结果。
    • 在合并开始之前定义一个标签,以便在合并被证明过于复杂或耗时时能够回到之前的状态。

你如何确保master(生产环境)和dev(集成环境)不会分歧?特别是在热修复时?你是否定期将master合并回dev,例如在发布后进行? - Bergi
1
@Bergi 使用git workflow,dev是一个短暂的分支,在每个新版本发布时被删除并重新创建。没有分歧。 - VonC
1
自从这篇文章最初发布已经过去了12年以上,但我想说的是,这个答案仍然非常有用和现实。 - Matheus
1
@MatheusCirillo 谢谢你,Matheus。实际上我在2019年修订了这个答案,提到了gitworkflow。但我很高兴它仍然有用。 - VonC

45

我们只使用开发分支,直到项目接近完成或我们正在创建里程碑版本(例如产品演示、演示版本),然后我们定期将当前开发分支分支成发布分支。

  • 发布分支

不会有新功能进入发布分支。只有重要的错误会被在发布分支中修复,而用于修复这些错误的代码会重新集成到开发分支中。

通过开发和稳定(发布)分支的两个步骤可以让我们的生活变得更加容易,我认为如果引入更多的分支,我们无法改善任何部分。每个分支也都有自己的构建过程,这意味着每隔几分钟就会产生一个新的构建过程,因此在进行代码检查后,大约半小时内就会得到所有构建版本和分支的新可执行文件。

偶尔我们也会为单个开发人员工作的新技术或创建概念验证而创建分支。但通常只有当更改影响到代码库的许多部分时才会这样做。这种情况平均每3-4个月发生一次,这样的分支通常在一个月或两个月内重新集成(或废除)。

通常我不喜欢每个开发人员都在自己的分支上工作,因为这会直接跳过集成工作而进入“集成地狱”。我强烈反对这种做法。如果你有一个共同的代码库,你们应该一起工作。这使得开发人员更加警惕他们的检查,在经验方面,每个编码人员都知道哪些更改可能会破坏构建,因此在这种情况下测试更加严格。

关于早期提交的问题:

如果要求只提交完美的代码,那么实际上什么都不应该提交。没有代码是完美的,而且对于QA来验证和测试它,需要将其放到开发分支中以便可以构建新的可执行文件。

对于我们而言,这意味着一旦开发人员完成并测试了某个功能,就会进行检查。即使存在已知的(非致命性)缺陷,它也可能被检查,但在这种情况下,通常会通知受到缺陷影响的人。未完成和正在进行中的代码也可以被检入,但只有在不会造成明显负面影响(如崩溃或破坏现有功能)的情况下才可以。

偶尔会出现无法避免的代码和数据混合检查,在新代码构建完毕之前程序将无法使用。最基本的做法是在检查注释中添加“等待构建”字样和/或发送电子邮件通知。


1
我投了赞成票。这与我们所做的类似,但我们正在开发中进行所有更改,然后尝试将这些错误修复合并到发布分支中...不起作用。然而,我认为如果我们改为在发布中进行所有错误修复并合并到开发中,那就可以解决问题了。 - TheCodeMonk
2
你的意思是QA测试开发分支,他们检查发布分支不是更好吗?这样我就可以开始开发我的新功能了,而这个新功能不会被包含在下一个版本中(可能会破坏某些东西),同时QA将测试现有代码而不受我的新功能干扰。 - BornToCode

16

就我所知,这是我们的做法。

大多数开发都在主干(trunk)上进行,虽然实验性功能或可能会显著破坏系统的东西往往会有自己的分支。这样做效果不错,因为这意味着每个开发者在他们的工作副本中总是拥有最新版本的所有内容。

这也意味着保持主干的工作状态非常重要,因为它完全有可能彻底打破它。在实践中,这种情况并不经常发生,而且很少成为一个重大问题。

对于生产版本,我们从主干创建分支,停止添加新功能,并开始修复漏洞和测试该分支(定期合并回主干),直到准备好发布。在此之后,我们对主干进行最后合并以确保一切都在那里,然后发布。

随后可以根据需要在发布分支上执行维护,并可以轻松地将这些修复合并回主干。

我不断言这是一个完美的系统(它仍然存在一些漏洞-我认为我们的发布管理流程还不够紧密),但它已经足够好用了。


足够好用,对于只编写代码而不使用版本控制系统的开发人员来说也足够简单。 - Matthieu

14

为什么没有人提到这个?一个成功的Git分支模型

对我来说,这是终极的分支模型!

如果你的项目很小,不要一直使用所有不同的分支(也许你可以跳过小功能的特性分支)。但否则,这就是做法!

分支模型


4
是的,除非它太复杂/完整,就像http://scottchacon.com/2011/08/31/github-flow.html所示。 - VonC
我同意。理解git flow分支模型(可以解决很多问题),并简化它以适应您的需求。GitHub流需要快速部署,但这并不总是可能的...这更或多或少是我们在项目中使用的分支模型(为了保持简单),但我们遇到了一个情况,我们本来很想使用git-flow模型:(,这让我们陷入了非常大的困境:( - Philippe
1
我认为,这基本上是对VonC大约1年前(在他的回答中)所说的一切的复制,但以更详细的方式和漂亮的图片呈现! - cregox
为什么还没有人提到这个?因为这个内容(提出的模型)已经有13年了,作者VD对事物的发展、进展等进行了更新的评论。在我看来,这不仅仅是关于“最佳实践”,更多地是关于平衡管理层意见的行动,关于你所做的事情。 - user5248982

6

在分支上开发代码,将实时代码标记在主干上。

没有必要制定“只提交完美代码”的规则 - 开发人员遗漏的任何内容都应该在四个地方被发现:代码审查、分支测试、回归测试和最终QA测试。

以下是更详细的逐步说明:

  1. 在分支上进行所有开发,并随时提交代码。
  2. 完成所有开发后,对更改进行独立的代码审查。
  3. 然后将分支交给测试。
  4. 一旦分支测试完成,将代码合并到发布候选分支中。
  5. 每次合并后,都对发布候选分支进行回归测试。
  6. 在所有开发分支合并后,对RC进行最终的QA和UA测试。
  7. 通过QA和UAT测试后,将发布分支合并到MAIN/TRUNK分支中。
  8. 最后,在此时标记主干,并将该标记部署到实时环境中。

4

开发人员使用主干(svn风格)进行开发,而发布的代码则在自己的分支上。

这是“按目的分支模型”(图3见《分支模型的重要性》 /! \ pdf)。


3
我们通过完全将生产代码(主干)与开发代码(每个开发人员都有自己的分支)分离来解决这个问题。
在经过QA和代码审查人员彻底检查之前,不允许任何代码进入生产代码。
这样就不会混淆哪些代码有效,因为它总是主干。

2

哦,是的 - 还有一件事 - 我们将非生产代码(即永远不会发布的代码 - 例如工具脚本,测试实用程序)保留在cvs HEAD中。通常需要明确标记,以免有人“意外”发布它。


2
也许将其作为先前答案的编辑会更好。 - Richard Harrison
6
他说 CVS。 :-) - Till

2
我们在主干上进行开发,每两周将其分支并投入生产。只有关键错误会在分支中修复,其余错误可以等待另外两周。
对于主干,唯一的规则是提交不应该破坏任何东西。为了管理工作进度代码和未经测试的代码,我们只需添加适当的 if 语句,以便轻松切换开关。
基本上,在任何时候都可以分支主干并投入生产。

0

我使用git,有两个分支:mastermaint

  • master - 开发代码
  • maint - 生产代码

当我发布代码到生产环境时,我会打标签并将master合并到maint分支。我总是从maint分支部署。从开发分支中挑选补丁并将它们cherry-pick到maint分支中,然后部署补丁。


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