我们目前正在考虑从CVSNT转移,很可能转向Subversion(因为我们已经在使用trac,它已经为SVN集成做好了充分的准备)。由于我们一直在广泛使用一些不太常见的CVS(NT)特征,因此很早就出现了一些问题。这只是第一个。
以下是该方案: (对于不耐烦的人:我的实际问题是在水平标尺下面这篇文章的最底部。)
我们所有的“项目”都有一些共同的代码。 CVS存储库中的目录层次结构看起来有点像这样(简化 - 希望不会太多):
...例如,ProjectA可能依赖于Lib1,Lib2,ExtLib1和ExtLib2以及依赖于Lib1和ExtLib1的ProjectB(实际上这可能是因为Lib1本身依赖于ExtLib1)。我们使用CVSROOT/modules
文件建模,如下所示:
ExtLib1Full -d Lib/ExtLib1Full External/ExtLib1
ExtLib1Src -d Lib/ExtLib1/Source External/ExtLib1/Source
ExtLib2Full -d Lib/ExtLib2Full External/ExtLib2
ExtLib2Src -d Lib/ExtLib2/Source External/ExtLib2/Source
Lib1 -d Lib/Lib1 Libs/Lib1
Lib1_WDeps -a ExtLib1Src Lib1
Lib2 -d Lib/Lib2 Libs/Lib2
Lib2_WDeps -a Lib2
ProjectAMain -a ProjectA
ProjectALibs -a Lib1_WDeps Lib2_WDeps ExtLib2
ProjectAFull -a ProjectAMain ProjectALibs
ProjectALibs_OursOnly -a Lib1 Lib2
ProjectAFull_OursOnly -a ProjectAMain ProjectALibs_OursOnly
ProjectBMain -a ProjectB
ProjectBLibs -a Lib1_WDeps
ProjectBFull -a ProjectBMain ProjectBLibs
ProjectBLibs_OursOnly -a Lib1
ProjectBFull_OursOnly -a ProjectBMain ProjectBLibs_OursOnly
对于ProjectA的构建,构建服务器现在只需要检查名为“ProjectAFull”的虚拟模块,以获得该特定构建所需的所有相互依赖的模块 - 甚至创建编译器所支持的目录结构(即外部和内部库都放在一个普通的“Lib”父文件夹下面。同样,当我们想要标记包含所有依赖项的版本时,我们只需使用cvs rtag -rTagName ProjectAFull
。在生成ChangeLog时,我们将使用cvs rlog ProjectAFull_OursOnly
的输出,以便不让来自外部库(我们使用cvs import
和供应商分支维护)的提交消息污染ChangeLog。
SVN中是否存在这些虚拟模块的等价物?我应该如何在新的SVN存储库中设置目录结构以适应这种情况?每个项目和库是否应该成为自己的SVN项目(即具有自己的“主干”,“标签”和“分支”文件夹)或者我应该简单地导入现有的目录结构?如何定义依赖关系?
我非常希望继续能够执行仅影响相关模块的单步标记/结账/日志操作。
答案 0 :(得分:4)
你应该看看SVN Externals,但请注意,我不确定我是否理解你在使用CVS做什么,因为我多年没有使用过CVS。
基本上,外部引用意味着您可以在项目下创建一个子目录,并将另一个项目签入其中。
基本上,您可以获得此布局:
ProjectA - svn://server/ProjectA
classes (svn://server/ProjectA/classes)
app (svn://server/ProjectA/app)
externals (svn://server/ProjectA/externals)
Ext1 - svn://server/Ext1
classes (svn://server/Ext1/classes)
Ext2 - svn://server/Ext2
说明: - svn:// ...是我签出的网址,(svn:// ...)是该目录的相对网址,但它是母项目目录结帐的一部分。
请注意,外部引用作为属性添加到“externals”目录中,并作为ProjectA的一部分提交到存储库中。添加这些属性,更新或新结账后,将自动下载Ext1和Ext2作为正常结帐的一部分。
但是,这将为您提供工作文件夹中的工作文件夹,并且您需要提交更改并分别对其进行分支/标记。 Subversion不允许您对所有这些工作副本进行修改,并且只需一步完成它们。
换句话说,如果为了向项目中添加一个功能,你可以在ProjectA / classes中更改一些文件,然后在Ext1 / classes上添加一些框架支持,你必须执行两个提交,一个用于Ext1一个是ProjectA。
如果你想要一个实例,这里是我的C#类库的子目录:http://vkarlsen.serveftp.com:81/LVK/LVK_3_5/trunk/LVK.UnitTests
要检查该目录,您需要指定用户名和密码,两者都应该是“guest”而不带引号。
我的类库单元测试项目中的外部引用包括“SigningKey”目录(检查主目录上的subversion属性),以及“libs”子目录的内容(检查libs上的subversion属性)。正如您所指出的,当您检查单元测试项目时,它会删除所需的其他所有库,除了它测试的项目。
但是,如果我现在添加一个单元测试,并同时更新SQLite库文件的版本,我需要做2次提交。一个是将新的SQLite文件放入存储库,因为它是一个单独的项目/工作文件夹,另一个用于将新的单元测试放入存储库。
答案 1 :(得分:2)
你看过SVN externals了吗?它们似乎就是你要找的东西。
答案 2 :(得分:-1)
如果您正在进行更改,请不要忘记查看Mercurial或Git。毕竟,未来是DVCS。
编辑:围绕DVCS存在很多无知,这可以通过对此评论的低票来证明,但我坚持我的建议,因为问题表明正在考虑源控制迁移并且Subversion是一个候选人。我担心我不得不在这艘船上下船。我意识到很多svn用户仍然对Linus Torvalds表示这是有史以来最无意义的项目(on camera),但是除了侮辱之外,DVCS的优点已经足够强大,可以看到采用Mercurial像Mozilla,Google Code和其他人一样。即使是Subversion项目的作者acknowledge,也有越来越多的项目无法从颠覆dvcs中受益。