SVN和代码在几个项目之间共享

时间:2009-10-28 16:12:23

标签: svn branch

我在SVN有多个项目。这些项目中的每一个都位于自己的主干中,并为发布而分支。

每个项目都有一个共享代码。问题是处理代码的最佳方法是什么。

让我给出几个场景以及与它们相关的问题

a)将共享代码放在单独的主干(或存储库)中,并使用svn:external。

如果我们分支一些项目,将会出现两个问题:

  • 在trunk中进行的共享代码的任何修改都将传播到分支,因为svn:external将获取更改
  • 如果我们需要在某个时刻返回并构建完全构建用于发布的代码,我们将很难获得准确的代码,因为snv:external将再次获取共享代码的最新副本,而不是在项目受到影响时的代码。

据我所知,有一项工作。一旦我们分支,我们就可以修改svn:external来获取共享代码的精确修订版。但是,还有两个陷阱:

  • 每次分支时都需要记住这样做。 (我讨厌这些容易忘记的事情。)
  • 如果需要为分支/已发布项目执行修补程序,则无法修改共享代码。

b)另一个解决方案是在项目分支时分支共享代码,并在外部更改为指向共享代码的bracnhed副本。

  • 同样,其中一个问题是手动步骤,这很容易忘记
  • 另一个问题是合并问题。当您尝试将项目中的更改合并到主干时,SVN将跳过外部。因此,开发人员需要记住手动合并共享代码。

我错过了什么吗?有没有合理的方法来解决这个问题?

6 个答案:

答案 0 :(得分:13)

我个人保留一个单独的存储库,然后使用[http://svnbook.red-bean.com/en/1.0/ch07s03.html svn:externals]属性。

SVN Externals允许您链接到其他存储库(即使是您没有运行的存储库,例如smarty subversion repo),当您运行svn更新时,您的项目和外部存储库都将更新。

使用SVN外部,您还可以使用http://path-to-project.com/svn/thing -r1234之类的某些标记链接到特定修订版本以及保持静态所需的其他内容

最佳实践IMHO始终指定修订版,然后在更改共享库时更新修订版号,以便您可以跟踪更新此数据的原因。当你标记或分支主项目时,也会保持一切正常。

答案 1 :(得分:3)

你有两个正确的答案,有两套缺点 这是我推荐的内容

将您的共享代码放入另一个存储库, 使用发布版本标记代码 在trunk目录中创建一个指向标记的svn externals。

更改库时,请将其重新标记,然后更新中继应用程序。 当您选择分支时,您的分支仍将指向您的库的正确标记版本。

或者尝试构建库的单独版本,并将库引用为jar或lib /。

答案 2 :(得分:3)

我们使用类似于CWT的系统:共享代码本身往往是独立的项目,因此在存储库(或单独的存储库)中单独存在。在使用外部项目(上游项目)的项目中,我们包含共享/下游项目的编译/打包二进制文件。

这样,下游项目中的意外更改不会阻止上游项目。

我们编写了一些脚本,以便在必要时使用这些二进制文件的更新版本自动更新主要上游项目(否则,这是将程序包复制到相应项目的手动过程,但这无论如何都不是那么大)。

我们在这个madnes ^ W方法中看到的缺点是,正在进行非常活动开发的下游项目(比如,在新库的早期阶段)需要看起来像是上游项目的更新数量过多。测试上游项目可能需要更新共享库,编译,复制上游二进制文件,以及编译/部署/上游项目。然而,一旦图书馆的最初开发狂潮减慢,并且lib变得有些稳定,这个“问题”就会消失。

与CWT一样,上游项目无法以任何有意义的方式修改共享代码。下游的更改必须在该项目中明确进行,并在必要时向上游传播。

答案 3 :(得分:2)

我们使用这样的单一存储库结构:

/trunk/project1
/trunk/classlibrary (shared code)
/trunk/project2

在C#中(可能不是您选择的语言),project1和project2包含对classlibrary的引用。当我们构建时(这是编译的.NET模型的一个很大的优势),找到正在构建的项目和class_library之间的任何不一致。在提交更改之前解决了这些不一致问题。使用基于服务器的构建工具(我们使用CruiseControl.NET),我们可以同时构建所有项目,这将告诉我们任何问题。

除非你的project1和project2需要引用一个特定版本的classlibrary(我们避免使用它,试图使project1和project2始终使用class_library的最新版本),这非常顺利。

我倾向于避免为相关应用程序创建单独的存储库。由于上面示例中的class_library将所有这些内容绑定在一起,因此在单独的版本中维护它的优点或逻辑很少,因为它在项目级别分离的真正原因是它是共享代码。共享代码的生产应用程序出于某种原因这样做 - 它们应该使用相同版本的共享代码,这意味着它们应该属于同一个源代码控制分支。

答案 4 :(得分:0)

我对处理共享代码(特别是Java和.NET或C / C ++库)的建议是使用两组存储库:一组用于源代码,另一组用于版本化已发布的映像。当您对“common”项目进行更改时,将源更改提交到源树,然后构建它,然后通过将它们作为发布树上的新修订提交来发布二进制文件。然后,使用“common”项目的项目使用svn:externals属性来引入已发布的二进制文件。修改共享代码的本地映像没有诱惑力。如果有人想要修改“通用”代码,那么他们就会通过该项目的正常开发实践来实现。

有关详细信息,请参阅此answer以查找类似问题。

答案 5 :(得分:0)

列表中缺少的答案是:

c)始终将外部指向特定版本的共享代码。

这非常有效:

  1. 您始终可以下拉特定版本的项目并保证构建。
  2. 分支和标记仅是项目路径上的操作。
  3. 可以为1个项目更新共享代码,但是第二个项目在准备好之前不会接收它们。
  4. 当第二个项目确实接收到更改时,您会在后备箱中记录一个事件,说明它已被拾取以及原因。
  5. 您有机会发布具有项目特定功能的特定版本的库。如果项目尚未准备好进行API更改但需要某些错误修复等,这可以让您摆脱困境。
  6. 如果需要,可以在单独的工作副本中检出库,并在主项目旁边进行修改。如果暂时更改项目以从磁盘上的工作副本中获取代码,则可以根据需要并行处理库和项目。