模式用于管理的源代码分支

现代的源代码控制系统提供了强大的工具,可以方便地在源代码中创建分支。但是最终这些分支必须合并在一起,并且许多团队花费了过多的时间来处理它们错综复杂的分支。有几种模式可以让团队有效地使用分支,集中于集成多个开发人员的工作和组织产品发布的路径。最重要的主题是应该频繁地集成分支,并将工作重点放在健康的主线上,这样就可以以最小的工作量将其部署到生产环境中。

2020年5月28日



源代码是任何软件开发团队的重要资产,几十年来,已经开发了一套源代码管理工具来保持代码的形状。这些工具允许跟踪更改,因此我们重新创建软件的早期版本,并查看它如何随着时间的推移而发展。这些工具对于一个由多个程序员组成的团队的协调也很重要,他们都在共同的代码基础上工作。通过记录每个开发人员所做的更改,这些系统可以一次跟踪多行工作,并帮助开发人员确定如何将这些工作合并在一起。

这种将开发划分为分裂和合并的工作线的做法是软件开发团队工作流程的核心,并且已经发展出一些模式来帮助我们处理所有这些活动。和大多数软件模式一样,很少有一个是所有团队都应该遵循的金标准。软件开发工作流非常依赖于上下文,特别是团队的社会结构和团队遵循的其他实践。

我在这篇文章中的任务是讨论这些模式,我是在一篇文章的上下文中这样做的,在这篇文章中,我描述了这些模式,但是将模式解释与更好地解释上下文和它们之间的相互关系的叙述部分穿插在一起。为了便于区分它们,我用“dingbat”标识了模式部分。

基本模式

在考虑这些模式时,我发现开发两个主要类别是有用的。一组研究积分如何多个开发人员的工作合并成一个连贯的整体。其他着眼于路径生产使用分支来帮助管理在生产中运行的产品从一个集成的代码库的路径。有些模式既巩固这些,现在我会解决这些作为基本模式。留下一对夫妇的既不是基本的模式,也不配合到两个主要群体 - 所以我会离开这些,直到结束。

源分支

创建一个副本并记录对该副本的所有更改。

如果几个人在同一个代码基上工作,他们很快就不可能在同一个文件上工作。如果我想运行编译,而我的同事正在键入表达式,那么编译将失败。我们必须互相喊叫:“我在编译,什么都不要改”。即使有两支球队,这也很难维持下去,如果有一支更大的球队,这将是不可理解的。

简单的答案是为每个开发人员把代码库的副本。现在,我们可以在我们自己的特点很容易的工作,但一个新的问题出现了:我们如何再次合并我们的两个副本一起回来的时候我们做了什么?

源代码控制系统使这个过程变得更加容易。最关键的是,它记录下到每个分支的提交作出的每个改变。不只是这是否是确保没有人忘记他们对所做的变化不大utils.java,记录变化可以更容易地进行合并,特别是当几个人已经改变了相同的文件。

这就引出了本文将使用的分支的定义。我定义了作为提交到代码基的特定序列。这个,或小费,一个分支是最新提交的该序列。

那是名词,但也有动词“to branch”。我的意思是创建一个新的分支,我们也可以把原来的分支分成两部分。当从一个分支提交到另一个分支时,分支合并。

我在“分支”中使用的定义与我观察到的大多数开发人员谈论它们的方式相一致。但是源代码控制系统倾向于以一种更特殊的方式使用“分支”。

我可以用一个现代开发团队的常见情况来说明这一点,这个团队将源代码保存在一个共享的git存储库中。一个开发人员,Scarlett,需要做一些更改,以便她克隆git存储库并签出master分支。她做了一些改变,把这些都交给了她的主人。同时,另一个开发人员,我们称她为Violet,将存储库克隆到她的桌面上,并检查主分支。思嘉和维奥莱特是在同一根树枝上工作还是在另一根树枝上工作?他们都在“master”上工作,但是他们的提交是相互独立的,当他们将更改推回到共享存储库时需要合并。如果Scarlett不确定自己所做的更改,因此标记最后一次提交并将其master分支重置为origin/master(她从共享存储库克隆的最后一次提交),会发生什么情况。

根据我之前给出的分支的定义,斯佳丽和维奥莱特正在处理单独的分支,这两个分支彼此独立,并且与共享存储库上的主分支分离。当斯佳丽把她的工作放在一个标签旁边时,根据我的定义,它仍然是一个分支(她很可能认为它是一个分支),但用git的话说,它是一个带标签的代码行。

有了这样的git的分布式版本控制系统,这意味着我们还可以得到额外的分支机构,只要我们进一步克隆库。如果斯嘉丽克隆她的本地仓库把她的笔记本电脑为她回家的火车,她创造了第三个主分支。同样的效应发生在GitHub的分叉 - 每个分叉库都有自己的额外组支路。

当我们遇到不同的版本控制系统时,这种术语上的混乱会变得更糟,因为它们都有自己的分支的定义。Mercurial中的分支与git中的分支非常不同,git更接近Mercurial的书签。Mercurial也可以用未命名的头进行分支,Mercurial的人通常通过克隆存储库进行分支。

所有这些术语的混乱导致一些人避免使用这个术语。这里更通用的术语是代码行。我定义了码线作为代码基的特定版本序列。它可以以一个标记结束,也可以是一个分支,或者在git的reflog中丢失。您会注意到我对分支和代码线的定义之间存在极大的相似性。代码线在很多方面是更有用的术语,我确实使用它,但它在实践中并没有广泛使用。因此,对于本文,除非是在git(或其他工具)术语的特定上下文中,否则我将交替使用分支和代码线。

这个定义的一个结果是,无论您使用的是什么版本控制系统,每个开发人员只要进行本地更改,就在自己的机器上的工作副本上至少有一个个人代码行。如果我克隆了一个项目的git repo、签出master并更新了一些文件,即使在提交任何东西之前,这也是一个新的代码行。类似地,如果我对suberversion存储库的主干创建自己的工作副本,那么该工作副本就是它自己的代码行,即使不涉及subversion分支。

何时使用

一个老笑话说,如果你从一座高楼上摔下来,摔下来不会伤害你,但落地会。所以对于源代码:分支很容易,合并比较困难。

源代码控制系统是记录在每一个变化都提交合并做出更容易的过程,但他们不使琐碎。如果斯嘉丽和紫都改变一个变量的名称,但不同的名称,然后有一个冲突的源头管理系统无法无需人工干预解决。为了使这种比较尴尬文本冲突至少东西源代码控制系统能发现并提醒人们去看一看。但是经常会出现冲突没有问题的文本合并在哪里,但系统仍然无法正常工作。想象一下,斯嘉丽改变函数的名称,以及紫罗兰添加一些代码,以她的分支,称在其旧名称此功能。这就是我所说的语义冲突。当这些类型的冲突发生的系统可能无法建立,也可以建立,但是在运行时出现故障。

问题是熟悉的人谁曾与并行或者分布式计算工作。我们与开发商在平行进行更新一些共享的状态(代码库)。我们需要通过串行化将更改一些共识更新以某种方式结合这些。我们的任务是由以下事实得到一个系统执行和运行正确变得更复杂意味着对于共享状态非常复杂的有效性标准。有没有建立一个确定性的算法来找到共识的方法。人类需要找到共识,这种共识可能涉及混合不同的更新选择部分。通常,共识只能与原来的更新来达到解决冲突。

我以“如果没有分支会怎样”开始。每个人都在编辑实时代码,不成熟的更改会阻塞系统,人们会互相践踏。所以我们给人们一种时间冻结的错觉,认为他们是唯一改变系统的人,这些改变可以等到他们完全烤熟了再冒系统的风险。但这是一种错觉,最终它的代价会到来。谁支付?什么时候?多少钱?这就是这些模式所讨论的:支付费用的替代方案。

- 肯特·贝克

因此,在本文的其余部分,我列出了各种模式,支持愉快的隔离和风通过你的头发,你下跌,但尽量减少不可避免的后果,与硬地面接触。

干线

一个单一的,共享的,分支充当产品的当前状态

主线是一个特殊的代码行,我们认为它是团队代码的当前状态。每当我想开始一项新的工作时,我都会将代码从主线拉到本地存储库中开始工作。每当我想与团队其他成员分享我的工作时,我会用我的工作更新主线,最好使用主线集成我稍后将讨论的模式。

不同的团队为这个特殊的分支使用不同的名称,这通常受到所使用的版本控制系统惯例的鼓励。git用户通常称之为“master”,subversion用户通常称之为“trunk”。

我必须在这里强调主线是单一,共享代码线。当人们在git中谈论“master”时,他们的意思可能不同,因为每个存储库克隆都有自己的本地master。通常这样的团队会有一个原始存储库,它的主人是主线。从头开始一项新工作意味着克隆源代码存储库。如果我已经有了一个克隆,我先把master拉到,这样它就和主线最新了。

当我在开发我的特性时,我有自己的个人开发分支,它可能是我的本地主控,或者我可以创建一个单独的本地分支。如果我在这方面工作一段时间,我可以通过每隔一段时间提取主线的更改并将它们合并到我的个人发展分支中,来跟上主线中的更改。

同样,如果我想创建一个发布产品的新版本,我可以与当前的主线开始。如果我需要修正错误,使发布的产品不够稳定,我可以使用释放分支

何时使用

我记得在21世纪初,我和一位客户的建筑工程师谈过,他的工作是组装团队正在开发的产品。他会给团队的每个成员发送一封电子邮件,他们会通过从他们的代码库发送各种准备好集成的文件来进行回复。然后,他将这些文件复制到他的集成树中,并尝试编译代码库。他通常需要几周时间来创建一个编译的构建,并为某种形式的测试做好准备。

相反,在一个主线,任何人都可以迅速从主线的尖端启动了最新打造的产品。此外,主线不只是使它更容易看到代码库的状态是什么,它是许多其他的模式,我会在短期内开拓奠定了基础。

干线的另一种选择是发布列车

健康科

在每次提交时,执行自动检查,通常是构建和运行测试,以确保分支上没有缺陷

以来干线拥有这种共享的、被批准的状态,将其保持在一个稳定的状态是很重要的。同样在21世纪初,我记得我和另一个组织的团队交谈过,这个组织以每天制作他们的产品而闻名。这在当时被认为是相当先进的做法,本组织为此受到赞扬。在这些文章中没有提到的是,这些日常构建并不总是成功的。事实上,找到几个月没有编译每日构建的团队并不罕见。

为了解决这个问题,我们可以努力保持一个分支的健康——这意味着它可以成功地构建,并且软件运行时几乎没有bug(如果有的话)。为了确保这一点,我发现我们写自测码。这种发展实践意味着,我们写的生产代码,我们还编写自动测试,一个综合套件,使我们可以相信,如果这些测试通过,则代码不包含任何错误。如果我们这样做,那么我们就可以保持一个分支健康运行构建与每一个承诺,这个版本包括运行这个测试套件。如果系统无法编译,或者测试失败,那么我们的首要任务是解决这些问题,我们做任何事情对分支之前。通常,这意味着我们“冻结”分支 - 没有提交允许它除了修复,使其恢复了健康。

为了提供足够的健康信心,在测试的程度上存在着紧张。许多更彻底的测试需要大量的时间来运行,从而延迟对提交是否正常的反馈。团队通过在部署管道。这些测试的第一阶段应该快速运行,一般不超过十分钟,但仍是相当全面。我指的是这样一套房的提交套件(尽管它通常被称为“单元测试”,因为提交套件通常是单元测试).

理想情况下,所有的测试都应该在每次提交时运行。但是,如果测试很慢,例如性能测试需要占用服务器几个小时,这是不实际的。现在,团队通常可以构建一个提交套件,该套件可以在每次提交时运行,并尽可能频繁地运行部署管道的后续阶段。

代码运行时没有错误,这不足以说明代码是好的。为了保持稳定的交货速度,我们需要保持代码的高的内部质量. 一种流行的方法是来自提交,尽管我们将会看到,还有其他的选择。

何时使用

每队应该有每个分支在其开发流程的卫生明确的标准。有在保持主线健康的巨大价值。如果主线是健康的,然后开发者可以通过只需拔当前主线开始新的工作,而不是在他们的工作方式得到的缺陷被挂住了。我们常常听到人们消磨时间,试图解决,或解决,在他们拉代码中的bug,才可以用新的工作开始。

一个健康的主线也可以平滑路径生产。一个新的生产候选人可从主线的头任何时候都可以建。最好的团队发现他们需要做一些工作来稳定这样的代码库,往往能够直接从主线释放到生产。

关键是有一个健康的主线是自测码一个几分钟后运行的提交套件。构建这种能力可能是一项重大的投资,但一旦我们能够在几分钟内确保我的承诺没有破坏任何东西,这将彻底改变我们的整个开发过程。我们可以更迅速、更自信地做出改变重构我们的代码,以保持它很容易使用,并极大地从所要求的功能减少循环时间代码运行在生产。

对于个人开发分支,这是明智的,让他们健康,因为这种方式它使DIFF调试. 但这种愿望与频繁提交检查点以检查当前状态是背道而驰的。如果我要尝试不同的路径,即使编译失败,我也可能创建一个检查点。我解决这种紧张关系的方法是,一旦我完成了眼前的工作,就把任何不健康的承诺都压制掉。这样,只有健康的承诺留在我的分支机构超过几个小时。

如果我保持我的个人分支健康,这也会使我更容易投入到主线上-我知道任何出现的错误主线集成纯粹是由于集成问题,而不是我的代码库中的错误。这将使查找和修复它们变得更快、更容易。

集成模式

分支是关于管理隔离和集成的相互作用。让每个人都一直在一个共享的代码基上工作是行不通的,因为如果你在输入变量名的过程中,我就无法编译这个程序。因此,至少在某种程度上,我们需要一个私有工作空间的概念,我可以在此工作一段时间。现代的源代码控制工具使分支和监视对这些分支的更改变得很容易。但是在某些时候我们需要积分。考虑分支策略实际上就是决定如何以及何时进行集成。

主线集成

开发人员通过从主线抽取、合并和(如果健康的话)回推主线来集成他们的工作

主线给出了团队软件当前状态的清晰定义。使用主线的最大好处之一是简化了集成。没有主线,这是一个复杂的任务,与团队中的每个人协调,我在上面描述。不过,有了主线,每个开发人员都可以自己进行集成。

我将通过一个例子来说明这是如何工作的。一个开发人员,我称之为斯嘉丽,通过将主线克隆到她自己的存储库中开始一些工作。在git中,这将使用clone(如果她还没有克隆),切换到master分支,并将master拉入她的repo。然后她可以在当地工作,向当地的主人作出承诺。

虽然她的工作,她的同事紫推一些变化到主线。由于她的工作在自己的代码行,斯嘉丽可以无视这些变化,而她的作品在她自己的任务。

在某种程度上,她达到了她想要融入的程度。第一部分是将主线的当前状态提取到她的本地主分支中,这将引入Violet的更改。当她在处理本地master时,提交将作为单独的代码行显示在origin/master上。

现在,她需要结合自己与紫色的变化。有些球队喜欢通过衍合合并,别人这样做。在一般人使用,每当他们谈论把树枝一起,他们是否真正使用混帐合并或调整基线操作单词“合并”。我会遵循使用,所以,除非我其实是在讨论合并和重订基之间的差异考虑“合并”,将是可与实现的逻辑任务。

关于是使用vanilla合并,使用还是避免快进合并,还是使用rebing,还有一个完整的讨论。这超出了本文的范围,尽管如果人们给我发送足够的Tripel Karmeliet,我可能会写一篇关于这个问题的文章。毕竟,交换条件都风靡一时这些天。

如果斯嘉丽是幸运的,在紫的代码合并将是一个干净的合并,如果不是她还会有一些矛盾来处理。这些可以是文本的冲突,其中大部分的源的控制系统可以自动处理。但是语义矛盾更难处理,而这正是自测码很方便。(由于冲突可能会产生大量的工作,并且总是会带来大量工作的风险,所以我用一块令人震惊的黄色标记它们。)

在这一点上,她已经成功地把主线拉进了她的代码线,但是-这一点既重要又常常被忽视-她还没有完成与主线的集成。为了完成整合,她必须将自己的变化推进主线。除非她这样做,否则团队中的其他人都将与她的变更隔离开来——基本上不整合。整合既是一种拉动,也是一种推动——只有思嘉推动了自己的工作与项目的其他部分整合。

很多球队这几天需要的代码审查步骤之前提交加入到主线 - 一种模式我称之为来自提交稍后再讨论。

偶尔也会有其他人在斯嘉丽完成她的推送之前就融入主线。在这种情况下,她必须再次拉并合并。通常这只是一个偶然的问题,不需要进一步的协调就可以解决。我曾经见过构建时间长的团队使用集成指挥棒,因此只有掌握指挥棒的开发人员才能进行集成。但近年来,随着构建时间的改善,我并没有听到太多这样的说法。

何时使用

正如它的名字所暗示的,我可以,如果我们还使用我们的产品主线只使用集成的主线。

使用主线集成的另一种方法是从主线中提取并将这些更改合并到个人开发分支中。这可能很有用——拉拽至少可以提醒思嘉注意其他人已经整合的变化,并发现她工作和主线之间的冲突。但在斯佳丽推动之前,维奥莱特将无法察觉她正在做的工作和斯佳丽的变化之间的任何冲突。

当人们使用“集成”这个词时,他们常常忽略了这一点。经常听到有人说,他们正在将主线集成到分支中,而实际上他们只是在拉动。我已经学会对此保持警惕,并进一步检查它们是否只是一个拉或一个适当的主线集成。两者的结果是非常不同的,所以不要混淆这两个术语。

另一种选择是,当斯佳丽正在做一些工作,还没有准备好与团队其他成员完全融合,但它与维奥莱特重叠,她想与她分享。如果那样的话,他们可以打开一个合作部门

功能分支

将一个特性的所有工作放在它自己的分支上,当特性完成时集成到主线中。

随着功能的分支,开发商开一家分店,当他们开始对要素的工作,继续就这一功能工作,直到他们完成,然后与主线进行整合。

例如,让我们来看看思嘉。她会拿起功能添加的地方销售税征收到他们的网站。她开始与产品的当前稳定版本,她会拉主线到她的本地仓库,然后创建一个新的分支开始在当前主线一角。她的作品的特点,只要需要,制作出一系列的提交到当地的分支机构。

她可能会将该分支推到项目回购中,以便其他人可以查看她的更改。

在她工作的时候,其他的任务都在主线上。所以她可能会不时地从主线上撤下来,这样她就可以判断是否有任何变化可能会影响她的功能。

注意,这不是我上面所描述的集成,因为她没有回到主线。在这一点上,只有她看到了自己的作品,其他人没有。

有些球队喜欢以确保所有的代码,无论集成与否,保存在共享存储库。在这种情况下,斯嘉丽将她推特性分支到共享存储库。这也将使得其他的团队成员,看看她的工作,即使它没有集成到其他人的工作呢。

当她完成特写后,她会表演主线集成纳入该功能到产品中。

如果思嘉同时处理多个功能,她会为每个功能分别打开一个分支。

何时使用

功能分支是当今业界流行的模式。谈论何时使用它,我需要介绍其主要的选择 -持续集成. 但首先我需要谈谈积分频率的作用。

积分频率

我们多久进行一次集成对团队的运作有着非常强大的影响。来自开发运行状态报告表明精英开发团队比低绩效团队更容易整合——这一观察结果与我的经验以及我的许多行业同行的经验相吻合。我将通过两个由斯嘉丽和维奥莱特主演的集成频率的例子来说明这一点。

低频积分

我先从低频率开始。在这里,我们的两个英雄开始了一个插曲的工作克隆到他们的分支主线,然后做了一些当地的承诺,他们还不想推动。

当他们工作的时候,其他人把承诺放在主线上。(我不能很快想到另一个人的名字那是一种颜色——也许是格雷厄姆?)

这个团队的工作方式是保持一个健康的分支,并在每次提交后退出主线。由于主线没有变化,斯佳丽在前两次投球时没有任何动作,但现在需要拉M1。

我已经用黄色的盒子标记了合并。这一个将提交的S1..3与M1合并。很快,维奥莱特也需要做同样的事情。

在这一点上,两个开发人员都是最新的主线,但他们没有集成,因为他们都是孤立的彼此。斯佳丽不知道维奥莱特在1.3版中做了什么改变。

斯嘉丽使一对夫妇更多本地提交,然后是准备做主线整合。这是一个简单的推给她,因为她拉着M1更早。

然而,Violet有一个更复杂的练习。当她进行主线集成时,她现在必须对S1进行集成。5与V1 . . 6。

我根据涉及的提交数量科学地计算了合并的大小。但即使你忽略了我脸颊上舌状的隆起,你也会明白紫罗兰的融合是最困难的。

高频集成

在前面的例子中,我们的两个丰富多彩的开发人员在几个本地提交之后进行了集成。让我们看看如果他们在每次本地提交之后进行主线集成会发生什么。

第一个变化是显而易见的与紫罗兰的第一次承诺,因为她整合了立即。由于主线没有改变,这只是一个简单的推动。

斯嘉丽的第一次提交也有主线整合,但因为维奥莱特是第一个,她需要做一个合并。但是因为她只合并了V1和S1,合并的规模很小。

斯嘉丽的下一个整合是一个简单的推动,这意味着Violet的下一个承诺还需要与斯嘉丽最近的两个承诺合并。不过,这仍然是一个很小的合并,一个是维奥莱特的,两个是斯佳丽的。

当外部推动主线出现,它就会在斯嘉丽和紫罗兰的整合通常的节奏回升。

虽然它与以前的情况相似,但集成度较小。思嘉这次只需要把S3和M1集成,因为S1和S2已经在主线上了。这意味着在推M1之前,Grayham必须整合已经在主线上的内容(S1..2,V1..2)。

开发人员继续他们剩余的工作,与每个提交集成。

比较积分频率

让我们再来看看这两张图片

低频

高频

这里有两个非常明显的区别。首先,顾名思义,高频积分有更多的积分——是这个玩具例子的两倍。但更重要的是,这些积分比低频情况下的积分要小得多。更小的集成意味着更少的工作,因为更少的代码更改可能会导致冲突。但比减少工作更重要的是,风险也更小。大合并的问题与其说是与之相关的工作,不如说是工作的不确定性。大多数时候,即使是大型合并也会顺利进行,但偶尔也会非常顺利,非常,糟透了。偶尔的疼痛比经常的疼痛更严重。如果我将每次集成额外花费10分钟与花费6小时修复一个集成的50分之一的可能性进行比较,我更喜欢哪一个?如果我只看努力,那么1/50更好,因为它是6小时,而不是8小时20分钟。但这种不确定性使每50人中就有1人的情况更糟,这种不确定性导致了对一体化的恐惧。

让我们来看看从另一个角度来看,这些频率之间的差异。如果斯嘉丽和紫开发他们的第一个提交冲突会发生什么?他们什么时候发现已经发生的冲突?在低频率的情况下,他们并没有发现它,直到紫的最终合并,因为这是第一次S1和V1放在一起。但是在高频情况下,他们在斯嘉丽的第一个合并检测。

低频

高频

频繁的集成增加了合并的频率,但降低了合并的复杂性和风险。频繁的集成还可以更快地向团队发出冲突警报。当然,这两件事是有联系的。糟糕的合并通常是团队工作中潜在冲突的结果,只有在集成发生时才会出现。

也许维奥莱特在看一个账单计算,并看到它包括评估税,作者假设了一个特殊的税收机制。她的功能需要对税收进行不同的处理,所以直接的方法是将税收从账单计算中去掉,以后作为一个单独的功能来执行。计费计算只在几个地方调用,所以很容易使用 移动报表呼叫者- 其结果,使该计划的未来发展更有意义。斯嘉丽,但是,不知道紫是这样做的,写了她的特点假设计费功能了税收照顾。

自测码是我们的救命恩人。如果我们有一个强大的测试套件,使用它作为健康分支的一部分将会发现冲突,这样bug进入生产环境的机会就会少得多。但是,即使有一个强大的测试套件作为主线的看门人,大型集成也会使工作变得更加困难。我们需要集成的代码越多,就越难找到缺陷。我们也有更大的机会出现多个干扰性的bug,这些bug非常难以理解。我们不仅可以用较小的提交查看更少的内容,我们还可以使用DIFF调试有助于缩小导致问题的变化范围。

很多人没有意识到的是,源代码管理系统是一种通信工具。这让斯佳丽可以看到队里其他人在做什么。通过频繁的集成,她不仅能在出现冲突时立即发出警报,还能更清楚地了解每个人都在做什么,以及代码库是如何发展的。我们不像是独立的个体,更像是一个团队在一起工作。

增加集成的频率是减少特性大小的一个重要原因,但是还有其他优点。功能越小,构建的速度就越快,投入生产的速度就越快,开始交付价值的速度就越快。此外,更小的特性减少了反馈时间,允许团队在更多地了解客户时做出更好的特性决策。

持续集成

开发人员只要有一个健康的承诺就可以进行主线集成,通常不到一天的工作

一旦一个团队体验到高频整合的效率更高、压力更小,那么自然要问的问题是“我们多久能去一次?”特性分支意味着变更集大小的下限-不能小于内聚特性。

持续集成为集成应用了一个不同的触发器-只要在功能上取得了巨大的进展,并且分支仍然健康,就可以进行集成。没有人期望这个特性是完整的,只是代码库有很多值得修改的地方。经验法则是“每个人每天都致力于主线”或者更准确地说:在本地存储库中,不集成的工作不应该超过一天. 在实践中,大多数持续整合的实践者一天整合多次,乐于整合一小时或更少的工作量。

使用持续集成的开发人员需要习惯使用部分构建的特性达到频繁集成点的想法。他们需要考虑如何在运行中的系统中不公开部分构建的功能。通常这很简单:如果我正在实现一个依赖优惠券代码的折扣算法,而该代码还不在有效列表中,那么即使我的代码是生产代码,也不会被调用。类似地,如果我添加了一个功能,询问保险索赔人他们是否吸烟,我可以构建和测试代码背后的逻辑,并通过将提出问题的UI保留到构建该功能的最后一天来确保它不会在生产中使用。通过连接一个Keystone接口最后往往是一种有效的技术。

如果没有办法轻松地隐藏部分功能,我们可以使用功能标志. 除了隐藏部分构建的功能外,这些标志还允许有选择地向用户子集显示该功能—通常对于缓慢推出新功能很方便。

集成部分构建的特性特别关注那些担心主线中有错误代码的人。因此,那些使用持续集成的人也需要自测码,这样就有信心在主线中部分构建功能不会增加出现错误的机会。使用这种方法,开发人员在编写部分构建的特性代码时为其编写测试,并将特性代码和测试一起提交到主线中(可能使用测试驱动开发).

就本地回购而言,大多数使用持续集成的人都不必为单独的本地分支机构操心。通常很容易提交给本地主机,完成后执行主线集成。不过,如果开发人员愿意,可以打开一个功能分支并在那里完成工作,以频繁的间隔将其集成回本地主控和主线中。特性分支和连续集成的区别不在于是否有特性分支,而在于开发人员何时与主线集成。

何时使用

持续集成是功能分支. 两者之间的取舍已经足够复杂,值得在本文中单独讨论,现在是解决这个问题的时候了。

比较特征分支和连续集成

功能分支似乎是最常见的,此刻在行业分支策略,但谁认为持续集成通常是一个优越的做法从业者的演唱组合。是持续集成提供了关键的优势是,它支持更高,往往高得多,整合频率。

集成频率差取决于球队是多么的小能够让其功能。如果一个团队的功能都可以在不到一天的时间来完成,那么他们可以执行两个功能分支和持续集成。但大多数球队有更长的功能长度比这 - 和更大的长篇,更大的两种模式之间的区别。

正如我已经指出的,更高频率的整合导致更少的参与整合和更少的整合恐惧。这通常是一件很难沟通的事情。如果你生活在一个每隔几周或几个月就进行一次整合的世界中,那么整合可能是一项非常令人担忧的活动。很难相信这是一天可以做很多次的事情。但整合是其中之一频率降低难度. 这是一个反直觉的概念——“如果受伤了,就多做一次”。但是,整合越小,它们就越不可能变成痛苦与绝望的史诗般融合。有了特性分支,这就支持更小的特性:天而不是周(月是正确的)。

持续集成允许团队获得高频集成的好处,同时将特征长度与集成频率分离。如果一个团队喜欢一到两周的特性,持续集成允许他们在获得最高集成频率的所有好处的同时做到这一点。合并规模较小,需要处理的工作较少。更重要的是,正如我上面所解释,在做合并更频繁地减少了讨厌的合并,这既削减了不好的结果,这带来,并减少合并的总体恐惧的风险。如果冲突中的代码,高频集成发现这些出现迅速,它们会导致那些讨厌的集成问题之前。这些好处是足够强大的,有具有的功能,仅需要几天仍然做持续集成的团队。

持续集成的明确的缺点是,它缺乏气候整合主线关闭。不只是这是一个失去的庆祝活动,这是一个风险,如果一支球队不擅长保持健康的分公司。保持一个共同的特征所有的提交也能够做出是否包括在即将发布的一个特点后期决定。虽然功能标志允许功能,以开启或关闭从用户的角度来切换,该特征的代码仍然是在产品中。这个担心是夸大经常毕竟代码不重东西,但它确实意味着谁想做持续集成团队必须建立一个强大的测试方案,使主线即使有许多集成每天保持健康,他们可以放心。有些团队发现这个技能很难想象,但也有人觉得它是两种可能,并释放。这个前提是否意味着功能分支是球队不强制健康科,并要求发布分支发布之前稳定代码更好。

虽然合并的大小和不确定性是特性分支最明显的问题,但它最大的问题可能是它可以阻止重构。重构是最有效的,当它有规律地进行并且几乎没有摩擦的时候。重构会引入冲突,如果这些冲突没有被快速发现和解决,合并就会变得很麻烦。因此,重构在高集成频率下最有效,因此它作为188足球比分直播极限规划其中也有持续整合作为最初的做法之一。特性分支还阻止开发人员进行不被视为正在构建的特性一部分的更改,这会削弱重构稳定地改进代码基础的能力。188足球比分直播

我们发现,面前分枝或分叉具有非常短的寿命(不到一天的时间)被合并到主干,将共计不到三个活跃的分支,是连续输送的重要方面,并且都有助于更高的性能。所以做了每天的基础上合并代码放到后备箱或主。

- DevOps的报告2016年国

当我遇到的软件开发实践的科学研究,我通常是由于严重的问题,他们的方法持怀疑态度。一个例外是开发运行状态报告,该公司开发度量的软件交付性能,这是他们对组织绩效更宽的措施,相关这又关联到业务指标如投资和盈利回报。在2016年,他们第一次评估,持续集成,并发现它更高的软件开发的性能作出了贡献,一直重复,因为每次调查的发现。

使用持续集成并不能消除保持特性小的其他优点。频繁地发布小的特性提供了一个快速的反馈周期,可以为改进产品创造奇迹。许多使用持续集成的团队还努力构建产品的薄片,并尽可能频繁地发布新功能。

功能分支

  • 功能中的所有代码都可以作为一个单元进行质量评估
  • 功能代码只添加到产品时,功能非常齐全
  • 不太频繁的合并

持续集成

  • 支持比长篇更高频率的集成
  • 减少查找冲突的时间
  • 较小的合并
  • 鼓励重构188足球比分直播
  • 需要致力于健康的分支(因此需要自我测试代码)
  • 有助于提高软件交付性能的科学证据

特性分支和开源

很多人归咎于功能分支到GitHub上的它起源于开源开发的普及和拉请求模式。鉴于此,有必要先理解之间的开源工作,很多商业软件开发中存在的非常不同的上下文。开源项目在许多不同的方式是结构化的,但一个共同的结构是,一个人或一个小团体,充当维护者承担大部分编程的。维护者可与一大群程序员谁是贡献者。维护者通常不知道贡献者,因此没有提供的代码的质量意识。维护者也有关于贡献者多少时间真正投入的单独工作,更不用说他们在做事情的效果如何少确定性。

在此背景下,功能分支使得一大堆的道理。如果有人要添加一个功能,或大或小,我不知道什么时候(如果)它要完成,那么它是有道理的,我要等到它整合之前完成。这也是更重要的是能够检查代码,以确保它通过什么质量吧我有我的代码库。

但是,很多商业软件团队有一个非常不同的工作环境。还有的人,所有这些都投入大量,通常专职,对软件的全职团队。该项目的领导人知道这些人好(比当他们刚开始等),并可以有代码质量和交付能力的可靠预期。因为他们支付的员工,领导者也有关于时间投产项目和这样的事情编码标准和组习惯更大的控制权。

鉴于这种截然不同的背景,应该清楚的是,这种商业团队的分支策略不必与在开源世界中运行的策略相同。持续集成对于偶尔参与开源工作的贡献者来说几乎是不可能的,但对于商业工作来说却是一个现实的选择。团队不应该假设在开源环境中工作的内容对于他们的不同上下文是自动正确的。

来自提交

每一个承诺主线是同行评审之前提交被接受的。

长期以来,代码评审一直被鼓励作为一种提高代码质量、改进模块性、可读性和消除缺陷的方法。尽管如此,商业组织经常发现很难融入软件开发工作流。然而,开源世界广泛采用了这样一种想法,即在接受对项目的贡献进入项目主线之前,应对其进行审查,近年来这种方法在开发组织中广泛传播,特别是在硅谷。这样的工作流特别适合拉式请求的github机制。

像这样的工作流程开始时,斯嘉丽完成工作的一大块,她希望整合。像她一样主线集成(假设她的团队实践了这一点)一旦她有了一个成功的构建,但在推进主线之前,她会将提交提交给审查人员。团队的其他一些成员,比如Violet,然后对提交进行代码检查。如果她在承诺上有问题,她会做出一些评论,然后来来回回,直到斯嘉丽和紫罗兰都满意为止。只有当它们完成时,提交才会放在主线上。

审查提交在开源中越来越受欢迎,在开源中,它们非常适合承诺维护者和偶尔贡献者的组织模型。它们允许维护者密切关注任何贡献。它们也与功能分支,因为一个完整的功能标记清晰的点做代码审查是这样的。如果你不能确定一个贡献者是要完成一个功能,为什么审查其部分工作?最好等到该功能非常齐全。这种做法也是在更大的互联网公司广泛流传,谷歌和Facebook都建立特殊的工具,以帮助使这项工作顺利进行。

制定及时提交评论纪律是非常重要的。如果开发人员完成一些工作,去到别的东西了两天,那么这项工作不再是他们心目中的顶部时的审查意见回来。这是令人沮丧的具有完整功能,但它是一个部分完成的功能,它可能很难取得进一步的进展,直到审查确认更糟。原则上,这是可以做到的持续集成经过审查的提交,实际上在实践中也是可能的-Google遵循这种方法。但是,虽然这是可能的,这是很难的,比较少见。来自提交和功能分支是比较常见的组合。

何时使用

虽然来自承诺已成为在过去十年中流行的做法,也有缺点和替代。即使做得很好,来自犯总是引入一些延迟到一体化进程,鼓励降低整合频率。结对编程提供了一个连续的代码评审过程,与等待代码评审相比,反馈周期更快。(就像持续集成和重构一样,它是188足球比分直播极限规划).

许多使用审查提交的团队做得不够快。他们所能提供的有价值的反馈来得太晚了,已经没有用处了。在这一点上,有一个尴尬的选择,要么大量的返工,要么接受一些可能工作,但破坏代码库的质量。

代码评审并不局限于在代码到达主线之前。许多技术领导者发现,在提交代码后复查代码是很有用的,当他们发现问题时,可以及时与开发人员联系。重构文化在这里是很有价值的,做得好这就建立了一个社区,团队中的每个人都定期检查代码库并修复他们看到的问题。188足球比分直播

被审查承诺的权衡主要取决于团队的社会结构。正如我已经提到的,开源项目通常有一些可信的维护者和许多不可信的贡献者。商业团队通常都是全职的,但可能有类似的结构。项目负责人(像维护人员一样)信任一小群(可能是单个的)维护人员,并对团队其他成员提供的代码保持警惕。团队成员可以同时被分配到多个项目,使他们更像开源贡献者。如果存在这样的社会结构,那么审查提交和特性分支就非常有意义。但是,具有较高信任度的团队通常会发现其他机制在不增加集成过程摩擦的情况下保持代码质量高。

因此,虽然审查提交可以是一个有价值的实践,但它绝不是通向健康代码库的必要途径,特别是如果您希望发展一个平衡的团队,而不是过度依赖其最初的领导者。

积分摩擦

审查提交的一个问题是,它常常使集成变得更加麻烦。这是一个例子集成的摩擦- 活动,使整合需要一段时间或者是精力去做。更集成小说有,更多的开发者倾向于降低集成的频率。试想一下,有些(功能失调)的组织,坚持所有提交到主线需要一种形式,采取半一小时来填写。这种制度不利于人们经常集成。无论你的态度,功能分支和持续集成,它是有价值的检查任何增加这种摩擦。除非明确增加价值,任何这样的摩擦应该被删除。

手工工艺是摩擦的共源的,特别是如果它涉及到与独立的组织协调。通常可以通过使用自动化流程,提高显影剂的教育(除去的需要),并推压步骤,以一个的后面的步骤可以减少这种摩擦部署管道生产中的质量保证。在持续集成和持续交付中,您可以找到更多消除这种材料摩擦的方法。这种摩擦在生产过程中也会出现,遇到同样的困难和处理方法。

让人们不愿意考虑持续集成的一个原因是,如果他们只在具有高度集成摩擦的环境中工作过。如果做一个积分需要一个小时,那么一天做几次显然是荒谬的。加入一个集成不是什么大事的团队,某人可以在几分钟内匆匆离开,感觉就像进入了一个不同的世界。我怀疑关于特性分支和持续集成的优点的争论是混乱的,因为人们没有经历过这两个世界,因此不能完全理解这两个观点。

文化因素影响整合摩擦 - 尤其是团队成员之间的信任。如果我是球队的领袖,我不相信我的同事们做一个体面的工作,那么我可能要防止损坏的代码库的提交。当然,这是驱动来自犯之一。但是,如果我在一个团队里,我相信我的同事的判断,我可能会更舒服后提交审核,或完全切割出来的审查,并依靠社区重构清理任何问题。188足球比分直播我在这样的环境增益消除摩擦是预提交评论引进,从而鼓励了更高的集成频率。通常,团队的信任是在要素分支机构和持续集成参数的最重要因素。

模块化的重要性

大多数关心软件架构的人都强调模块化对于一个性能良好的系统的重要性。如果我面对的是对一个模块性差的系统做一个小小的改动,我必须理解几乎所有的改动,因为即使是一个小小的改动也会波及到代码库的许多部分。但是,有了良好的模块性,我只需要理解一两个模块中的代码,再多了解几个模块的接口,就可以忽略其他模块。这种减少理解所需工作的能力是为什么随着系统的增长,在模块化上投入这么多精力是值得的。

模块化也会影响集成。如果一个系统有很好的模块,那么大多数时候,Scarlett和Violet将在代码库中分离良好的部分工作,并且它们的更改不会导致冲突。良好的模块化也增强了诸如Keystone接口分支的抽象避免针对分支机构提供隔离的需要。通常,球队被迫使用源分支,因为缺乏模块化饿死的其他选择他们。

特性分支是一个穷人的模块化架构,它没有构建能够在运行时/部署时方便地交换特性的系统,而是将自己耦合到通过手动合并提供此机制的源代码管理。

--丹·博达

支持是双向的。尽管许多尝试,但它仍然很难建立一个良好的模块化架构,我们开始编程之前。为了实现模块化,我们需要因为它的增长不断地看我们的制度和更加模块化的方向倾向于它。188足球比分直播重构的关键是实现这一目标,并重构需要高频率的整合。模块化和快速整合从而相互支持,一个健康的代码库。

也就是说,模块化虽然很难实现,但值得努力。这项工作包括良好的开发实践、学习设计模式,以及从使用代码库的经验中学习。乱七八糟的合并不应该仅仅以一种可以理解的、想要忘记它们的愿望来关闭——而是问问合并为什么乱七八糟。这些答案通常是一个重要的线索,可以帮助我们改进模块性,改善代码库的健康状况,bet188足球从而提高团队的生产力。

关于整合模式的个人思考

作为一个作家,我的目的不是说服你走一条特定的道路,而是告诉你应该考虑的因素,比如决定走哪条路。尽管如此,我还是要在这里补充我的观点,我更喜欢前面提到的模式。

总的来说,我更喜欢在一个使用持续集成. 我认识到环境是关键,在很多情况下,持续整合不是最好的选择,但我的反应是努力改变环境。我之所以有这样的偏好,是因为我希望在这样一个环境中,每个人都可以轻松地对代码库进行重构,改进其模块性,保持其健康—所有这些都使我们能够快速响应不断变化的业务需求。188足球比分直播

这些天来,我更多的是作家不是开发商的,但我还是选择在工作熊子川,一个公司,是充满了谁赞成这种工作方式的人。这是因为我相信这极限规划风格是我们开发软件最有效的方法之一,我想观察团队进一步开发这种方法,以提高我们专业的效率。

从主线到产能的释放路径

主线是一个活跃的分支,与新的和修改后的代码规则的液滴。保持它的健康是很重要的,这样,当人们开始新的工作,他们也开始掀起了稳定的基础。如果它足够健康,你也可以直接从主线版本的代码投入生产。

保持主线处于始终释放的状态的这种理念是的中心原则连续交货. 要做到这一点,必须有决心和技能来保持主线作为健康科,一般用部署流水线支持所需的高强度测试。

以这种方式工作的团队通常可以通过在每个发布的版本上使用标记来跟踪他们的发布。但不使用连续交付的团队需要另一种方法。

释放分支

一个只接受提交的分支,接受提交是为了稳定一个准备发布的产品版本。

典型的发布分支将从当前主线复制,但不允许向其添加任何新功能。主要开发团队继续在主线中添加这样的特性,这些特性将在将来的版本中得到应用。致力于发布的开发人员只关注于消除阻止发布准备就绪的任何缺陷。对这些缺陷的任何修复都在发布分支上创建并合并到主线。一旦不再有故障需要处理,分支就可以进行生产发布了。

尽管在发布分支上修复的工作范围(希望如此)比新特性代码小,但是随着时间的推移,将它们合并回主线中变得越来越困难。分支不可避免地会产生分歧,因此随着越来越多的提交修改主线,将发布分支合并到主线中就变得越来越困难。

以这种方式将提交应用到发布分支的一个问题是,很容易忽略将它们复制到主线上,尤其是在由于分歧而变得更加困难的情况下。由此产生的回归是非常令人尴尬的。因此有些人有利于建立对主线的提交,只有一次他们要在那里工作樱桃接他们到发布分支。

一个摘樱桃当提交被复制从一个分支到另一个,但分支机构不合并。也就是说,只有一次提交被复制,而不是因为分支点以前提交。在这个例子中,如果我是F1合并到发布分支,那么这将包括M4和M5。但樱桃采摘只需要F1。樱桃挑选可能不干净的应用到发布分支,因为它可能会依赖于M4和M5所作的更改。

在mainline上编写发行版修复程序的缺点是,许多团队发现很难这样做,而且在mainline上以一种方式修复它会令人沮丧,并且在发行版发生之前必须重新处理发行版分支。当有时间压力来释放压力时尤其如此。

一次只生产一个版本的团队将只需要一个发布分支,但是一些产品在生产中会有很多版本。客户工具包上运行的软件只有在客户希望升级时才会升级。许多客户不愿意升级,除非他们有令人信服的新功能,因为升级失败会让他们吃苦头。然而,这样的客户仍然希望修复bug,特别是当它们涉及到安全问题时。在这种情况下,开发团队会为每个仍在使用的版本打开版本分支,并根据需要对它们应用补丁。

随着开发的进行,对旧版本应用修复程序变得越来越困难,但这通常是业务成本。只有鼓励客户频繁升级到最新版本,才能缓解这种压力。保持产品稳定是至关重要的,一旦烧毁了客户将不愿做不必要的升级再次。

(其他方面,我已经听到了发布分支包括:“释放制剂分会”,“稳定分支”,“候选人店”,“硬化分支”,而是“释放分支”似乎是最常见的。)

何时使用

当一个团队无法使其主线保持健康状态时,发布分支是一个有价值的工具。它允许团队的一部分专注于必要的bug修复,这些修复是为生产做好准备所必需的。测试员可以从这个分支的顶端提取最稳定的最近的候选人。每个人都能看到为稳定产品所做的工作。

尽管发布分支的价值,最最好的球队不要使用这个模式来单生产的产品,因为他们并不需要。如果主线保持足够健康,那么任何承诺主线可以直接释放。在这种情况下释放应被标记与公开可见的版本,版本号。

你可能已经注意到,我坚持笨拙的形容词“单生产”到前面的段落。这是因为当球队需要管理生产多个版本,这种模式就显得至关重要了。

当发布过程中出现重大摩擦时,发布分支可能也很方便,例如发布委员会必须批准所有生产发布。作为克里斯·奥尔德伍德所说的“在这种情况下发布分支更像一个隔离区,而公司的齿轮慢慢转动”。一般情况下,这样的摩擦应在释放过程以类似的方式去除尽可能,我们需要删除集成的摩擦. 然而,在某些情况下,如移动应用商店,这可能是不可能的。在许多情况下,标记在大多数情况下都是足够的,只有当源代码需要进行一些必要的更改时,分支才会打开。

释放分支也可以是环境科,但要考虑使用该模式的问题。也有一种长寿命释放分支,我将准备简短描述。

到期分行

其头部标记代码基成熟度级别的最新版本的分支。

团队常常想知道什么是最最新版本的源代码的是,这可能与具有成熟的不同程度的代码库是复杂的事实。QA工程师可能想看看产品的最新版本的升级,有人在调试生产故障想看看最新的量产版。

成熟分支提供了这样的跟踪的方式。有观点认为,一旦代码库的版本达到战备一定程度,它被复制到特定分支。

考虑一个用于生产的成熟度分支。当我们准备好一个产品版本时,我们打开一个版本分支来稳定产品。一旦准备好了,我们就把它复制到一个长时间运行的生产分支。我认为这是复制而不是合并,因为我们希望生产代码与在上游分支上测试的代码完全相同。

一个成熟的分支的诉求之一是,它清楚地显示出代码的每个版本的河段,在发布工作流程阶段。所以在上面的例子中,我们只希望在生产分公司,结合承诺M1-3和F1-2单个提交。有拉这一关SCM-暗中捣鬼的几个位,但在任何情况下,这种丢失的链接上主线细粒度的提交。这些提交应记录在提交信息,帮助人们跟踪他们下来以后英寸

成熟分行在开发流程的适当阶段之后通常命名。因此,像“生产分公司”,“分期店”,“QA分支”。偶尔我听到有人到生产成熟的分支为“释放分支”。

何时使用

源代码控制系统支持协作和跟踪代码库的历史。通过使用成熟度分支,人们可以通过显示发布工作流程中特定阶段的版本历史来获取一些重要的信息。

我可以通过查看相关部门的负责人找到最新的版本,比如当前运行的生产代码。如果出现了我确信之前不存在的错误,我可以查看分支上的先前版本,并查看生产中特定的代码基更改。

自动化可以扎入更改特定分支 - 例如自动化过程可以部署一个版本到生产每当有内容提交到生产分支制成。

使用成熟的分支另一种是应用标记方案。一旦一个版本是准备QA,它可以被标记为这样的 - 通常包括版本号的方式。因此,当构建762准备QA可以标记“QA-762”,当为生产做好准备它得到“PROD-762”。然后,我们可以通过搜索代码库进行匹配我们的标签方案,它标记获取的历史。自动化同样可以基于关闭标签分配。

因此,一个成熟的分支可以添加一些便利的工作流程,但许多组织发现标记工作得很好。所以,我看这是那些不具有很强的收益或成本模式之一。然而,通常使用的源代码管理系统,这样的跟踪需要的是一个团队的加工不良的征兆部署管道

变化:长寿命释放分支

我可以将其看作是发布分支模式的一个变体,它将其与发布候选的成熟度分支相结合。当我们想发布时,我们会将主线复制到这个发布分支中。与每一个发布分支一样,提交只在发布分支上进行,以提高稳定性。这些修复也合并到主线中。当发布发生时,我们会标记一个发布,当我们想做另一个发布时,我们可以再次复制主线。

提交可以作为在成熟的分支更典型的被复制,或合并。如果合并了,我们必须要小心,发布分支的头主线的头部完全匹配。要做到这一点的方法之一是恢复所有的已合并之前被应用到主线的修正。有些球队也合并,以确保每次提交后壁球提交代表一个完整的候选发布版。(谁发现这个棘手的人有一个很好的理由,更喜欢切割一个新的分支每个版本。)

这种方法只适用于产品,同时在生产单一的释放。

团队喜欢这种方法的一个原因是,它确保了发布分支的负责人总是指向下一个发布候选版本,而不是必须挖掘出最新发布分支的负责人。但是,至少在git中,我们通过拥有一个“release”分支名称来达到同样的效果,当团队删除一个新的发布分支时,这个“release”分支名称会进行硬重置,在旧的发布分支上留下一个标记。

环境科

配置产品通过应用源代码提交一个新的环境中运行。

软件通常需要在不同的环境中,如开发者的工作站,一个生产服务器,也许不同的测试和试运行环境中运行。通常在这些不同的环境中运行需要一些配置的变化,如邮件系统,用来访问数据库的URL,位置和网址为关键资源。

环境分支的分支,包含适用于源代码来重新配置产品运行在不同的环境下的提交。我们可能会对主线版本2.4的运行,现在希望我们的临时服务器上运行它。我们通过削减一个新的分支开始在2.4版本中做到这一点,应用适当的环境的变化,重建的产品,并将其部署到临时环境。

这些变化通常是用手涂抹,但如果负责人是舒服的git他们可以挑樱桃从早期分支的变化。

环境分支模式通常与到期分行. 长寿命的QA成熟度分支可以包括QA环境的配置调整。合并到这个分支中,然后将获取配置更改。类似地,长寿命的发布分支可能包含这些配置更改。

何时使用

环境分支是一种吸引人的方法。它允许我们以任何方式调整应用程序,以便为新环境做好准备。我们可以将这些更改保留在diff中,以便在将来的产品版本中进行挑选。然而,它是反模式-当你开始的时候看起来很吸引人,但是很快就会导致一个充满痛苦、龙和冠状病毒的世界。

环境中任何变化的潜在危险是,当我们将应用程序从一个环境移动到另一个环境时,它的行为是否会发生变化。如果我们不能在生产环境中运行一个版本并在开发人员的工作站上调试它,那么就很难解决问题。我们可以引入只在特定环境中出现的错误,最危险的生产环境。由于这种危险,我们希望尽可能确保在生产中运行的代码与在其他地方运行的代码相同。

环保分支机构的问题是非常灵活,使他们如此吸引人。因为我们可以把这些差异改变代码的任何方面,我们可以很容易地引入,导致不同的行为的配置和补丁来与他们的错误。

其结果是,许多组织明智地坚持一个铁律,一旦一个可执行文件被编译,它必须是相同的可执行文件,在任何环境运行。如果需要更改配置,必须通过机制而分离,例如明确的配置文件或环境变量。这样,他们可以最小化到执行过程中不会改变的常量简单的设置,少留空间臭虫滋​​生。

通过直接执行源代码(如JavaScript、Python、Ruby)的软件,可执行文件和配置之间的简单界限很容易变得非常模糊,但原理是一样的。保持任何环境变化最小,不要使用源分支来应用它们。一般的经验法则是,您应该能够检出产品的任何版本并在任何环境中运行它,因此任何纯粹由于不同部署环境而更改的内容都不应该在源代码控制中。在源代码控制中存储默认参数的组合有一个参数,但是应用程序的每个版本都应该能够根据需要在这些不同的配置之间进行切换,这取决于环境变量等动态因素。

环境分支是使用源分支作为穷人的模块化架构。如果一个应用程序需要在不同的环境中运行,不同的环境之间的能力,开关需要它的设计的第一级的一部分。bet188足球环境分支可以作为缺乏的设计应用的杰里 - 操纵机制是有用的,但后来应该是一个可持续的替代去除高优先级。bet188足球

热修复分支

以捕捉工作的一个分支,以解决迫切的生产缺陷。

如果一个严重的错误出现在生产,那么它需要尽快解决。关于这个bug的工作将是一个更高的优先级比任何其他的工作团队在做,并没有其他的工作应该做任何工作放慢对这个修补程序。

在源控制做修复工作的需要,让球队能够正常记录和它合作。他们可以通过打开最新发行版本的一个分支,并申请在该分支的修补程序的任何变化做到这一点。

一旦修复程序应用到生产中,并且每个人都有机会有一个像样的夜晚睡眠,那么可以将修复程序应用到主线,以确保不会与下一个版本出现倒退。如果有一个发布分支为下一个版本打开,则修补程序也需要继续执行该操作。如果两个版本之间的时间很长,那么修补程序很可能是在更改的代码之上进行的,因此合并起来会更加困难。在这种情况下,暴露错误的良好测试确实很有帮助。

如果团队正在使用发布分支,则可以在发布分支上执行修补程序工作,并在完成后生成新的发布。从本质上讲,这将把旧的发布分支变成一个热修复分支。

与发布分支一样,可以在主线上进行热修复,并将其选择到发布分支。但这并不常见,因为热修复通常是在很强的时间压力下完成的。

如果一个团队持续交付,它可以直接在主线下发布修补程序。他们可能仍然使用一个热修复分支,但是他们将从最新的提交开始,而不是从最后发布的提交开始。

我将新版本标记为2.2.1,因为如果一个团队以这种方式工作,那么M4和M5可能不会公开新功能。如果他们这样做了,那么修补程序很可能只是折叠成2.3版本。当然,这说明了使用持续交付修补程序不需要回避正常的发布过程。如果一个团队有一个充分响应的发布过程,那么一个修补程序就可以像平常一样处理——这是持续交付思维的一个显著好处。

对于一个持续交付团队来说,一个特别的处理方法是在热修复完成之前不允许对主线进行任何提交。这符合这样一个信条:没有人比修理主线更重要的任务了,事实上,在主线上发现的任何缺陷都是正确的,即使那些还没有投入生产的缺陷也是如此。(所以我想这并不是什么特别的处理方式。)

何时使用

修补程序在相当大的压力的时间通常做的,当一支球队是压力最大,它是最有可能犯错误。在这些条件下,它甚至比平常使用的源代码控制和更为频繁比似乎是合理的承诺更有价值。保持一个分支这项工作让每个人都知道什么是正在做处理问题。唯一的例外是一个简单的修补程序,可以直接应用到主线。

这里更有趣的问题是决定什么是要修复的热bug,什么是可以留在正常开发工作流中的东西。一个团队发布的频率越高,它就越能将生产缺陷的修复留在正常的开发节奏中。在大多数情况下,决策将主要取决于bug的业务影响,以及它如何与团队的发布频率相适应。

发布列车

松开设定的时间间隔,就像火车上定期出发。当他们完成了他们的特点开发商选择哪个要赶火车。

使用一个版本系列的一个小组将设置的版本中,每两个星期,或每六个月如常规节奏。日期是当球队将削减发布分支的每个版本中,列车时刻表的比喻以下设置。人们决定他们想要一个功能,渔获物的火车,并针对他们的那列火车的工作,把他们提交到适当的分支,而火车装载。一旦列车的出发,该分支是释放分支并且只接受修复程序。

根据2月份的版本,一个使用每月列车的团队将在3月份开始一个分支。随着时间的推移,他们将增加新的功能。在一个固定的日期,也许是这个月的第三个星期三,火车离开-特点是冻结那个分支。他们为4月份的列车开了一个新的分站,并增加了新的功能。与此同时,一些开发商稳定了3月份的列车,准备好后投入生产。对三月的火车所做的任何修理都是由四月的火车精心挑选出来的。

释放列车通常用于功能分支. 当思嘉意识到什么时候才能把自己的容貌搞定时,她就会决定乘哪趟火车。如果她认为她能完成三月的释放,她将融入三月的火车,但如果不能,她将等待下一个,并融入那里。

有些车队在列车出发前几天使用软冻结(即硬冻结)。一旦发布序列处于软冻结状态,那么开发人员就不应该将工作推到该序列上,除非他们确信他们的特性是稳定的并准备好发布。任何显示软冻结后添加的错误的功能将被恢复(推下列车),而不是固定在列车上。

如今,当人们听到“释放火车”时,他们经常听到敏捷释放训练从安全的概念。外管局的敏捷发布培训是一个团队组织结构,指的是一个大型的团队的团队,共享一个共同的发布培训时间表。虽然它使用了发布序列模式,但它与我在这里描述的并不相同。

何时使用

释放序列模式的一个核心概念是释放过程的规律性。如果您提前知道发布火车应该在什么时候离开,那么您就可以计划为该火车完成您的特性。如果你不认为你能在3月的火车上完成你的专题,那么你知道你会赶上下一班火车。

当释放过程中有重大摩擦时,释放列车特别有用。一个外部测试小组,需要几周的时间来验证一个发布版本,或者在产品的新版本发布之前需要与发布委员会达成一致。如果是这样的话,明智的做法通常是消除释放摩擦,允许更频繁地释放。当然,在某些情况下,这几乎是不可能的,例如移动设备上的应用程序商店使用的验证过程。调整释放列车,以匹配这样的释放摩擦,然后可能使最好的情况。

发布培训机制有助于将每个人的注意力集中在应该在什么时候出现什么特性上,从而帮助预测特性将在什么时候完成。

这种方法的一个明显缺点是特点,在列车的时期年初完成将坐在火车上看书一边等待出发。如果这些功能很重要,这是意味着该产品未命中数周或数月的重要能力。

发布训练可以是改进团队发布过程的一个有价值的阶段。如果一个团队在稳定的释放上有困难,那么一路跳跃到连续的交付可能是一个太远的跳跃。选择一个合适的释放火车周期,一个艰难但似乎合理的,可以是一个很好的第一步。随着团队获得技能,他们可以增加列车的频率,最终随着能力的增长放弃列车进行连续交付

变化:装载未来列车

功能列车的基础例子有一个新的火车到达平台,同时与前车的出发去接功能。但是,另一种方法是在同一时间有一个以上的列车接受的特点。如果斯嘉丽并不认为她的功能将在三月火车来完成,她仍然可以把她的大多是全熟的功能四月列车,并推动进一步提交它离去之前完成它。

每隔一段时间,我们就把3月的火车开到4月的火车上。有些团队更喜欢只在3月的火车离开时才这样做,因此他们只有一个合并任务要做,但是我们这些知道小规模合并要简单得多的人更喜欢尽快完成每个3月的提交。

加载未来列车允许谁是在四月的开发者功能进行协作,而不会干扰在三月列车的工作。它的缺点是,如果在四月化妆乡亲变化与月的工作冲突,三月工人没有得到反馈,从而使未来的合并变得更复杂。

相比于普通版本关闭主线

一种的释放列车的主要好处是发布到生产的常规节奏。但有新的发展多个分支增加了复杂性。如果我们的目标是定期发布,我们可以用主线一样好实现这一目标。决定发布日程是什么,然后从什么是主线的切尖发布分支上日程。

如果有一个准备发布的主线有没有需要发布分支。通过定期发布这样,仍然有开发商通过,如果它只是在定期发布日期前不推到主线忍住几乎全熟的功能下一个版本的选项。同持续集成如果人们想要某个特性等待下一次预定的发布,他们总是可以延迟放置keystone或者关闭特性标志。

准备发布的主线

保持主线足够健康,使主线的头部始终可以直接投入生产

当我开始这个部分的时候,我评论说如果你干线a健康科,并且您将运行状况检查设置得足够高,然后您可以直接从主线下释放,随时用标记记录释放。

我花了很多时间来描述模式,这些模式是这个简单机制的替代品,所以我认为是时候强调这一点了,因为如果一个团队能够做到这一点,这是一个很好的选择。

仅仅因为对主线的每一个提交都是可发布的,并不意味着它应该被发布。这就是连续交货持续部署. 使用持续部署的团队确实会发布接受到主线的每一个更改,但是随着持续交付,而每一个更改都是可发布的,是否发布是一个业务决策。(因此,持续部署是持续交付的一个子集)我们可以将持续交付视为给我们在任何时候发布的选择,我们行使该选择的决定取决于更广泛的问题。

何时使用

再加上持续集成作为的一部分连续交货,准备发布的主线是高性能团队的一个共同特征。考虑到这一点,以及我对持续交付的众所周知的热情,您可能会期望我会说,与我在本节中描述的备选方案相比,准备发布的主线始终是最佳选择。

模式,但是,都是关于上下文。具有优异的一个上下文的模式可以是在另一个阱。准备发布的主线的效果受到制约集成频率的团队。如果团队使用功能分支而且通常每个月只集成一个新特性一次,那么团队可能会陷入困境,而坚持一个发布就绪的主线可能会成为他们改进的障碍。不好的地方是他们不能对不断变化的产品需求做出反应,因为从创意到生产的周期太长。它们也可能有复杂的合并和验证,因为每个特性都很大,导致许多冲突。这些可能会在集成时出现,或者当开发人员从主线拉入其功能分支时,它们会继续消耗开发人员的精力。这种拖拽阻碍了重构,从而降低了模块性,从而加剧了问题。188足球比分直播

要获得这个陷阱了,关键是要提高整合频率,但在许多情况下,这可能是难以实现的,同时保持一个准备发布的主线。在这种情况下,它往往不如放弃准备发布的主线,鼓励更频繁的整合,以及使用释放分支稳定生产主线。当然,随着时间的推移,我们希望通过改进部署管道来消除对发布分支的需求。

在高频集成的背景下,一个发布就绪的主线具有明显的简单优势。不必为我所描述的各种分支的复杂性而烦恼。即使是修补程序也可以应用到主线,然后应用到生产中,使它们不再特别到值得命名。

此外,保持主线发布准备就绪可以鼓励有价值的规程。它将生产准备放在开发人员的头脑中,确保问题不会以bug或流程问题的形式逐渐潜入系统,这些问题会减慢产品的周期。持续交付的完整原则——开发人员每天将多次集成到主线中而不破坏主线——对许多人来说似乎非常困难。然而,一旦实现并成为一种习惯,团队就会发现它显著地减少了压力,并且相对容易保持。这就是为什么它是输送区敏捷流畅模式。

其他分支模式

这篇文章的主要重点是在讨论围绕团队整合的模式和路径来生产。但也有一些其他的模式我想提一提。

实验科

收集在一起,上一个代码库的实验工作,那是预期不会直接合并到产品中。

实验分支是开发人员想要尝试一些想法的地方,但不要期望他们的更改简单地集成回主线中。我可能会发现一个新的图书馆,我认为这将是一个很好的替代我们正在使用的图书馆。为了帮助决定是否切换,我启动了一个分支,尝试编写或重写系统中使用它的相关部分。练习的目的不是为代码库贡献代码,而是学习新工具在我的特定上下文中的适用性。我可以自己做,也可以和一些同事一起做。

同样,我有一个新的功能来实现,并能看到一对夫妇的方式来处理它。我花每替代一两天帮我决定跟去哪一个。

这里的关键点是,期望的是,在实验科的代码将被抛弃,并没有合并到主线。这也不是绝对的 - 如果它恰好是我喜欢的结果和代码可以很容易地集成那么我不会忽略的机会 - 但我不期待这是事实。我可以放松了一些平时的生活习惯,少的测试,有些不管三七二十一代码的重复,而试图重构它的干净。我希望,如果我喜欢实验,我会从头开始把这个原理应用到生产代码的工作,用实验的分支,提醒和引导,但不使用任何提交的。

一旦我完成了一个实验分支的工作,在git中,我通常会添加一个标记并删除该分支。标记会保留代码线,以防以后我想重新检查它-我使用一种约定,比如用“exp”开始标记名,以使其性质清晰。

何时使用

无论何时我想尝试什么东西,实验分支都是有用的,但我不确定最终是否会使用它。这样我可以做任何我喜欢的事,无论多么滑稽,但我有信心我可以很容易地把它放在一边。

有时我会认为我在做常规工作,但要意识到我所做的其实是一个实验。如果发生这种情况,我可以打开一个新的实验分支,并将主工作分支重置为最后一个稳定提交。

未来分公司

用于过于侵入性变化的单个分支来与其它方法进行处理。

这是一种罕见的模式,但作物最多偶尔当人们使用持续集成。有时候球队需要做出改变,这是非常侵入性的代码库,并整合工作正在进行中不适用很好的常用技术。在这种情况下,球队做一些事情,看起来很像功能分支,他们削减未来的分行,从主线只有拉,不是做干线整合,直到结束。

一个未来的分公司和特性分支之间最大的区别是,只有一个未来的分公司,因此人们对主线未来科的工作永远不会太远,而且也没有其他不同分支处理。

这可能是对未来的分公司,几个开发人员的工作,在这种情况下,他们做持续集成与未来的分公司。当他们做他们的整合首先从主线到未来科拉他们集成他们的变化之前。这会减慢一体化进程,而是使用未来分公司的成本。

何时使用

我应该强调,这是一种罕见的模式。我怀疑大多数进行持续集成的团队从来都不需要使用它。我看到它对系统的架构进行了特别有侵略性的改变。一般来说,这是最后的手段,只有在我们不知道如何使用的时候才会用到分支的抽象相反。

将来的分支仍然应该尽可能短,因为它们在团队中创建了一个分区,并且像任何分布式系统中的分区一样,我们需要将它们保持在绝对最小值。

合作部门

为开发人员创建的分支,用于在没有正式集成的情况下与团队的其他成员共享工作。

当使用一个团队干线,则大多数协作都是通过主线进行的。只有当主线集成出现做一个团队的其他成员看到开发商在做什么。

有时开发人员希望在集成之前共享他们的工作。为协作打开一个分支允许他们在一个特别的基础上这样做。可以将分支推送到团队的共享存储库中,协作者可以直接从其个人存储库中拉取和推送,也可以设置一个短期存储库来处理协作工作。

一个协作分支通常是暂时的和封闭的,一旦整合到主线的工作。

何时使用

随着集成频率的降低,协作分支变得越来越有用。如果团队成员需要协调对某个代码区域的某些更改,而这些更改对几个人来说很重要,那么长寿命的功能分支通常需要非正式的协作。但是一个团队使用持续集成可能永远不需要打开协作分支,因为它们只有很短的一段时间工作彼此不可见。主要的例外是实验科,从定义上讲,它永远不会被集成。如果几个人一起做一个实验,他们需要使实验分支也是一个协作分支。

团队整合分公司

允许子团队在与主线集成之前相互集成。

较大的项目可能有几支球队在一个单一的逻辑代码库运行。团队集成分支允许团队成员不使用主线项目的所有成员整合相互集成。

有效地,团队将团队集成分支视为团队内的主线,并将其与整个项目主线进行集成。除了这些集成之外,团队还单独努力与项目主线集成。

何时使用

使用一个团队整合分支明显的驱动程序是正在积极通过这么多的开发商,这对他们有意义分成不同的团队开发的代码库。但是,我们应该警惕这样的假设,因为我碰到的很多,似乎过大,所有的工作是落单的主线球队,但设法都是一样的。(我已经有上百年的开发人员的这一报告。)

团队集成分支的一个更重要的驱动因素是期望的集成频率的差异。如果项目总体上希望团队完成几个星期的功能分支,但是子团队更喜欢持续集成,那么团队可以建立一个团队集成分支,与之进行持续集成,并在完成后将他们正在处理的功能与主线集成。

如果整个项目用于健康科和子团队的卫生标准。一个子团队可能选择在健康的水平更严格的操作,如果更广泛的项目不能保持主线到足够高的高度稳定性。类似地,如果子团队正在努力使其健康提交足够的良好控制的主线,他们可以选择使用团队整合分公司,并使用自己的发布分支前都要主线,以稳定的代码。这不是一个情况我通常青睐,但在特别的情况下充满需要。

我们还可以将团队集成分支看作是一种更结构化的协作分支,它基于正式的项目组织,而不是特别的协作。

查看一些分支策略

在这篇文章中,我讨论了根据模式进行分支。我这样做是因为我不想提倡一种分支方法,而是要列出人们做这件事的常见方式,并在我们在软件开发中发现的各种不同环境中思考他们的取舍。

许多分支方法已经被描述了多年。当我试着去理解它们是如何工作的,什么时候是最好的使用它们的时候,我已经通过我头脑中的半成形模式来评估它们。现在我终于开发并写下了这些模式,我想看看其中的一些策略,看看我是如何看待它们的。

Git的流

Git的流动已经成为我碰到的最常见的分支政策之一。它是作者:文森特·德里森2010年,以git的身份出现越来越受欢迎。在git之前,分支经常被看作是一个高级的主题。Git使分支更具吸引力,部分原因是改进了工具(例如更好地处理文件移动),但也因为克隆存储库本质上是一个分支,在推回到源存储库时需要对合并问题进行类似的思考。188bet足球充值

Git流使用干线(称其为“发展”)在一个单一的“原点”库。它用功能分支协调多个deveopers。鼓励开发人员使用他们的个人资料库作为合作部门与其他从事类似工作的开发人员进行协调。

git的传统核心分支是“master”,在git流中,master用作产品到期分行. Git流使用释放分支使工作从通过“发展”,通过发布分支为“大师”。修补程序均已通过举办热修复分支

Git流没有说明特性分支的长度,因此也没有说明预期的集成频率。对于干线是否应该是健康科如果是的话需要什么健康的水平。发布分支的存在意味着它不是一个准备发布的主线

作为Driessen的增编今年指出,混帐流设计供种,其中有在生产中发布多个版本,如安装在客户现场的软件项目。bet188足球拥有多个现场版,当然,对于使用的版本分支的主要触发之一。然而,许多用户在单个生产的web应用的上下文中拿起git的流 - 在该点,例如一个分支结构容易变得必要以上复杂。

虽然混帐流是非常受欢迎的,在这个意义上,很多人说他们使用它,它经常会发现谁的人说他们正在使用Git流实际上是做完全不同的东西。通常,它们的实际做法是接近GitHub的流量。

GitHub流

虽然Git流真的很流行,但它的分支结构对于web应用程序来说不必要的复杂性鼓励了许多替代方案。随着github的流行,开发者使用的分支策略将成为众所周知的策略github流也就不足为奇了。这个最佳描述作者:斯科特·查孔

有了这样的GitHub流程的名称,也没有惊喜,这是明知根据,赞成与反对,混帐流动的反应。两者之间的主要区别是不同种类的产品,这意味着不同的上下文,并且因此不同的图案。Git的流量假定一个产品,几个版本的生产。GitHub的流程假定生产高频集成的单一版本到准备发布的主线. 在这种情况下,释放分支不需要。生产问题的解决方式与常规功能相同,因此不需要热修复分支,在某种意义上,热修复分支通常意味着偏离正常进程。删除这些分支可以极大地将分支结构简化为主线分支和特征分支。

GitHub的流程采用调用它的主线“主人”。与开发商工作功能分支. 他们定期将其功能分支推送到共享存储库,以支持可见性,但在功能完成之前,不会与主线集成。Chacon指出,功能分支可以是一行代码,也可以运行几个星期。在这两种情况下,流程的工作方式都是相同的。作为github,pull请求机制是主线集成和用途来自提交

Git流和GitHub流经常会混淆,所以和以前一样,要比名称更深入地了解到底发生了什么。它们的主题都是使用主线和特征分支。

基于主干的开发

正如我之前写的,我经常听到“主干驱动开发”是持续集成的同义词。但将主干驱动的开发看作git流和GitHub流的分支策略也是合理的。保罗·哈曼特写了一篇深度网站来解释这个方法。保罗是我在ThoughtWorks的长期同事,他有一个可靠的记录,就是用他那把值得信赖的+4弯刀深入客户僵化的分支结构。

干线为基础的发展集中在做的所有工作干线(称为“trunk”,这是“mainline”的常见同义词),因此避免了任何类型的长寿枝。较小的团队直接使用主线集成,较大的团队可能使用短期的功能分支其中“短”意味着不超过几天,这可能相当于持续集成在实践中。团队可以使用释放分支(称为“释放分支”)或准备发布的主线(“从后备箱释放”)。

最后的想法和建议

自从最早的程序,人们发现,如果他们想要一个程序做一些有点不同于现有的程序,它很容易采取一个副本的来源,并根据需要调整。有了所有的资源,我有能力做出任何我想要的改变。但通过这个操作,我的副本很难接受原始源代码中的新功能和错误修复。随着时间的推移,这可能会变得不可能,正如许多企业在早期的COBOL程序中发现的那样,并且在今天受到广泛定制的ERP软件包的影响。即使没有使用这个名称,我们在复制源代码并修改它的任何时候源分支,即使没有参与的版本控制系统。

正如我在这篇长文章开头所说:分支很容易,合并更难。分支是一种强大的技术,但它使我想到goto语句、全局变量和并发锁。功能强大,易于使用,但容易过度使用,往往成为粗心和缺乏经验的陷阱。源代码控制系统可以通过仔细跟踪更改来帮助控制分支,但最终它们只能充当问题的见证者。

我不是谁的人说的分支是邪恶的。有日常问题,比如多个开发促进一个单一的代码库,在合理使用的分支是必不可少的。但是,我们应始终保持谨慎,并记住帕拉塞尔苏斯的看法,即有益的药物和毒物之间的差异剂量。

所以我的第一个技巧进行分流:无论何时考虑使用分支,都要考虑如何合并. 任何时候你使用任何技术,你都是在与其他选择进行权衡。如果不了解一项技术的所有成本,你就无法做出明智的权衡决定,而随着分支,派珀在你合并时会收取她的费用。

因此,接下来的方针:确保您了解分支的替代方案,它们通常是优越的。记得波达定律,有没有通过提高你的模块来解决问题的方法吗?可以改善您的部署流水线?是标签还不够吗?什么样的变化对您的过程将使得这个分支不必要的?这很可能是分公司,其实,最好的路线,现在走了 - 但多数民众赞成提醒您应该在未来几个月内获得解决一个深层次问题的味道。摆脱需要一个分支通常是一件好事。

记得乐华插图:树枝分叉呈指数,因为他们不跑整合。因此,考虑多久你整合你的分支。把你的积分频率提高一倍。(这里显然是一个极限在这里,但你不会靠近它,除非你在的区域是持续集成)在更频繁地集成时会遇到一些障碍,但这些障碍通常正是为了改进您的开发过程而需要给予过多的炸药的那些障碍。

由于合并是分支的最困难的部分,注意合并困难的原因. 有时是流程问题,有时是架构的失败。不管是什么,不要屈服于斯德哥尔摩综合症。任何合并问题,特别是引发危机的合并问题,都是提高团队效率的路标。记住,只有从错误中吸取教训,错误才有价值。

我在这里描述的模式概述了在我和同事的旅行中遇到的分支的常见配置。通过给它们命名,解释,最重要的是,解释它们何时有用,我希望这能帮助你评估何时使用它们。记住,和任何模式一样,它们很少是普遍的好或坏——它们对你的价值取决于你所处的环境。当您遇到分支策略(无论是众所周知的,如git流或基于主干的开发,还是开发组织中自己开发的)时,我希望了解其中的模式将帮助您决定它们是否适合您的环境,以及哪些其他模式将有助于混合。


确认

Badri Janakiraman、Dave Farley、James Shore、Kent Beck、Kevin Yeung、Marcos Brizeno、Paul Hammant、Pete Hodgson和Tim Cochran阅读了本文的草稿,并就如何改进给出了反馈。

彼得·贝克尔提醒我指出叉子也是分支的一种形式。我取了史蒂夫·伯楚克的名字“主线”软件配置管理模式

进一步阅读

有很多关于分支的材料,我不能做一个认真的调查。但我想强调一下史蒂夫·伯丘克的书:软件配置管理模式. 史蒂夫的作品,连同他的撰稿人布拉德·阿普尔顿的作品,对我如何看待源代码管理产生了深远的影响。

显著修订

2020年5月28日:出版的最后一期

2020年5月27日:发布时间看一些分支政策

2020年5 21:发布协作分公司和团队整合分公司

2020年5月20日:起草最终想法

2020年5月19日:已发布的未来分支

2020年5月18日:已发表的实验分支

2020年5月14日:发表的第一步主线

2020年5月13日:对分枝政策起草节

2020年5月13日:发布时间发布列车

2020年5月12日:发布的修补程序分支

2020年5月11日:起草发布准备主线

2020年5月11日:发布时间环境科

2020年5月7日:发表成熟度分支

2020年5月6日:发布分支

2020年5月5日:出版的集成摩擦,模块化的重要性,以及我对集成模式的个人想法

2020年5月4日:已发布的审阅提交

2020年4月30:持续集成和功能分支的发布时间相比较。

2020年4月29日:发布的持续集成

2020年4月28日:草案:增加了模块化部分

2020年4月28日:发布时间积分频率

2020年4月27日:草案:广义生产分行至到期分行

2020年4月27日:发布时间特性分支

2020年4月23日:发布时间主线集成

2020年4月22日:发布健康科

2020年4月21日:发布时间主线。

2020年4月20日:发布第一批:源分支。

2020年4月5日:第五稿:处理发布模式的评审意见,编写发布序列,修改源分支。

2020年3月30日:第四稿:处理了关于base和integration部分的大部分评论。使源分支成为一种模式。

2020年3月12日:三稿:重铸特殊版式

2020年3月5日:第二稿:重组文本集成模式和路径的生产。添加插图版本的分支和修复程序,改写文本匹配

2020年2月24日:第一草案:与审阅共享

2020年1月28日:开始写作