不同项目中使用不同的svn仓库进行代码管理

8

首先,我想告诉你我的系统是什么,并希望在此基础上进行构建。

1- A Solution (has)
   a- Shared Class Library project (which is for lots of different solutions)
   b- Another Class Library project (which is only for this solution)
   c- Web Application project (which main part of this solution)
   d- Shared Web Service project (which also serves for different solutions)

2- B Solution (has)
   a- Shared Class Library project (which is for lots of different solutions)
   c- Windows Form Application project (which is main part of this solution)
   d- Web Service project (which also serves for different solutions)

我正在使用xp-dev.com作为我们的svn仓库服务器。我为这些项目打开了不同的项目(共享类库、Web服务项目、Windows表单应用程序项目、Web应用程序项目、另一个类库项目)。

当然,我想对所有这些项目进行版本控制。

我的第一个问题是,我应该将每个项目(一个解决方案)放在一个svn仓库中,以后获得它们的修订号吗?

还是应该将它们中的每一个放在不同的svn仓库中,并保留(记录)它们用于发布/部署每个解决方案的正确版本号?

如果我为每个项目(共享类库、Web应用程序、共享Web服务...)使用一个svn,如何在VS.2010中在真实的解决方案中关联正确的svn地址和版本? alt text

那么,你如何管理你的仓库和项目呢?

4个回答

7
我认为正确的解决方案是使用标签。我不认为将您的解决方案分散到不同的存储库中是一个好主意。建议将所有即使稍微相关的项目放在同一个存储库中,并使用标准的存储库布局,例如:

/branches
/tags
/trunk

将所有工作解决方案文件夹放在上述 /trunk 中。Trunk 可以包含您认为可管理的任意数量的项目/解决方案,甚至可以按项目类型进一步组织。我的一个 Trunk 文件夹是 /trunk/websites,我在其中保存了所有网站解决方案。

当您准备发布版本时,您可以使用“Branch/Tag”将您的 trunk 或部分 trunk 标记为该版本或构建版本,并将其转移到 /tags/ 中。这为您提供了记录发布说明的机会。

有关在 SVN 中进行分支和标记的更多信息(假设使用 Tortoise),请参见 TortiseSVN 文档中的 分支/标记

有关这些术语的更多信息,请参见 StackOverflow 中的 此问题

希望这对您有所帮助。我不知道您可能会在 SVN 主机方面面临哪些限制。这些建议是基于我在托管自己的 VisualSVN Server 存储库时的经验得出的。

我从 SourceSafe 到 SVN,花了一些时间才看到这种标准的价值,并开始使用这些实践方法。现在它们对我来说非常宝贵。


但是,当我在开发其他项目时需要添加新功能到我的共享dll项目中(这些项目与解决方案分开,有自己的存储库),主要项目的其余部分将不会拥有这些新功能。我希望保持每个项目都更新,但与主要项目兼容。 - uzay95
如果相关项目在另一个代码库中,这确实是一个问题。如果这些项目在同一个代码库中,您可以将它们一起标记。我的回答基于一个建议,即所有相关项目都在同一个代码库中。如果不可能,可能有一种被接受的方法来解决这个问题,比如使用svn:extern(参见:http://svnbook.red-bean.com/en/1.0/ch07s03.html),但尽管我没有直接经验,我的印象是它只应该在必要时使用。 - Derrick

4
你可以采取的另一种方法是使用Subversion 外部资源属性来管理你的代码,无论是在单个仓库还是在分离的仓库中。优点是当你需要在解决方案中共享代码的新版本时,你只需简单地更新相关的URL即可。

注意: 我不记得Visual Studio解决方案和项目组织的任何内容了;自从我没有做过Windows开发已经有至少5年了。尽管如此,无论文件/目录布局如何,本文讨论都是适用的。我将虚构一个例子,请根据实际情况进行调整。

假设你有一个包含所有相关项目的大型仓库。如果你认为这并不一定可扩展,我建议你看看Apache projects SVN setup;他们所有的项目都在一个仓库里。借鉴ASF的方式,我们开始构建仓库结构,如下所示:

/SolutionA/trunk
/SolutionA/tags
/SolutionA/branches

/SolutionB/trunk
/SolutionB/tags
/SolutionB/branches

/SharedClassLib/trunk
/SharedClassLib/tags
/SharedClassLib/branches

/SharedWebService/trunk
/SharedWebService/tags
/SharedWebService/branches

到目前为止,这只是一个标准的SVN布局;每个相对独立的实体都有自己的存储库区域可供使用。现在,假设您一直在开发SharedClassLib,并且您已经达到了2.0.0版本,在SharedWebService上您的版本为1.2.5。目录布局将类似于:

/SharedClassLib/tags/1.0.0
/SharedClassLib/tags/1.5.0
/SharedClassLib/tags/2.0.0

/SharedWebService/tags/1.0.0
/SharedWebService/tags/1.2.0
/SharedWebService/tags/1.2.5

其他标签只是为了说明您的开发工作已经在不断进行并且您已经发布了多个版本。
现在,回到SolutionA,您有一个LocalClassLibrary项目和一个LocalWebApp项目。这些项目严格属于此解决方案,不与此解决方案之外的任何内容共享。尝试一下目录布局,您的主干可能如下所示:
/SolutionA/trunk/SolutionA/<some_solution_level_files>
/SolutionA/trunk/SolutionA/LocalClassLibrary/<some_project_level_files>
/SolutionA/trunk/SolutionA/LocalWebApp/<some_project_level_files>

所以,我们的问题是如何将SharedClassLib和SharedWebService放入SolutionA中?通过使用Subversion externals。首先阅读externals网页,然后回到这里。

为了让您的生活变得更加轻松,我建议在解决方案目录中创建一个svn.externals文件来设置svn:externals属性(如果您是从命令行执行此操作)。如果您使用其他工具,请记住,在这种情况下,您需要添加多行。该文件将如下所示:

SharedClassLib         http://your.svn.server/SharedClassLib/tags/2.0.0
SharedWebService       http://your.svn.server/SharedWebService/tags/1.2.5
编辑 1: 此时,您可以看到所引用的URL是完全限定的。这意味着它们可以是单独的存储库,您不必使用我在此处描述的布局。此外,如果您在开发的中间阶段,并且需要使用共享代码的最新开发版本,请使用类似于http://your.svn.server/SharedClassLib/trunk的URL。但是,在标记和发布解决方案之前,您最终会想要选择一个稳定版本的外部代码。 编辑 2: 请注意,这是1.5之前的svn语法。在1.5中已经有所改变。
在解决方案目录中执行svn propset svn:externals -F svn.externals .,然后执行svn commit && svn update。此时,svn将使用那些URL的内容填充您的工作副本。您的工作副本将类似于:
./SolutionA/svn.externals
./SolutionA/<some_solution_level_files>
./SolutionA/LocalClassLibrary/<some_project_level_files>
./SolutionA/LocalWebApp/<some_project_level_files>
./SolutionA/SharedClassLibrary/<some_project_level_files>
./SolutionA/SharedWebApp/<some_project_level_files>

当您需要引入共享项目的新版本时,请适当更新svn:externals属性。请注意,这种方法有一些注意事项,在SVN外部文档中有详细说明。主要是不要指望在./SolutionA/SharedClassLibrary中进行更改,并期望在提交SolutionA时自动捕获更改。
现在,您已准备好将SolutionA发布到世界上。只需创建相应的标签(svn copy)从主干到标签目录即可:
/SolutionA/tags/1.0.0

现在,您的解决方案A将在正确的标签/版本中拥有自己的代码,并且您正在使用该发布版本的共享项目的正确版本。显然,相同的讨论也适用于解决方案B。如果我上述内容有任何错误,请见谅,因为我已经有一段时间没有使用SVN了。

1

我的建议是将具有相同生命周期的项目放在同一个代码库中。

让我们以您的A方案为例。我们有:

  1. 共享类库项目(用于许多不同的解决方案)
  2. 另一个类库项目(仅用于此解决方案)
  3. Web应用程序项目(这个解决方案的主要部分)
  4. 共享Web服务项目(也为不同的解决方案提供服务)

这将使2和3成为同一解决方案的不同项目(因此具有相同的生命周期)的一个代码库:

/solution-A/trunk/ClassLib
/solution-A/trunk/WebApp
/solution-A/tags/1.0.0/ClassLib
/solution-A/tags/1.0.0/WebApp

假设它们具有不同的生命周期,一个存储库用于1,另一个用于4。

/library-A/trunk/ShClassLib
/library-A/tags/1.0.0/ShClassLib
/library-B/trunk/ShWebService
/library-B/tags/1.0.0/ShWebService

现在,根据开发人员正在处理的主题,他可以检出主干、标签(只读)或分支。例如,使用已发布库的“解决方案”上工作的开发人员将检出解决方案的主干和库的“正确”标签。需要库的下一个版本的开发人员将检出库的主干(或分支),等等。

当然,最好有一个能够提供二进制版本库以及每晚构建的构建/发布系统。


1
关于Visual Studio支持,实际上没有太多可说的,因为Subversion和Tortoise无法在Visual Studio内部使用。当你处理项目和解决方案时,你可能需要仔细考虑项目和解决方案设置是否会影响其他用户。例如,如果你的本地路径与存储库中的项目不同,你可能需要检出项目和解决方案文件并将它们永久保留在检出状态。
对于Web应用程序,web.config文件可能需要一些仔细的考虑,如果文件中有特定于机器的设置。例如,如果你正在运行IIS 7,并下载了一个使用IIS 6创建的项目,则项目文件可能会被更改,潜在地指向不同位置的系统模块和处理程序引用。或者你可能有一个连接字符串指向与原始web.config文件不同的服务器。在这种情况下,解决方案是首先下载文件,然后将文件保留在本地检出状态,并记住不要更新它。
我真诚建议将项目放入同一个存储库中;这样易于查找和备份。但是,在存储库中创建新分支并添加新文件时,需要记住以下关键事项:
- 首先在存储库中创建文件夹 - 只检出文件夹到本地文件夹 - 在资源管理器中使用Tortoise添加文件 - 提交更改
附注:
如果您喜欢在Visual Studio中进行源代码控制的集成,可以尝试使用VisualSvn,该工具可直接与TortoiseSVN集成。Visual SVN与现有的Subversion文件夹一起使用,因此不使用Visual Studio版本控制提供程序(在我看来是一件好事)。它与TortoiseSVN API通信并直接从文件存储库获取数据。我还没有长时间使用Visual SVN,但到目前为止它看起来很不错,虽然我已经习惯了使用资源管理器进行源代码控制,但有了这种集成也没有帮助显著提高效率。
其中一个明显更容易处理的事情是创建新项目 - 您只需使用“添加到Subversion”,VSVN会负责为您创建分支并检出文件。
在IDE中直接查看文件状态确实很好,而且如果您经常向系统添加新文件,VSVN也很好用,因为它知道Visual Studio文件关联并自动添加所有相关文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接