4

A 在 SVN 存储库中有一个大项目。我想在其他应用程序中使用该项目的一些模块,所以我考虑从我的主 SVN 存储库中签出它们,以便我可以更新我的代码。

如何“导出”我的存储库的一个文件夹/模块,以便仅将该模块签出到其他项目?我想要包含该模块的其他项目也在他们自己的 SVN 存储库中。

在简历中,我希望能够对主仓库进行 SVN 更新,但对项目仓库进行提交。

我希望它清楚我想要做什么。

回应 DavidW anwser:

  • 我有一个包含多个项目的存储库,但如有必要我可能会更改它。
  • 我想提供源代码。它是一个 php 项目。我正在分叉模块。(我有一个全球通用项目,如果我的
    客户需要一些特定的功能,
  • 我想为该客户创建一个单独的项目(在 svn 中也分开)。但我想
    有一种方法将主项目中所做的一些更改合并到
    客户端项目中。(例如:全局错误修复或功能)。
4

2 回答 2

1

几个问题:

  • 您是在谈论多个存储库,还是同一个存储库中的多个项目?
  • 如果你借用这个其他模块的代码,你是让它与那个模块保持同步,还是你在分叉那个模块?
  • 真正想分享什么?您是否必须共享源代码或编译后的输出(*.so*.a在 Unix C/C+、*.jarJava 等中)。

你给出的答案很大程度上取决于你对这些问题的回答。

让我们假设代码实际上是共享的。你在一个中所做的就是你希望在另一个中完成的。您在项目中进行了更改,其他项目中的代码也会更改。

在这种情况下,使用svn:externals. 这是您放置在目录上的属性。它所做的是将 Subversion URL 与子目录名称相关联。例如:

$ svn propset svn:externals "http://svn.vegibanc.com/svn/trunk/project/stuff utils" .

将属性放置在当前目录中。当您进行更新或签出时,utils将在您的项目中创建一个名为的目录,Subversion 将自动签http://svn.vegibanc.com/svn/trunk/project/stuff出到该目录。这是魔法,但就像所有魔法一样,它既有光明的一面,也有黑暗的一面。

首先是光明的一面:

这是在两个项目之间共享代码。您在utils目录中进行更改并提交更改,其中的stuff子目录project将被更新。我用它在我的项目中构建工具。如果我升级该工具,所有项目都会获得升级后的工具。

现在,黑暗的一面:

如果你svn:externals像我展示给你的那样定义,你会后悔的。想象一下,如果您决定将工作分支以发布。好吧,您的目录utils仍然指向trunk. project/stuff如果您为 2.1 版分支,并且主干现在在 2.2 上工作,那么您将获得utils您不想要的东西。

更糟糕的是,如果您创建一个标签,该标签将继续更改,因为utils主干中的该目录仍在更改。

因此,强烈建议您指定 URL 的确切版本:

$ svn propset svn:externals "-r23283 ^/trunk/project/stuff@23283 utils" .
$ svn propset svn:externals "^/tags/2.3.3/project/stuff utils" .

首先,我指的是 URL 的特定修订。它是完全不变的。如果我需要将它指向另一个修订版,我需要更改svn:externals属性本身。

第二个是指向一个特定的标签。它不安全,因为标签可以更改,但我可以通过这种方式将我的外部依赖项视为发布。我正在使用 2.3.3 版的东西实用程序。

两者都使用^快捷方式,这只是意味着Subversion Repository Root。这样,如果您将 Subversion 存储库移动到另一个系统,或者从 更改httpsvn,您的外部存储库仍然可以工作。当然,如果你这样做,你将永远无法更改svn:externals. 而且,这不是你想要的。

您也可以使用相对URL,但它们更危险。

想象一下你的两个项目是这样的,你想让stuff目录成为utilssvn:external目录的链接:

http://svn.vegibanc.com/svn/trunk/project/foo/stuff
http://svn.vegibanc.com/svn/trunk/project/bar/utils

项目一起分支并标记在一起。你可以这样做:

$ co http://svn.vegibanc.com/svn/trunk/project/bar bar-trunk
$ cd project-bar
$ svn propset svn:externals "../foo/stuff utils" .

这会将stuff目录从外部链接到您的utils目录。但是,它是以相对的方式完成的。如果你这样做:

$ cp http://svn.vegibanc.com/svn/trunk http://svn.vegibank.com/svn/branches/2.3

您的utils目录仍将外部链接到 foo 项目下的stuff目录,但它们都将位于 2.3 分支上。

更改代码bar/utils将更改代码,foo/stuff反之亦然。您仍在共享代码,但在某种程度上,两个项目仍在同一个分支中。

稍后,如果您像这样标记:

$ cp http://svn.vegibank.com/svn/branches/2.3 http://svn.vegibank.com/svn/tags/2.3.0

您的标签 2.3.0 不太可能更改,因为外部链接及其链接的内容都包含在该标签中。

以上假设您正在共享代码,并且任何一个项目中的更改都会影响另一个项目。

更好的方法是foo创建可以存储在发布服务器上的某种编译对象(如 JAR 文件或 *.so)。您将此编译对象视为具有自己的版本控制的自己的项目,并且您的项目将依赖于该对象的特定版本。不幸的是,这并不总是有效。

如果您只是分叉代码,请svn cp从存储库中的一个位置到另一个位置。您可以在不影响其他项目的情况下进行更改,反之亦然。更好的是,您可以在两个位置之间来回合并更改,以使它们保持同步。

希望这能回答你的问题。如果您可以扩展您的问题并向我们提供有关您想要的更多详细信息,我将能够更新我的答案。

于 2013-04-11T13:34:34.173 回答
1
  • 如果你想在 Subversion 存储库中使用共享代码 - 它是 svn:externals
  • 如果您希望将共享代码上的主线端口更改为特定于客户的共享代码版本 - 它是 svn lingo 中的“供应商分支”

结合a)和b)将为您提供所需的结果

  1. 选择一些节点(客户存储库的外部主干),您将链接到 dev-repo 中的共享节点
  2. 创建外部定义(首选 PEG 修订,如果在提交到 dev-repo 后您必须轻松地收回手动更新定义的成本)
  3. 将节点复制到该位置,其中 in 必须在实时项目中 ( svn cp ...)
  4. 代码...
  5. 当您在 dev-repo 中进行更改时,您希望将其转移到客户 repo - 将外部更新为所需的修订,将“供应商”节点合并到“实时”

样本:

如果您在客户的仓库中有

  • /vendor/lib(其中 lib 是来自国外 repo 的目录)*/trunk/common/lib(上面的 lib 的客户版本)

合并来自 lib-mainline 的更改是从 /vendor/lib 合并到 /trunk/common/lib (在您的主干的工作副本的相应节点中)

大卫关于外部的笔记仍然有效、正确和有用

于 2013-04-11T20:12:48.400 回答