一些问题:
- 您是在谈论多个存储库,还是同一存储库中的多个项目?
- 如果您“借用”另一个模块的代码,您是否会将其与该模块保持同步,还是会分叉该模块?
- 您真正想要分享什么?必须分享源代码还是已编译的输出(Unix C/C+中的
*.so
或*.a
,Java中的*.jar
等)。
您给出的答案严重取决于这些问题的答案。
让我们假设代码实际上是共享的。您在一个项目中所做的就是您希望在另一个项目中完成的工作。您在您的项目中进行更改,其他项目中的代码也会更改。
在这种情况下,请使用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
目录中进行更改并提交更改,
project
中的
stuff
子目录将被更新。我用它来构建工具到我的项目中。如果我升级了工具,则所有项目都会获得升级后的工具。
现在是黑暗面:
如果您按照我展示的方式定义
svn:externals
,您将会深刻地后悔。想象一下,如果您决定为一个版本创建分支,那么您的
utils
目录仍然指向
project/stuff
的
trunk
。如果您为2.1版本创建分支,而trunk现在正在处理2.2版本,那么您将会得到一些您不想要的
utils
内容。
更糟糕的是,如果您创建了一个标签,那么该标签将继续更改,因为trunk中的
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
属性本身。
第二种情况是指向特定标记。这不太安全,因为标记可能会更改,但是我可以将我的外部依赖项视为发布。我正在使用
stuff实用程序的2.3.3版本。
两者都使用
^
快捷方式,它仅表示
Subversion Repository Root。这样,如果您将Subversion存储库移动到另一个系统,或从
http
更改为
svn
,您的外部将仍然有效。当然,如果您以这种方式进行操作,则永远无法更改
svn:externals
下的代码。而且,这并不是您想要的。
您也可以使用
相对 URL,但它们有点危险。
假设您有两个项目,您想将stuff目录作为svn:external
链接到utils目录:
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
从存储库中的一个位置复制到另一个位置。您可以在不影响其他项目的情况下进行更改,反之亦然。更好的是,您可以在两个位置之间来回合并更改,以使它们保持同步。
希望这回答了您的问题。如果您能扩展您的问题并给我们更多细节,我将能够更新我的答案。
svn:externals
。那么问题是什么?请参阅相关文档:http://svnbook.red-bean.com/en/1.7/svn.advanced.externals.html 和 http://tortoisesvn.net/docs/release/TortoiseSVN_en/tsvn-howto-common-projects.html#tsvn-howto-common-externals - bahrep