说来惭愧,鄙人从事开发多年,使用svn已经好几个年头了,可是却仅限于update、commit、compare之类的操做,最近想到github上学习别人写的NIO源码,顺便去熟悉git的使用,可是一想到svn,我内心虚了:用了那么多年却对其只知其一;不知其二,就连最基本的权限分配都没有作过,更别说进行分支拉取和合并了,何谈去get其余技能?作技术的仍是要踏实一点,近一年来,我都在对以前未深刻的领域进行扫盲,因此,注定svn是绕不过的坎,因而乎开始各类查资料,安装svn服务端(Virtual SVN)和客户端(TortoiseSVN),比对网上的博文进行各类尝试,不能说过程痛苦,可是当你在云里雾里摸索的时候挺难受的吧(顺便说下,在学习的时候精力必定要集中!对我而言,顺便塞上耳塞听音乐工做效率是事半功倍,哈哈哈~)~不废话了,今天这篇博文就讲讲SVN里面比较高级的操做:建立分支(branch)、将主干(trunk)中的代码合并到分支(branch)、将分支(branch)中的代码合并到主干(trunk)中~html
说到分支和主干,我想很多coder也是比较少接触吧,毕竟不少时候,咱们想着的仍是如何赶进度~之因此出现分支和主干,就是但愿主干和分支两份代码能够各自进行独立的管理互不影响,在须要的时候再进行合并。试想这样一种场景:公司项目已经完成一个阶段的开发计划,这时候拉取一个branch专门用来测试以及BUG修复,而原先trunk上面的代码还能够继续往下开发,互不影响,等测试的branch问题修复以后,将这个branch“合并”回trunk。这样trunk和branch能够在互不干扰的状况下各自作本身的事儿,最后再进行整合,合并过程当中有可能会有冲突,这个并不麻烦,等出现冲突的时候自行百度,我相信大家能够解决的,若是仍是晕乎乎,欢迎加群交流~git
接下来我就来讲说如何建立分支(branch)、将主干(trunk)中的代码合并到分支(branch)、将分支(branch)中的代码合并到主干(trunk),首先说明一下笔者当前测试环境:github
准备工做(以上客户端服务端自行安装,除了安装路径看本身喜爱以外,其余都按照默认设置,点击“下一步”吧):服务器
1)建立repositoryapp
打开Virtual SVN,在左侧列表中,右键Repositories,新建一个repository,名字随意,格式笔者是选择FSFS,Repository Structure笔者选择Single-project repository******,这样方便后面的描述,为了测试的方便,在选择“Repository Access Permissions”的时候,选择全部人SVN的user都有访问这个repository的权限(user能够在Virtual SVN的左侧列表Users节点右键,进行新增)svn
2)Check out trunk目录到本地学习
首先复制刚刚新建的repository下trunk的SVN URL测试
在本机随意一个目录新建一个空目录,好比笔者在d盘新建了一个svntrunk的目录,而后右键=>SVN Check out,将trunk的svn地址复制到“URL of repository”那一栏,而后点击“OK”spa
3)在D:\svntrunk目录下新建一个目录(名称设为project),而后在新建的目录下新增两个text文件:1.txt(文件内容:111111),2.txt(文件内容:222222),而后右键这个project目录,先Add,而后进行commit:.net
4)建立分支(branch)(唠叨一下,分支是建立在SVN服务器的repository中,而merge是合并在开发者本地)
右键D:\svntrunk\project文件夹,选择TortoiseSVN->Branch/tag,在弹出的对话框中,To path输入分支存放在repository的相对目录,这边注意:project01不能先建立,否则会报project01已经存在,不能建立分支!在log message中输入建立分支的日志,这对后续了解这个分支建立的目的有必定意义。在log message输入栏下面,还有一个Create copy in the repository from的选项,这个选项的目的是为了让开发者选择用哪份源码做为建立的版本 ,第一个是trunk中最新的版本,第二个用户能够选择trunk中指定的版本(经过序号标识),第三个是将工做拷贝做为建立分支的版本
上步点击OK以后,建立分支完成,就是这么简单,如今请先记住,咱们是以trunk中版本序号是2的工程做为建立分支的版本,这个对后续的合并有意义~(这边顺便说下,在一个repository,版本号是一个全局资源,不论是trunk、branch仍是tag,他们使用的版本号不会重复,好比如今trunk已经用掉2这个版本号,那么分支就只能往下一个,用3)
5)分支(branch)中的代码合并到主干(trunk)
首先,就像以前将主干(trunk)Check out到本地同样,将svn服务器上面的分支(branches)Check out到D盘svnbranches目录:
如今假设主干(trunk)和分支(branche)并行开发,主干(trunk)project下1.txt的文件内容改成121212,分支(branch)中project1下面增长一个3.txt文件,文件内容为:333333
右键主干中project文件夹,选择TortoiseSVN->Merge,这时会弹出一个Merge type让你选(TortoiseSVN1.9.5这个版本只有两个选项,网上有些博文有三个选项),Merge type的选择仍是颇有讲究,而且也是很容易搞错的,下面会具体来讲说:
咱们先来讲说“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,这样就完成了合并~
(ps:这边还有一个Reverse merge复选框,恢复以前的合并。假设咱们刚刚作的merge有问题,须要将本地的working copy恢复成merge以前的,那么就须要将以前应用于本地working copy的操做所有回退,操做和merge基本同样,只是最后,须要复选这个Reverse merge复选框)
上步选择了Revision range to merge以后,点击“Next”,进入以下界面,这时咱们就能够看到以下界面:
所有使用默认的选项,而后在点击Merge以前,能够先点击Test merge按钮,测试一下merge以后的效果:
如上图所示,分支(branch)版本新增的3.txt文件最终会合并到本次working copy中,最后将本地working copy中的3.txt提交到svn中,这样就完成了分支到trunk的合并了~
咱们再来讲说这个“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必须选取当时拉取当前分支的主干版本,否则主干上面新增的代码会丢失,以前我对From和To的顺序,以及revision的选取也是迷糊了大半天,我但愿对读者而言,我这边已经说清楚了~若是还有什么不清楚的欢迎加群交流~
上步以后,点击Next,进入下面这个页面,一样,在最终merge之时,点击Test merge
点击Test merge以后,能够看到最终合并以后的效果
6)主干(trunk)中的代码合并到分支(branch)
这边的操做和分支(branch)合并到主干(相似),须要注意的是,Merge type若是选择“Merge a range of revisions”,那么范围的起始版本应该为拉取分支时的主干版本,结束版本应该为trunk最新的版本;若是选择“Merge two different trees”,那么From必须是选取拉取分支时的主干的版本,或者分支的第一个版本,To必须是主干最新的版本
最后总结一下:无论选取哪一个Merge type,都能完成主干到分支、分支到主干的合并,须要注意的是,在选择“Merge two fifferent trees”时From和To对应的URL所表明的含义(5)分支(branch)中的代码合并到主干(trunk)这一节有讲),而且须要了解合并的原理,那么拉取分支和合并的操做并非什么难事。若有什么疑问,请加群交流~
一、http://blog.csdn.net/zhuyong0722/article/details/8965095
二、http://blog.csdn.net/wjtxt/article/details/8623262
三、http://www.cnblogs.com/firstdream/p/5632296.html
为方便没有博客园帐号的读者交流,特地创建一个企鹅群(纯公益,非利益相关),读者若是有对博文不明之处,欢迎加群交流:261746360,小杜比亚-博客园