处理多个Subversion项目之间的关系

4
在我的公司,我们使用一个SVN仓库来存储我们的C++代码。代码库由一个共同部分(基础设施和应用程序)和客户端项目(作为插件开发)组成。
仓库布局如下:
- 基础设施 - App1 - App2 - App3 - 为客户端1开发的项目
- App1插件 - App2插件 - 配置
- 为客户端2开发的项目
- App1插件 - App2插件 - 配置
每个客户端项目的典型发布包括项目数据和它所使用的每个项目(例如,基础设施)。
每个目录的实际布局为:
- 基础设施
- 分支 - 标签 - 主干
- 为客户端2开发的项目
- 分支 - 标签 - 主干
其他项目也是相同的布局。
我们有几个问题与上述布局有关:
  1. 对于客户项目,启动一个全新的开发环境很困难,因为必须检出所有涉及的项目(例如:基础设施、App1、App2、project-for-client-1)。
  2. 由于上述原因,很难在客户项目中标记发布版本。
  3. 如果客户项目需要更改一些公共代码(例如基础设施),我们有时会使用分支。很难跟踪哪些分支用于哪些项目。

SVN 中是否有任何方法可以解决以上任何问题?我考虑在客户项目中使用 svn:externals,但阅读了this post后,我明白这可能不是正确的选择。


虽然我的问题涉及不同类型的svn布局问题,但我收到了一个非常好的关于svn:externals的答案,可能会对您有所帮助。https://dev59.com/M3VC5IYBdhLWcg3wvT1a hth - Pieter
链接文章的作者在用普通副本(分支)替换外部引用代码后,在其他机器上使用“svn update”时遇到了问题。我不会因为这种边缘情况而放弃使用外部引用。 - Wim Coenen
5个回答

3
您可以使用svn:externals来处理此问题。这是一个指向svn存储库中某个位置的url 这使您可以拉取不同存储库(或相同存储库)的部分。一种使用方法是在project-for-client2下,您添加一个svn:externals链接到所需的基础设施分支、app1分支等。因此,当您检出project-for-client2时,您将获得所有正确的部分。
svn:externals链接与其他所有内容一起进行版本控制,因此随着project-for-client1的标记、分支和更新,将始终拉取正确的外部分支。

2

是的,这很糟糕。我们做同样的事情,但我真的想不出更好的布局。

所以,我们有一套脚本可以自动化处理所有与Subversion相关的事情。每个客户的项目都包含一个名为project.list的文件,其中包含构建该客户所需的所有Subversion项目/路径。例如:

Infrastructure/trunk
LibraryA/trunk
LibraryB/branches/foo
CustomerC/trunk

每个脚本大致都是这个样子:

for PROJ in $(cat project.list); do
    # execute commands here
done

命令可能是checkout、update或tag。虽然情况比这个复杂,但这意味着所有操作保持一致,checkout、更新和标记成为一个单一的命令。

当然,我们尽量少分支,这可能是我能提出的最重要的建议。如果我们需要分支,我们将尝试从主干或尽可能多的依赖的先前标记版本中工作。


2
一个建议是改变目录结构,从
  • 基础设施
    • 分支
    • 标签
    • 主干
  • 为客户1的项目
    • 分支
    • 标签
    • 主干
  • 为客户2的项目
    • 分支
    • 标签
    • 主干
  • 分支
    • 特性1
      • 基础设施
      • 为客户1的项目
      • 为客户2的项目
  • 标签
  • 主干
    • 基础设施
    • 为客户1的项目
    • 为客户2的项目
这种布局也存在一些问题。分支变得庞大,但至少更容易标记代码中的特定位置。
要使用代码,只需检出主干并使用它即可。然后您不需要脚本来检出所有不同的项目。他们只用 "../基础设施" 引用基础设施。此布局的另一个问题是,如果您想要完全独立地工作于项目,则需要检出多个副本。否则,对一个项目的基础设施的更改可能会导致另一个项目无法编译,直到该基础设施也得到更新。
这可能也使发布变得有些麻烦,并分离不同项目的代码。

2
首先,我不同意外部引用是邪恶的观点。虽然它们并不完美。
目前,您需要多次检出才能建立一个工作副本。如果您使用外部引用,它会自动地、一致地完成这个过程。
如果您将外部引用指向目标项目中的标签(和/或特定版本),则每个发布只需要对当前项目进行标记(因为该标记将准确指示您正在引用的外部引用)。您的项目中还将记录您何时更改了外部引用以使用特定库的新版本。
外部引用不是万能药——正如帖子所示,它们可能会出现问题。我相信有比外部引用更好的东西,但我尚未找到(即使在概念上)。当然,您使用的结构可以在开发过程中产生大量信息和控制,使用外部引用可以增加这些内容。然而,他遇到的问题并不是基本的损坏问题——干净的获取将解决所有问题,并且这种情况非常罕见(您真的无法在您的存储库中创建库的新分支吗?)。
需要考虑的要点——使用递归外部引用。我对此并没有完全认可或反对,而是采取务实的方法。
考虑使用像文章中建议的 piston,我没有看到它的实际操作,因此无法发表评论,但它可能以更好的方式完成与外部引用相同的工作。

0

根据我的经验,我认为为每个单独的项目建立一个代码库更有用。否则,你会遇到你所说的问题,此外,如果其他项目发生变化,修订号也会发生变化,这可能会令人困惑。

只有当单个项目之间存在关联时,例如软件,硬件原理图,文档等,我们才使用单一代码库,因此修订号可用于将整个包裹置于已知状态。


1
将每个项目的修订号设置为唯一值并不是选择某种方式的好理由。它只是一个数字,它所承载的唯一含义就是较小的数字比较大的数字旧。项目的修订号中有间隔根本无关紧要。 - nickf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接