5.2. 导入数据到版本库

5.2.1. 版本库布局

在将你的数据导入到版本库之前,首先你得考虑如何组织你的数据。如果你使用一种推荐的布局,你在后面的操作将会更容易许多。

有一些标准的、推荐的方式来组织一个版本库。大多数人建一个trunk目录来存放开发的“主线”、一个branches目录来容纳分支副本、以及一个tags目录来容纳标签复制。如果一个版本库只存放一个项目,人们通常创建三个这样的顶层目录:

/trunk
/branches
/tags

如果一个版本库包含多个项目,人们通常按分支来安排布局:

/trunk/paint
/trunk/calc
/branches/paint
/branches/calc
/tags/paint
/tags/calc

……或者按项目:

/paint/trunk
/paint/branches
/paint/tags
/calc/trunk
/calc/branches
/calc/tags

如果项目不是密切相关,而且每一个是单独被检出,那么按项目布局是合理的。对于那些你想一次检出所有项目,或需要将它们打成一个分发包的相关项目,按分支来布局通常比较好。这种方式你只要检出一个分支,而且子项目之间的关系也比较清楚。

如果你采用顶层/trunk /tags /branches这种方式,并不意味着你必须复制整个主线为分支或标签,而且某些情况下这种结构更具灵活性。

对于不相关的项目,你可能更愿意使用不同的版本库。当你提交时,改变的是整个版本库的修订号,而不是项目的。让两个不相关的项目共用一个版本库,会导致修订号出现较大的跳跃。Subversion和TortoiseSVN项目看起来是在同一个主机地址,但是它们是在完全独立的版本库中开发着,并且版本号也不相干。

当然,你完全可以不理会上面提及的通用布局。你可以自由改变,来满足你和你团队的需要。请记住,不管你选择哪种布局,它都不是永久的。你可以在随时重新组织你的版本库。因为分支和标签是普通的目录,只要你愿意,TortoiseSVN可以将它们移动或重命名。

从一种布局转换到另一种布局仅仅是在服务器端移动一些文件或目录;如果你不喜欢版本库的组织形式,仅管大胆地修改那些目录。

所以,如果你还没创建一个基本的文件夹结构到你的版本库中,你现在可以这样做:

  1. 在你的硬盘上创建一个空的文件夹

  2. 在那个文件夹下创建你想要的顶级目录--千万不要放任何文件进去!

  3. 通过在那个文件夹右键,选择TortoiseSVN导入... 将这个结构导入到版本库中。这将导入临时文件夹到版本库的根目录形成一个基本的版本库布局。

注意,你所导入的那个文件夹的名字并不存在于版本库中,仅仅是它所包含的内容。比如,创建如下结构的文件夹

C:\Temp\New\trunk
C:\Temp\New\branches
C:\Temp\New\tags

导入C:\Temp\New到版本库的根目录,版本库中将会是这样:

/trunk
/branches
/tags

你还可以使用版本库浏览器直接在版本库中创建文件夹。

5.2.2. 导入

在将你的项目导入到版本库之前,你应该:

  1. 删除所有构建工程不需要的文件(临时文件,编译器产生的文件,例如 *.obj,生成的二进制文件,...)

  2. 组织目录和子目录内的文件。尽管以后可能会改名/删除文件,我们还是建议你在导入之前使你的项目结构组织良好!

现在进入资源管理器,选择你的项目的顶层目录,右击打开上下文菜单。选择命令TortoiseSVN导入 ...,它会弹出一个对话框:

图 5.6. 导入对话框

导入对话框

在这个对话框中,输入你的项目导入到版本库的URL。

这个输入信息将用作提交日志。

默认情况下,匹配全局忽略模式的文件和文件夹不会被导入。你可以使用包含忽略文件检验栏来禁止此行为。参考第 5.27.1 节 “常规设置”以获得关于全局忽略模式的更多信息。

当你点击确认时,TortoiseSVN 会导入包含所有文件的完整目录树到版本库。如前所述,你导入的文件夹名称不会在版本库中出现,只有这个文件夹的内容会在版本库中出现。现在这个工程就存贮在版本库,被版本控制。请注意,你导入的文件夹没有被版本控制!你需要检出刚才导入的版本,以便获得受版本控制的工作目录。或者继续阅读,找到如何导入文件夹到合适的位置。

5.2.3. 导入适当的位置

Subversion 导入命令功能有限 - 你不能容易的选择导入的项目。而且,你导入的文件夹不会成为 Subversion 工作副本 - 你不得不单独做检出。但是不要担心,有其它方法克服这些缺陷 :-)

假定你已经有个版本库,你想给它增加一个新目录结构,只需以下步骤:

  1. 使用版本库浏览器直接在版本库中创建项目文件夹。

  2. 在你要导入的文件夹检出新目录。你会得到一个本地目录为空的警告。现在你有一个版本控制的顶级目录,含有未版本控制的内容。

  3. 在此受版本控制的文件夹上使用TortoiseSVN增加...增加部分或全部内容。你可以增加或删除文件,在文件夹上设置svn:ignore属性,或者你需要的其它修改。

  4. 提交顶级目录,你有一个新的版本树,一份从你已有目录创建的本地工作副本。

5.2.4. 专用文件

有时候你需要版本控制一个包含用户专用的数据。它意味着你有一个文件,每个开发者/用户都需要修改,一边满足他/她的本地配置。但是版本控制这样的文件是困难的,因为每个用户可能都要提交他/她的修改。

在这种情况下,我们建议使用模版文件。创建你个包含所有开发者需要的数据的文件,增加到版本库中,让开发者检出。然后,每个开发者创建一个副本,改名此文件。于是,修改这个文件不再是问题。

作为例子,你可以看看TortoiseSVN的构建脚本。它调用一个TortoiseVars.bat文件,它并不在版本库中。 只有TortoiseVars.tmpl在版本库中。TortoiseVars.tmpl是一个模版文件,每个开发者都需要创建一个副本,改名为TortoiseVars.bat。在这个文件中,我们增加了注释,所以用户知道他们需要编辑那些行,以便适应他们的本地配置,使其能工作。

于是为了不干扰用户,我们也将TortoiseVars.bat增加到它的父目录的忽略列表,也就是,我们设置了Subversion属性svn:ignore包含这个文件名称。这样,每次提交时它都不会作为没有版本控制的文件出现。

5.2.5. 引用的工程

有时候,构建一个需要不同检出的工作目录是很有用的。举例来说,你需要不同的子目录来自版本库的不同位置。,或者可能完全来自不同的版本库。如果你需要每个用户具有相同的目录结构,你可以定义svn:externals属性。

比如说,你检出了/project1D:\dev\project1。选择目录D:\dev\project1右击,选择Windows 菜单属性。出现属性对话框。在Subversion页,你可以设置属性。点击增加...。从组合框选择svn:externals属性,在编辑框按照名称 URL格式输入版本库URL,或者你需要一个指定的版本,那么使用名称 -r版本 URL。你可以增加多个外部工程,每行一个。注意,URL必须使用逃逸字符编码,不然可能无法正常工作。举例说明,你必须将每个空格替换为%20。注意使用包含空格的目录名称是不可能的。假设你为D:\dev\project1设置了这些属性:

sounds   http://sounds.red-bean.com/repos
quick_graphs  http://graphics.red-bean.com/repos/fast%20graphics
skins/toolkit -r21 http://svn.red-bean.com/repos/skin-maker

现在点击 设置,提交你的修改。当你(或其他用户)更新工作副本时, Subversion 将会创建子目录D:\dev\project1\sounds,并且检出sounds工程,另一个子目录D:\dev\project1\quick_graphs包含graphics工程,最后一个嵌套的子目录D:\dev\project1\skins\toolkit包含的skin-maker工程的版本21。

如果一个外部工程位于同一版本库中,当你向主项目提交你的修改时,你对外部工程做的修改也会包含在提交列表中。

如果外部工程位于不同的版本库,当你向主项目提交你的修改时,你对外部工程做的修改会被通报,但是你必须单独的提交这些外部项目的修改。

注意如果你修改了svn:externals属性中的URL,下次更新工作目录时,Subversion将会删除老的外部目录,重新检出副本,于是你将看到文件被增加而不是你期望的被更新。当你引用一个其它项目的标记时,这种情况就可能发生。即当那个项目发布新版本时,你将外部引用改为新的标记。

[提示]提示

你应当认真考虑在所有外部定义中使用确定的版本号。这样做意味着你决定下载一个快照,并且精确的指明了是哪个快照。与使用通常的分支相比,你不会为第三方版本库的修改感到惊讶,这些版本库你可能没有任何控制,使用精确的版本号能使你回溯工作目录到以前的版本,你的外部定义也遵循此规则,看起来是以前的版本,即外部工作副本的更新匹配他们的老版本。对于软件工程,它是你的复杂代码构建成功或失败的重要区别。

外部定义svn:externals中的URL是绝对路径。如果你重新定位工作副本,或者外部版本库重新定位了,这些URL不会自动更新。而且,如果你分支了一个工程,它的外部定义位于同一版本库中,分支中的这些URL也不会更新;你可能需要用对分支的引用替换对最新版本的引用。

如果你需要TortoiseSVN如何处理属性的更多信息,请阅读第 5.15 节 “项目设置”

如果你需要知道存取公共子个我我你工程的不同方法,请阅读第 B.6 节 “包含一个普通的子项目”.