0

我在检查 svn 存储库中的标记版本时遇到了一些麻烦,很可能是因为内部的 'svn:externals' 没有引用正确的修订版。让我们考虑简化的情况:

我有第一个 svn 存储库,它在 XXX1 修订版中看起来像这样:

Repo1 (@ Rev XXX1)
  tags
    ...
  trunk
    Folder1
      ExternalRefToFolder2 (svn:externals '../Folder2')
    Folder2
      SomeFile1.txt
      SomeFile2.txt

并且已被重构为(在头部修订时):

Repo1 (@ HEAD1)
  tags
    ...
  trunk
    Folder1
      SomeFile1.txt
      SomeFile2.txt

IE:无论好坏,外部引用Folder2已被删除并替换为修订XXX1HEAD1.

我在同一台服务器上还有第二个存储库,如下所示:

Repo2 (@ HEAD2) 
  tags
    1.0.0
      ExternalToRepo1 (svn:externals -rXXX1 ^/../Repo1/trunk)
  trunk
    ExternalToRepo1 (svn:externals ^/../Repo1/trunk)

IE:同样,无论好坏,第二个存储库使用外部引用引用第一个存储库(标记版本HEAD1中的修订trunk和修订XXX1,以便将所有内容冻结在正确的修订中)。

问题

  • 当我签出trunkof 时Repo2,我没有问题。那是Repo1用它的单检出的Folder1

  • 当我检查 的标签1.0.0时,svn 抱怨它在修订Repo2时找不到。http://server//Repo1//trunk//Folder2HEAD1

因此,即使标签在其正确的修订版1.0.0中引用,它看起来也是如此;内部外部被解释为好像基于(而不是我所期望的修订)。Repo1/trunkXXX1svn:externals '../Folder2'HEAD1XXX1

这种行为是否正常,我该如何解决这个问题?

注意:我拥有的 Svn 版本是 2012 年 12 月 12 日编译的 1.7.8 (r1419671)

编辑

重现问题的另一种方法是签出或简单地浏览Repo1revision XXX1svn:externals '../Folder2'然后仍然是相对的,HEAD1所以猜测没有太多解决方案。

4

2 回答 2

2

乍一看,它看起来有点奇怪,但接下来你会发现它按预期工作。

SVN 为特定的提交集分配修订号,该提交集不仅可以包含更改,还可以包含通过 svn 副本创建的目录、文件、属性和链接(所谓的标签或分支)的添加或删除。SVN 并没有真正复制来自文件系统的目录,而是将其内容链接到一个新目录。当所有链接(原始目录和复制目录)都被删除时,内容会在 SVN 历史的深处“暂停”(但实际上并未删除)。您可以随时更新到最后一个修订版已包含该目录的最后链接内容。

外部就像您可以设置到外部存储库的链接,但与始终由同一存储库维护的链接相反,外部内容实际上不能“暂停”,因为它是从另一端控制的,来自包含外部内容的存储库. 换句话说,存储库包含一个外部链接,并且存储库存储了一个内容,因为它可以维护完全不同的地址并位于不同的机器上。

这就是为什么在您必须为外部设置正确的修订号时会发生什么样的错误,否则外部链接将采用最后一个,即 HEAD。当内容已经不存在时,您的 ExternalRefToFolder2 会进行头部修订。明确设置外部修订版或使用 svn copy。

但请记住,svn copy 创建链接但有它自己的内容历史。这意味着对链接到修订版 Folder2 的所有提交都不会通过链接到修订版 ExternalRefToFolder2/Folder2 更改内容,反之亦然。

所以嵌套链接和外部的工作方式相同。这只是另一个级别的参考。您必须为所有外部设置(并提交相关属性)特定修订,以便从根获取确切的目录树结构/内容。

于 2016-10-11T01:16:15.990 回答
1

用作svn:externals穷人的依赖管理或代码重复避免方案是您的麻烦之源。嵌套它们并不是双重的坏事,它是乘法的。我推荐这个关于外部不良的优秀长答案

使用内部的东西你永远不会有很好的结果svn:externals,但是如果你继续使用它们,你可以通过以下方式减轻痛苦:

  1. 听从红皮书的建议,永远不要在头脑中进行外部拉动:

您应该认真考虑在所有外部定义中使用明确的修订号。这样做意味着您可以决定何时提取不同的外部信息快照,以及准确提取哪个快照。除了避免对您可能无法控制的第三方存储库进行更改而感到意外之外,使用明确的修订号还意味着当您将工作副本回溯到以前的修订时,您的外部定义也将恢复到它们的外观在之前的版本中,这反过来意味着外部工作副本将被更新以匹配它们在您的存储库处于之前的版本时回顾的方式。对于软件项目,这可能是复杂代码库旧快照构建成功和失败之间的区别。

  1. 如果您不执行上述操作,请使用svncopy.pl创建您的标签。当您创建标签时,它将“固定”您的外部版本的修订。

您没有提到为什么您有多个存储库 - 您是否有可能从整合中受益?
您没有提到您使用的语言/工具。我很确定有更好的方法可以满足您的要求。例如,如果它是一个带有一些库的 Java 应用程序,您通过外部引入 - 如果您单独构建库并使用类似 maven 的物质发布它们,然后在构建应用程序时解决它们,您会更开心。

于 2013-04-04T02:47:01.563 回答