您现在的位置是:首页 >  云笔记 >  开发随笔 >  文章详情

SVN开发过程中trunk、branches、tags的使用详解

admin   2019-04-20 22:26:53   1090人已围观

       在SVN中创建代码库时,通常会创建trunk、branches、tags三个子目录,今天就讲讲在日常开发过程中对这3个目录的使用:       

       trunk-主干,或称主线,顾名思义是开发的主线。
       branches-分支,是从主线上分出来,独立于主线的另一条线,可以创建多个分支,一个分支总是从主干一个备份开始的。在版本控制的系统中,我们经常需要对开发周期中的单独生命线作单独的修改,这条单独的开发生命线就可以称为Branches,即分支。分支经常用于添加新的功能以及产品发布后的bug修复等,这样可以不影响主要的产品开发线以及避免编译错误等。当我们添加的新功能完成后可以将其合并到主干中。
        tags-标记,主要用于项目开发中的里程碑,比如开发到一定阶段可以单独一个版本作为发布等,它往往代表一个可以固定的完整的版本。即主干和分支都是用来进行开发,而标记是用来进行阶段发布的。
        branches以及tags在TortoiseSVN中创建方法是一致的,它们都是通过存储类似Linux中的lunch快捷方式一样,只是创建了指向某个版本的链接,而不会真正将此版本的内容复制到分支或者标记中,这样既可以节省空间,也可以很快速的创建,被称为“廉价的拷贝”。

        关于代码管理的分支和发布策略,目前主要有两种:一种是主干作为新功能开发主线,分支用作发布。另一种是分支用作新功能开发,主干作为稳定版的发布。

       我这里用一个新的SVN目录来做测试,先将一个测试的代码工程提交到svn的trunk目录中,我先采用主干发布,分支开发的管理策略;分别介绍如何拉取分支(Branch)?如何合并(Merge)?如何打标记(Tag)?

第一步、创建分支

          将主干trunk签出(checkout)到本地,在本地checkout的trunk目录上单击鼠标右键,在弹出菜单中选择“TortoiseSVN” →“Branch/tag…”如下图:

在弹出框中配置分支目标地址:

上图中Create copy revision in the repository下的选项:
1、 HEAD revision in the repository:拷贝当前主干中的最新版本。不需要从你的工作副本中传输任何数据,这个分支的建立是非常快的。
2、 Specific revision in repository:拷贝主干中的某个指定版本。假如你在上周发布了项目时忘记了做标记,这将非常有用。如果记不起来版本号,通过点击鼠标右键来显示版本日志,同时从这里选取版本号。和上次一样不需要从你的工作副本中传输任何数据,这个分支建立起来是非常快的。
3、  Working copy:新的分支是一个完全等同于你的本地工作副本的一个拷贝。如果你更新了一些文件到你的工作副本的某个旧版本里,或者你在本地做出了修改,这些改变将准确无误地进入拷贝中。自然而然地这种综合的标记会包含正在从工作副本传输到版本库中的数据,如果这些数据还不存在的话。

       选择分支路径并且自己写一个分支名称,写上日志提交即可。再去分支下面更新一下就可以看见刚才新建的dev-v1.0,如下图:


第二步、合并

       合并的工作是把主线或者分支上合并范围内的所有改动列出,并对比当前副本的内容,由合并者手工修改冲突。如果当前工作副本是主线的,则合并的范围是分支上的改动,如果工作副本是分支的,则合并范围是主线上的改动。其中需要注意的是关于Merge Type中 Merge two different trees和 Merge a range of revisions这2个选项的选择。

     Merge a range of revisions这个选项:我们选中这个选项,然后点击“Next”,会看到如下界面,因为我们是要将分支(branch)合并到主干(trunk),所以这边URL to merge from选项要选择服务器上面需要合并到主干(trunk)的分支(branch)地址(注:合并是合并到本地的working copy,所以一般合并之前,最好将本地working copy代码先更新一遍,有冲突的解决冲突,并且将未提交的代码提交,以防在合并之后,未提交的代码丢失),这边有个Revision range to merge选项,当选择all revisions进行merge的时候,TortoiseSVN做了怎么样的操作呢?其实就是:diff and apply。diff是比较URL to merge from指定的工程最新一个版本和最初的一个版本的差异,假设最新版本是r-last,最初的版本r-first,r-last相对r-first而言,增加了文件a,修改了文件b,那么在合并的时候,就将“增加文件a,修改文件b”的操作应用在本地的working copy上面去,这就完成了合并;假设选择的是specific range,那么用户可以选择一个版本范围,也可以单独指定一个版本或者不填写任何值(此时相当于选all revisions),假设用户指定了版本r1-r3,其中r1新增了文件a,r2新增了文件b,r3删除了文件c,那么在合并的时候TortoiseSVN就会将“新增文件a,新增文件b,删除文件c”应用于本地的 working copy,这样就完成了合并~

    Merge two different trees这个选项:从它自己选项的解释来看,是将两个不同的分支(branch)合并到本地working copy中,当然,我们也可以用这个选项将分支(branch)修改的内容合并回主干(trunk)。选择Merge two different trees,点击Next上步之后,会出现如下对话框,注意,我们现在是将分支(branch)合并回主干(trunk),这个时候,我相信很多人想当然的认为Fom处填写的应该是分支(branch)的URL,而To,应该是主干(trunk)的URL,因为是从分支(branch)到主干(trunk)啊,然后事实并非如此!之前在创建分支(branch)这一节,有让读者记住拉取分支(branch)时,主干(trunk)的版本号,当时主干(trunk)的版本号是2,所以From处的URL应该写主干(trunk)的URL,Revision应该选2(其实trunk revision为2的版本,其实也就是branch的第一个版本,所以这边From可以选择主干拉取分支的版本,也可以选取分支最开始的版本),而To处的URL应该选分支的URL,Revision选HEAD Revision,也就是选最新的分支版本。现在就来说说为什么要这样填写:此处进行merge的时候,进行的操作也是diff and apply,将To处URL和revision指定的某个版本,与From处URL和Revision指定的某个版本进行对比,对比是有顺序的,这个怎么理解呢?比如现在To处的为工程project1,From处的为工程project,如果project1相对于project而言,有文件a,没有文件b,换句话说project1相对于project而言,“新增了a,删除了b”,那么此处merge的结果就是会将“新增a,删除b”的操作应用于本地working copy的工程,那为什么From处的project不能指定为最新的Revision呢,既HEAD Revision?试想一下,假如主干(trunk)在拉取了分支(branch)之后,主干(trunk)和分支(branch)都有在并行开发,那么必然主干(trunk)上会有新增的
功能,这样就会有新增的代码,这些代码在分支(trunk)上并不存在,在To和From比较过程中,就会出现“删除xxx”的操作,这在merge过程中会应用在本地working copy中,本来这个“xxx”是主干新功能的代码,在将分支合并过来的时候,不应该删除,所以不能用主干最新的版本和分支最新的版本做对比,应该是将当时拉取分支的时候的主干版本和当前最新的分支版本进行对比,应用到本地working copy中才对,所以这边的From必须选取当时拉取当前分支的主干版本,不然主干上面新增的代码会丢失。

第三步、打标记

   Tags即标签主要用于项目开发中的里程碑,比如开发到一定阶段可以单独一个版本作为发布等,它往往代表一个可以固定的完整的版本。SVN中Branches以及Tags经常容易混淆,因为在TortoiseSVN中创建方法是一致的,而且它们都是通过存储类似Linux中的lunch快捷方式一样,只是创建了指向某个版本的链接,而不会真正将此版本的内容复制到分支或者标签中,这样既可以节省空间,也可以很快速的创建。还有一点值得注意的是,SVN不推荐在创建的Tag基础上Revision,这种情况应用Branches,因为Tag一般保持不变不作任何修改。

第一步,在主干拉tag(我这里主干是最新的代码,分支是开发代码)

第二步、选择tag的存放目录和给tag命名:

提交后,去tag存放目录更新一下就可以看见刚才的tag版本了。




分享到:

编辑发布时间:2019-04-20 22:26:53