共享库的分支和版本控制策略


12

这些 帖子似乎相关,但是我的大脑开始融化,试图通过:P来思考

我的雇主刚刚开始使用源代码控制,主要是因为在雇用更多开发人员之前,“存储库”是唯一的开发人员的硬盘驱动器,该开发人员主要在家中工作。所有他写的.NET代码的检入集体,并有大量的重复(读:复制粘贴)功能。现在,我们的SCM系统是光荣的备份。

我想将某些重复的代码放入共享库中。我将单独保留原始存储库,以便我们不会破坏任何内容,我们可以在需要时移动和/或重构现有代码。因此,我为新代码(包括库)设置了一个仓库。

我的问题围绕着对库进行版本控制而没有过多的时间来烦恼我们:承认我们需要一种更一致的方法,更多的开发人员都编写非常相似的代码,管理人员和其他开发人员都愿意进行重组,但可能不会如果解决方案开始影响生产效率,则下降得很好。

在我的痴迷心中,理想的解决方案是分别构建库,而每个从属项目都是针对故意选择的兼容版本构建的。这样,我们就可以准确地知道哪些客户端具有哪个库的哪个版本,可以更可靠地重现错误,维护产品和库的独立发行分支,并且在更改共享代码时不会破坏彼此的项目。

但是,这使得更新库很麻烦,尤其是对于在家工作的开发人员而言。我希望这些库能快速变化,至少在最初(最终)将这些通用位组合在一起时会如此。我完全有可能对此进行全面考虑,并且可以根据最新的库提交构建所有内容,但我至少要做好准备,以便我们决定某些组件必须独立版本化并分散式。必须在GAC中安装某些库这一事实使得版本控制特别重要。

所以我的问题是:我想念什么?我觉得我已经专注于一种解决方案,现在正在尝试寻找可以使更改更平滑的变体。您以前使用过哪些策略来解决此类问题?我意识到这个问题无处不在。我会尽力清理并澄清所有不确定性点。

尽管我很想使用Mercurial,但我们已经在集中式商用SCM(Vault)上花了钱,并且切换不是一种选择。此外,我认为这里的问题比版本控制工具的选择更深。


固定成本沉没
替代

Answers:


1

我赞扬你的主动。当您实施此操作时,这将为组织带来许多好处。我将移动代码而不是复制它。拥有副本可能会导致不兼容的更改,需要解决。

随着库的开发和稳定,将会有些痛苦。一旦完成,收益就会到达。请记住,与库的接口本质上是一个合同,而使用该合同的项目则是如此。您可能具有删除旧接口的优势,因为您可以确定是否使用了旧接口。

在库稳定的同时,获取新库可能应该是代码更新过程的一部分。您可能要计划库更改的提交。宣布要移动的代码可能有助于减少冲突的更改。

这些库应视为单独的项目,并应尽快稳定下来。一旦稳定了它们(尤其是接口),应该更容易将更改与其他项目集成在一起。新库应使用旧代码。使用自己的发行版ID标记稳定的库发行版。尝试像对待第三方库一样对待这些库。


6

项目之间共享的代码必须视为自己的项目。必须与第三方库一样对待它们。没有别的办法了。

如果您不能让您的团队采用共享代码策略,则可以在Mercurial或GIT等现代源代码管理工具的帮助下自己采用,即使您的公司将不会正式使用SCM。稍加注意,两个SCM可以通过告诉一个忽略另一个的内部文件来使用同一工作目录。您将使用一个SCM来处理日常事务,而使用公司的SCM来进行集成。

无论如何,您必须负责何时使用其他项目对共享代码进行的修改来更新工作目录。只有当您准备好应对可能出现的不兼容时,这些情况才会发生。否则,您的工作可能变得不稳定,无法完成。


4

如果您有能力将它们分解为单独的“模块”项目,则可以采用这种方法。要考虑的一件事是代码耦合。您可以通过分解关注点分离它们,这是一个好习惯。

一些好处:

  1. 每个模块的调试更简单。
  2. 更快的构建周期(不重建未更改的库)
  3. 一旦工作成功,您就不太可能通过更改该模块之外的其他区域来破坏它(不是100%,但是可以减少机会)。
  4. 如果不是相互依存的混乱局面,则更容易分解工作任务。
  5. 修复一个库时,较小块的分配速度更快(这是拥有.dll / .so文件的一个重要原因)。

我对此部分确实有一个问题:

“在我的痴迷心中,理想的解决方案是分别构建库,每个从属项目都是针对故意选择的兼容版本构建的。”

您是否静态链接了整个项目?如果是这样,将导致:6.减少不必要的代码膨胀。

一些负面因素:

  1. 如果项目很小,那么您只是在不需要它的地方增加了复杂性。
  2. 分支很多模块可能会变成大型项目的维护问题。我不知道“保险柜”,所以不确定它们的分支操作是好是坏。

它是C#代码,因此按通常的含义对静态链接“不”。Vault就像Subversion 1.5之前的版本一样:PI 非常热切地等待svn中的合并跟踪,以为我终于到了天堂。然后我找到了DVCS。
Shambulator 2011年

1

现在,您似乎已经将一个代码库一次全部构建到一个目标中。您可能不超过五个开发人员。我真的没有看到过多分离库的实用性。您可以将工作流程从代码->编译->运行更改为代码->编译->复制DLL->编译->运行...

一些公司(谷歌和亚马逊)拥有足够的开发基础架构,因此拥有许多单独构建的单独库是很容易的。使它轻松运行的基础结构涉及一种指定驻留在您的SCM中(可能有)的库版本的方法,一种指定驻留在您的SCM中的依赖版本的方法,一种可以理解它并正确编译所有内容的构建服务器。 ,以及从构建服务器和本地工作区中获取适当的构建工件的方法。我怀疑你有那个。

如果没有该基础结构,则当满足以下条件之一时,我将分离该项目:

  • 您有多个产品或不同的应用程序,具体取决于此库
  • 您一次只在这些库上工作几天
  • 该库的功能与任何与业务相关的功能(例如,围绕平台特定的API的包装程序)都极为不同
  • 合并项目的构建时间过长

当您有很多项目,而有些项目有专门的开发人员和独立的发布周期时,我会担心构建该基础结构。

可以应该现在做的是建立可靠的,可重复的构建了一个构建服务器,并确保你能找到从给定的可执行文件修订版本。您似乎正在使用.NET。设置CruiseControl.NET插入版本字符串(包括修订号)非常简单。

拥有构建服务器后,拆分库几乎就是将其移至Vault中,在CC.NET中添加另一个目标,并将生成的DLL复制到主项目的库文件夹中并提交的问题。在SCM方面比日常开发更容易。


1

Mercurial具有称为子存储库的功能。我最近从Kiln 阅读了这个博客,解释了它们如何工作。

基本上,您将项目链接到库存储库的特定修订版。您可以根据需要任意更新库,而无需破坏相关项目。准备就绪后,可以将库的新功能引入项目中,并处理所有损坏。不同的项目可以链接到库的不同修订版,因此不必全部同步并使用相同的库修订版。

也许保险柜具有类似的功能。


1

我们已经在SC中的每个模块中添加了一个元数据文件,用于指示它所依赖的所有其他模块的名称。产品将具有第二个元数据文件,该文件指示该产品需要每个从属模块的版本。在此之上的是一个工具,用于分析元数据文件,检出所有必需的模块并为我们的IDE生成一个项目。

这样可以确保我们的构建始终是可复制的,并且始终在组件之间共享正确的头文件。随着需求的发展,其他复杂性也可以叠加。我们拥有一些工具,它们现在可以生成关于产品的任何两个版本之间的差异的报告,可以指定SC中所有独立模块中已更改的源文件,签入注释,版本注释,作者。我们从代码库中获得了惊人的数量重用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.