几个问题:
- 您是在谈论多个存储库,还是同一个存储库中的多个项目?
- 如果你借用这个其他模块的代码,你是让它与那个模块保持同步,还是你在分叉那个模块?
- 你真正想分享什么?您是否必须共享源代码或编译后的输出(
*.so
或*.a
在 Unix C/C+、*.jar
Java 等中)。
你给出的答案很大程度上取决于你对这些问题的回答。
让我们假设代码实际上是共享的。你在一个中所做的就是你希望在另一个中完成的。您在项目中进行了更改,其他项目中的代码也会更改。
在这种情况下,使用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 存储库移动到另一个系统,或者从 更改http
为svn
,您的外部存储库仍然可以工作。当然,如果你这样做,你将永远无法更改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
从存储库中的一个位置到另一个位置。您可以在不影响其他项目的情况下进行更改,反之亦然。更好的是,您可以在两个位置之间来回合并更改,以使它们保持同步。
希望这能回答你的问题。如果您可以扩展您的问题并向我们提供有关您想要的更多详细信息,我将能够更新我的答案。