我们的项目在svn下,一切进展顺利。最近,一个主要客户要求我们为他们做一些非常特定的自定义,这些自定义需要编码和内容(无法使用配置或部署来完成)。我们决定维持两条独立的发展路线:trunk
分支是我们的标准版本,已部署用于
普通顾客arsh
分支是针对该客户的,并且正在与trunk
正在进行的开发中分开
现在,事情是arsh
应该从trunk
接收更新,有时arsh
中实现的功能在trunk
中很有用。这种关系是双向的,但一个方向相当普遍(从trunk
到arsh
),而另一个方向是偶然的。
最好的方法是什么?工作流程 ?最佳做法?见解?
编辑:我们使用PHP 5.3,MySQL,Apache和Linux。
最佳答案
最佳实践? #ifdef
(或由运行时配置或任何其他编译时或运行时条件式有条件地包含或有条件地依赖注入同一接口的单独实现)!
在任何版本控制系统中,将并行版本保持为分支是很痛苦的。最好使用适当的条件编译或运行时配置技术来维护并行版本。
请记住,如果将分支A合并到分支B,然后将分支B合并回分支A,则两个分支将完全相同。这是三向合并的固有属性。这正是功能分支所需的功能,但完全不适合为不同客户维护并行版本。
要为不同的客户保留版本,请使用条件编译。
在面向对象的代码中,通常可以使基类具有公共逻辑,而每个变量的自定义派生类仅具有特定于该变量的逻辑,该逻辑有条件地包含在项目中或有条件地实例化。
大多数编程语言都支持某种形式的条件编译,而Java是例外。
通过运行针对所有变体的测试或由持续集成服务器构建和测试所有变体,该方法使每个人始终可以立即检查它们是否对任何一个变体都没有破坏任何功能。
您提到了PHP。那里没有编译步骤,因此配置仅是运行时。我可能会创建一个包含特定于客户的覆盖的目录,该覆盖将有条件地包含在适当的模板中。
注意:我目前正在以这种方式为20多个客户定制的C ++项目,并且可以很好地扩展。我们没有每个客户确切的代码,相反,我们有一组可选的功能,不同的子集交付给不同的客户。这使测试所有功能变得容易一些,因为我们可以构建一个最大的变体并对其进行测试。当您扩展到大量功能时,这会有所帮助,尤其是在您的项目需要很长时间才能构建的情况下(连续集成构建大约需要一个小时,每晚构建需要8个小时,而所有客户变体的构建要花一整天的时间)。