4

在我的公司,我们使用一个 SVN 存储库来保存我们的 C++ 代码。代码库由公共部分(基础设施和应用程序)和客户端项目(作为插件开发)组成。

存储库布局如下所示:

  • 基础设施
  • 应用程序1
  • 应用程序2
  • 应用程序3
  • project-for-client-1
    • App1-插件
    • App2-插件
    • 配置
  • 客户项目 2
    • App1-插件
    • App2-插件
    • 配置

客户项目的典型发布包括项目数据和它使用的每个项目(例如基础设施)。

每个目录的实际布局是 -

  • 基础设施
    • 分支机构
    • 标签
    • 树干
  • 客户项目 2
    • 分支机构
    • 标签
    • 树干

其他项目也是如此。

上面的布局有几个问题:

  1. 很难为客户项目启动一个全新的开发环境,因为必须检查所有涉及的项目(例如:Infrastructure、App1、App2、project-for-client-1)。
  2. 出于与上述相同的原因,很难在客户端项目中标记发布。
  3. 如果客户项目需要更改一些通用代码(例如基础设施),我们有时会使用分支。很难跟踪项目中使用了哪些分支。

SVN 有什么办法可以解决以上问题吗?我曾想过在客户项目中使用 svn:externals,但在阅读了这篇文章后,我明白这可能不是正确的选择。

4

5 回答 5

3

你可以用 svn:externals 来处理这个问题。这是 svn 存储库中某个位置的 url 这使您可以拉入不同存储库(或相同存储库)的部分。使用它的一种方法是在 project-for-client2 下,将 svn:externals 链接添加到所需的基础设施分支、所需的 app1 分支等。因此,当您查看 project-for-client2 时,您会得到所有正确的部分。

svn:externals 链接与​​其他所有内容一起进行版本控制,因此随着 project-for-client1 被标记、分支和更新,正确的外部分支将始终被拉入。

于 2009-09-10T13:36:24.150 回答
2

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

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

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

然后每个脚本看起来像这样:

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

命令可能是结帐、更新或标记。它比这要复杂一些,但这确实意味着一切都是一致的,签出、更新和标记成为一个命令。

当然,我们尝试尽可能少地分支,这是我可能提出的最重要的建议。如果我们需要分支某些东西,我们将尝试使用主干或尽可能多的依赖项的先前标记版本。

于 2009-09-10T12:56:57.497 回答
2

一个建议是从改变目录布局

  • 基础设施
    • 分支机构
    • 标签
    • 树干
  • project-for-client-1
    • 分支机构
    • 标签
    • 树干
  • 客户项目 2
    • 分支机构
    • 标签
    • 树干

  • 分支机构
    • 功能一
      • 基础设施
      • project-for-client-1
      • 客户项目 2
  • 标签
  • 树干
    • 基础设施
    • project-for-client-1
    • 客户项目 2

这种布局也存在一些问题。分支变得庞大,但至少在代码中标记特定位置更容易。

要使用代码,只需检查主干并使用它。然后,您不需要检查所有不同项目的脚本。他们只是用“../Infrastructure”来指代基础设施。这种布局的另一个问题是,如果您想完全独立地处理项目,则需要检查多个副本。否则,一个项目的基础架构更改可能会导致另一个项目在更新之前无法编译。

这也可能使发布变得更加繁琐,并将不同项目的代码分开。

于 2009-09-10T13:13:48.217 回答
2

首先,我不同意外在是邪恶的。虽然它们并不完美。

目前,您正在执行多个结帐以构建工作副本。如果您使用外部,它会完全做到这一点,但每次都是自动且一致的。

如果您将外部指向目标项目中的标记(和/或特定修订),则只需在每个版本中标记当前项目(因为该标记将准确指示您指向的外部)。您还将在项目中准确记录您何时更改外部引用以使用特定库的新版本。

外部不是万能的——正如帖子显示的那样,可能会出现问题。我确信有比外部更好的东西,但我还没有找到它(甚至在概念上)。当然,您使用的结构可以在您的开发过程中产生大量信息和控制,使用外部可以增加。然而,他遇到的问题并不是根本的腐败问题——一个干净的 get 可以解决所有问题,而且非常罕见(你真的无法在你的 repo 中创建一个新的库分支吗?)。

需要考虑的要点 - 使用递归外部。无论是或否,我都没有被出售,并且倾向于采用务实的方法。

考虑使用文章建议的活塞,我还没有看到它在行动,所以不能真正评论,它可能以更好的方式做与外部相同的工作。

于 2009-09-10T14:29:15.183 回答
0

根据我的经验,我认为为每个单独的项目都有一个存储库会更有用。否则,您会遇到您所说的问题,此外,如果其他项目发生变化,修订号也会发生变化,这可能会造成混淆。

仅当单个项目之间存在关系时,例如软件、硬件原理图、文档等。我们使用单个存储库,因此修订号用于使整个包处于已知状态。

于 2009-09-10T12:53:20.903 回答