关于版本控制:分支策略

关于版本控制:分支策略

Branching Strategies

我工作的公司开始对他们当前的分支模型有疑问,我想知道社区接触到哪些不同类型的分支策略?

有针对不同情况的好方法吗? 贵公司使用什么? 它们的优缺点是什么?


这是我过去成功使用的方法:

/ trunk-边缘出血。该代码的下一个主要版本。在任何给定时间可能有效或可能无效。

/branches/1.0、1.1等。稳定的代码维护分支。用于修复错误,稳定新版本。如果是维护部门,则应在任何给定时间进行编译(如果适用)并准备进行质量检查/装运。如果是稳定分支,则应编译并完成功能。不应添加任何新功能,不进行重构以及不进行代码清理。您可以添加前缀以指示稳定分支与维??护分支。

/分支机构/ cool_feature。用于可能会也可能不会进入主干(或维护分支)的高度实验性或破坏性工作。不保证有关代码的编译,工作或其他行为。在合并到主线分支之前,应尽可能保持最短的时间。

/tags/1.0.1、1.0.2、1.1.3a等。用于标记打包和出厂的发行版。永不改变。制作所需数量的标签,但它们是不可变的。


我强烈鼓励您阅读Eric Sink关于此事的观点:

第7章:分支

我和Eric一样,更喜欢他谈论的"文件夹"样式分支。


有关分支模式的信息,请参见Brad Appleton的"流线:并行软件开发的分支模式"。这是繁重的工作,但就分支的广度和深度而言,我还没有发现任何可以超越它的东西。


我们的存储库如下所示:

1
2
3
4
5
/trunk
/branches
/sandbox
/vendor
/ccnet

/ trunk是您的标准,发展前沿。我们使用CI,因此必须始终构建并通过测试。

/分支这是我们批准的大型更改的地方,即我们知道的某些内容将使更改成为主要内容,但可能需要做一些工作并破坏CI。另外,我们还负责维护版本,这些版本具有自己的CI项目。

/ sandbox每个开发人员都有自己的沙箱,以及共享的沙箱。这是针对您在不执行实际工作时执行的"让我们向产品中添加LINQ提供程序"这类任务。它最终可能会进入主干,可能不会,但它在那里并且受版本控制。这里没有CI。

/ vendor标准供应商分支,用于我们编译的项目,但不是我们维护的代码。

/ ccnet这是我们的CI标记,只有CI服务器可以在此处写入。 Hindsight会告诉我们将其重命名为更通用的名称,例如CI,BUILDS等。


  • 一个分支用于主动开发(/ main或master,取决于术语)
  • 每个维护版本都有一个分支->它只会收到很小的修正,而所有主要开发都移至/ main
  • 每个新任务的一个分支:创建一个新分支,以处理Bugzilla / Jira / Rally上的每个新条目。经常提交,使用英寸的卵石签入文件自行记录更改,并仅在完成并经过良好测试后将其合并回其"父"分支。
  • 看看这个http://codicesoftware.blogspot.com/2010/03/branching-strategies.html以获得更好的解释


    第一件事:吻(保持简单愚蠢!)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    /branches
      /RB-1.0 (*1)
      /RB-1.1 (*1)
      /RB-2.0 (*1)
    /tags
      /REL-1.0 (or whatever your version look like e.g. 1.0.0.123 *2)
      /REL-1.1
      /REL-2.0
    /trunk
      current development with cool new features ;-)

    * 1)保持版本可维护-例如如有必要和/或需要,可以合并到中继的Service Pack,修补程序,Bug修补程序)
    * 2)major.minor.build.revision

    经验法则:

  • 标签文件夹无需签出
  • 发布分支中只有很少的编码(使合并更简单)-没有代码清除等。
  • 永远不要在标签文件夹中编码
  • 切勿将具体的版本信息放入源文件中。使用占位符或0.0.0.0,构建机制将用您正在构建的版本号替换它们
  • 切勿将第三方库放入您的源代码管理中(也没有人会将STL,MFC等库添加到SVN ;-)
  • 只提交编译的代码
  • 优先使用环境变量而不是硬编码的路径(绝对路径和相对路径)
  • --hfrmobile


    当发布准备好进行最终质量检查时,我们会分支。如果在质量检查过程中发现任何问题,则将这些错误修复在分支中,进行验证,然后合并到中继中。分支机构通过质量检查后,我们会将其标记为发布。该版本的所有修补程序也会在分支上完成,验证,合并到主干,然后标记为单独的版本。

    文件夹结构如下所示(1个质量检查行,2个修补程序版本和主干):

    /branches

    /REL-1.0

    /标签

    /REL-1.0

    /REL-1.0.1

    /REL-1.0.2

    /树干


    我在这里没有看到的替代方法是"变革分支"的哲学。

    如果您的后备箱是"当前发行版",怎么办呢?当一次仅发布一个版本的应用程序时(例如网站),此方法效果很好。当需要新功能或错误修复时,将创建一个分支来保存该更改。通常,这允许将修补程序迁移到各个版本,并防止您的牛仔编码员意外添加您不想要的功能。 (通常是后门-"仅用于开发/测试")

    Ben Collins的指针在确定哪种样式适合您的情况时非常有用。


    Gnat在分支策略方面的各种建议中都写下了出色的分解。

    没有一种分支策略,它适用于:

    • 您的团队规模
    • 您的产品和生命周期
    • 您正在使用的技术(网络,嵌入式,Windows应用)
    • 您的源代码控制,例如Git,TFS,Hg

    杰夫·阿特伍德(Jeff Atwood)的职位打破了很多可能性。另一个要补充的是晋升的概念(来自Ryan Duffield的链接)。在这个设置中,您有一个dev分支,测试bracnh和release分支。您可以将代码提升到发行分支并被部署。


    Henrik Kniberg的多个敏捷团队的版本控制也有一些需要考虑的方面。


    我们使用git分支的狂野,狂野,西方风格。我们有一些分支具有按惯例定义的知名名称,但是在我们的情况下,标签实际上对于我们满足公司流程策略要求的重要性更大。

    我在下面看到您使用Subversion,所以我想您可能应该查看Subversion手册中有关分支的部分。具体来说,请查看"分支机构维护"和"通用分支模式"中的"存储库布局"部分。


    杰夫·阿特伍德(Jeff Atwood)在一篇不错的博客文章中写道。该帖子中有一些重要链接。


    我们目前有一个分支机构进行日常维护,而一个分支机构则负责"新计划",这仅意味着"将来会出现某种东西;我们不确定何时。"我们偶尔还会有两个维护分支:一个是为当前生产中的问题提供修复,另一个是仍在质量保证中。

    我们看到的主要优势是能够更快地响应用户请求和紧急情况。我们可以对正在生产的分支进行修复,然后发布它,而不释放可能已经签入的任何额外内容。

    主要缺点是我们最终会在分支之间进行大量合并,这增加了某些内容被错误遗漏或合并的机会。到目前为止,这还不是问题,但是绝对要牢记。

    在制定这项政策之前,我们通常在主干中进行所有开发,并且只有在发布代码时才分支。然后,我们根据需要针对该分支进行了修复。它比较简单,但没有那么灵活。


    我们在工作中遵循的理念是将行李箱保持在可以随时推入的状态,而不会对现场造成重大伤害。这并不是说行李箱将始终处于完美状态。当然会有错误。但是关键是永远不要彻底破坏它。

    如果您要添加功能,请分支。设计更改,分支。我曾想过很多次,"哦,我可以在后备箱中做这件事,用不了那么长时间",然后5个小时后,我不知道是什么在破坏我的bug。真的希望我分支了。

    当您保持行李箱清洁时,您就有机会快速应用并推出错误修复程序。您不必担心自己的分支代码容易损坏。


    无论选择哪种分支模式,都应尝试将分支保持为二叉树形式,如下所示:

    1
    2
    3
    4
    5
    6
    7
       trunk - tags
         |
        next
       /  \  \
    bugfix  f1  f2
            /   \  \          
           f11    f21 f22
    • 子节点只能与直接父节点合并。
    • 尽力将合并的整个分支与父分支合并。从不合并分支中的子文件夹。
    • 只要您仅合并并从整个分支中选取,就可以在需要时选择提交。
    • 上图中的下一个分支仅用于说明,您可能不需要它。

    对于Subversion,我同意Ryan Duffield的评论。他所指的这一章对使用哪种系统进行了很好的分析。

    我问的原因是Perforce提供了一种完全不同的方式来从SVN或CVS创建分支。另外,所有DVCS都提供了自己的分支哲学。您的分支策略将由您使用的工具决定。

    仅供参考,Svnmerge.py是协助合并SVN中分支的工具。只要您经常使用它(每10-30次)提交一次,它就可以很好地工作,否则工具可能会感到困惑。


    这取决于您使用的版本控制系统。每个VCS都有不同的分支方法。

    您使用哪个VSC?


    推荐阅读