自由开源的本管理系统.ppt
自由、开源的版本管理系统,南京大学软件学院2009,1,1 Subversion简介2 版本控制的基本原理3 Subversion基础4 Subversion基本工作流程及基本操作CheckOut,Commit,Update,Status5 Subversion高级操作Branch/Tag,Merge6 Subversion其他操作(演示)7 常见Subversion的GUI客户端使用(演示),内容简介,1 Subversion简介,Subversion的作用Subversion的历史Subversion的特性Subversion的架构,Subversion的作用,一个自由,开源的版本控制系统一个通用系统,不是简单的一个SCM系统以替代CVS为目标可以管理任何类型文件,并且追踪变更不具有某些和开发紧密结合的特性,如支持某种特定的编程语言,集成构建工具等应用:版本管理,网络硬盘?网址:http:/subversion.tigris.org,Subversion的历史,2000年,CollabNet公司开始寻找CVS的替代产品2月,这个公司联系了Open Source Development with CVS的作者Karl Fogel,他同意为这个项目工作。同时,他还联系了其他几个人一起开发这个新系统3月,Subversion开始详细设计和编码2001年8月31日,Subversion第一个完整版本问世经过1.0,1.1,1.2直到现在的1.4.3版,Subversion的特性(和CVS比较),和CVS的相似性目录的版本化更加好的文件版本管理(例如对文件拷贝,重命名的处理)提交的原子性元数据的版本化可选的网络层对文本文件和二进制文件一致的差异比较算法高效的分支(branch)和标签(tag)操作良好的可维护性,Subversion的架构,2 版本控制的基本原理,客户/服务器架构的版本控制简述版本控制的数据共享模型数据共享的问题锁定-修改-解锁方案拷贝-修改-合并方案冲突及解决两种方案的对比及选择Subversion的实现,客户/服务器架构的版本控制,版本库(Repository):按照一定格式存储了所有数据,包括文件和目录经过授权的客户端可以连接到版本库,读写库中的文件版本库和普通文件服务器的不同:版本库会记录每一次的更改,所以,客户端可以任意查询更改的历史。例如:ApplicationContext.java的1451版和1450版相比修改了什么?谁作的修改?什么时候作的修改?等等,版本控制数据共享模型,版本控制系统的核心任务:协作编辑和数据共享基础问题:怎样允许用户共享信息,并且不会因意外而互相干扰?数据共享问题的产生解决办法,数据共享问题,解决方案1锁定-解锁方案,锁定-解锁方案的问题,可能导致管理问题,如长期锁定文件不放会导致不必要的顺序开发可能导致死锁例如Sally和Harry都需要修改plugin_mgr.c和plugin_mgr.h,两者互相关联,Sally锁定了.c文件而Harry锁定了头文件,就会进入死锁状态,解决方案2拷贝-修改-合并方案,(续图),冲突(Conflict)及解决(Resolve),冲突的产生:冲突是随着拷贝-修改-合并方案的产生而带来的问题。两个开发者使用拷贝-修改-合并方案编辑同一个文件,并且两人的修改发生了交叠时就发生了冲突冲突的解决:当冲突发生时,开发者会看到一对冲突的修改结果,通常情况下,必须让引起冲突的两个人商议之后,手动选择保留一组更改。在这里,版本控制系统只能提示冲突的发生而无法给出解决建议冲突的预防:增加开发者的交流可以最大限度减少冲突的发生,但是不可能杜绝冲突后面可以看到冲突的具体例子以及解决办法,两种方案的对比及选择,虽然锁定-解锁方案有很多的弊端,但在一些情况下仍然是必须的;虽然拷贝-修改-合并模型能解决大多数问题,但它也不是万能的比较:文本文件和二进制文件的特点选择:拷贝-合并模型假定文件是可以通过上下文合并的。通常情况下,文本文件(例如源代码以及用纯文本,HTML,TeX等格式保存的文档)因为其内部结构直观可知,容易理解上下文,所以用拷贝合并方案较好。而二进制文件(例如用Microsoft Word格式,PDF等格式保存的文档及图片,声音,可执行文件,库等)内部结构复杂,且不容易理解更改处的上下文,采用锁定-解锁方案较好,Subversion的实现,Subversion主要采用拷贝-修改-合并模型,配合锁定-解锁模型管理数据的共享,3 Subversion基础,基本概念工作拷贝(Working Copy)修订版本(Revision)文件状态混合修订版本的工作拷贝,工作拷贝(Working Copy),工作拷贝是本地机器的一个普通的目录。这个目录的内容是版本库中某个目录的拷贝。工作拷贝是私有工作区,可以任意编辑里面的文件并且发布更改通常,一个工作拷贝对应于版本库的一个子目录,日常的开发是针对工作拷贝进行的工作拷贝里面还有一些由Subversion创建和维护的额外文件,用于命令的协助执行,所以它们又叫工作拷贝管理目录。通常,它们都保存在工作拷贝目录及子目录下的.svn目录(隐藏)中,凭借这个目录中保存的信息,Subversion可以识别哪一个文件被修改了,哪一个文件已经过时了,等等,修订版本(Revision),SVN的提交(Commit)操作是把工作拷贝的更改发布到版本库的一个原子操作。每当一次提交完成后,版本库的文件系统就进入了一个新的状态,叫做一次修订(Revision),每一次修订都会赋予一个独一无二的版本号,一般是从0开始的递增自然数,一个比一个大初始修订版本是0,这只是一个空目录,没有任何内容。随着每次的提交,版本库里仿佛就多了一个当前内容的“快照”。在版本库中,最新的一个修订版本称为HEAD,修订版本(图示),(HEAD),文件状态,对于工作拷贝的每一个文件,SVN在管理目录(.svn)记录两项关键的信息该文件作为基准的修订版本(叫做文件的工作修订版本)该文件最后更新的时间戳根据以上两项关键信息,通过和版本库通讯,SVN可以得到工作拷贝中一个文件的状态,它有下面几种可能未修改,并且版本库也未修改(Up-to-date状态)已修改,但是版本库没有修改(Modified状态)未修改,但是版本库已经修改已修改,并且版本库也已修改(需要合并)可以用svn status命令查看文件状态,混合修订版本的工作拷贝,很灵活,但是比较难理解的一个特性混合修订版的工作拷贝:为了灵活,允许一个工作拷贝中存在多个修订版本的文件SVN特性:修订版本号的全局性。如果某文件的修订号为N,并不意味这这个文件被提交了N次(甚至有可能这个文件只修改过1次),而意味着整个版本库被提交了N次当一次Checkout或者(整个工作拷贝的)Update操作完成后,工作拷贝中所有文件都会被更新到同一个版本号两个操作可能引起混合版本的情况:提交和部分更新,混合修订版本的工作拷贝(续),提交会引起混合修订版本的情况SVN的原则:一个PUSH的动作不会导致被PUSH,或者反之。换句话说,提交某个修改的过程不会导致工作拷贝被修改。在SVN中,更新和提交是分开的当提交修改时,被提交修改的文件版本号将递增,但是工作拷贝中的其他文件仍然保持原有版本号,于是就形成了混合修订版本的格局,混合修订版本的工作拷贝(续),很显然,(部分)更新也可能会引起这种情况部分更新是指对工作拷贝中某个文件或者子目录的更新操作(不限于更新到HEAD)很灵活的一个特性,混合修订版本的工作拷贝(续),混合修订版本是一种正常的情况同时,混合修订版本很有用例如,可以用来追溯Bug的源头,或者确定某个特性在某个历史版本中是否具有会影响某些命令,如Log例如,当前HEAD版本号为2007,而你由于做了很多提交操作,但一直没有做更新操作,导致虽然最新的文件版本号已经是2007,但是仍然有文件版本号只有1937,当你对这个文件用log命令想查看历史记录,会发现这个文件的历史到1937就为止了混合版本有限制:不是最新的不能提交(喜新厌旧?),4 Subversion基本工作流程和基本操作,Subversion的基本工作流程是:,(续),基本命令CheckOutUpdateStatus/LogCommitSVN的帮助,用svn help 命令名称可以得到命令的帮助,或者查看man手册和info页。Windows环境下可以查看Subversion带的CHM格式参考资料,一般help命令就足够了,CheckOut操作,从版本库中取出某个目录的拷贝到本机上某个目录的操作叫做CheckOut,这个操作是工作的基础语法:checkout(co)URLREV.PATH注:省略svn,即完整的命令应该是svn checkout 例1:svn co svn:/218.94.9.38/svnrepos/skizcorp/trunk在当前目录建立一个trunk目录,里面是工作拷贝例2:svn co svn:/localhost/torm I:PROJECTStorm会在I:PROJECTS目录下创建torm目录,里面存放工作拷贝例2的命令较为常用,因为大多数情况下,我们并不想把工作拷贝目录命名为trunk,CheckOut操作(续),指明Checkout的版本号默认CheckOut操作是针对HEAD版本进行的,大多数情况下我们需要HEAD版本,但如果需要历史版本,可以用-r(-revision)参数或者是用“版本号”的形式例:-r 1452 会检出1452版,如果存在的话-r“2007-05-05”会检出最接近这个日期的版本/trunk1452 效果同第1个例子递归与不递归-N:不递归(仅针对顶层目录),否则目录递归(默认,常用)注:上面两个参数-r N在很多命令里面都用到,Update操作,把版本库的修改同步到本地的过程是Update语法:update(up)PATH.例1:up直接把工作拷贝更新到最新版(HEAD版)例2:up-r 2007更新到2007版例3:up doc/design只更新doc/design下的文件-r和-N参数仍然有用Update会修改被更新目录的BASE版本号,文件状态,BASE版:某个文件的BASE版本是指存放在管理目录.svn中的该文件拷贝的版本,Revert会使该文件回到BASE版本做Update操作时,SVN会打印出受影响文件的状态,有以下几种:A AddedD DeletedU UpdatedC ConflictG Merged若提示C,表示冲突,冲突可以用status命令加-u参数来预测,Revert操作时光倒流,所谓Revert,是指放弃对某个文件的修改,把该文件的内容回复和BASE版本相同,也就是,把该文件的状态回复到未修改状态语法:revert 文件/路径例子例1 revert abc.c 丢弃对abc.c的所有修改例2 revert src/edu/nju/pojo 放弃对此目录下所有文件的修改,冲突解决,当文件发生冲突时,SVN会额外创建3个不受版本控制的文件,同时被冲突文件如果能够合并,会在被冲突文件内部留下冲突记录。例如,冲突的文件为plugin.c,BASE版本是1458,HEAD为1459,会产生3个临时文件plugin.c.mine,plugin.c.r1458,plugin.c.r1459,解决思路:A.手动修改被冲突文件 B.放弃自己的更改实际中,解决办法很灵活,一般需要与他人商量注意:由于这3个文件是在Update后才创建的,而Update之后,工作拷贝的BASE目录已经变成更新后的版本了,所以放弃自己的更改会回到新版本如果不是用Revert的方法解决冲突的话,由于那3个临时文件留在那里,会使Subversion认为冲突没有解决,所以要运行resolved命令告诉SVN冲突解决或者删除临时文件,工作拷贝中对文件的操作,编辑文件,没什么好说的把一个文件加入SVN版本控制,用add命令从版本控制中移除,用delete(rm,remove)命令移动或者重命名,用move(rename)命令拷贝,用copy命令创建目录,用mkdir命令具体命令用法请参照文档注意:尽量不要用操作系统提供的命令管理文件,这样Subversion不知道更改,检验修改,通过status命令可以检查工作拷贝的状态通过diff命令可以检查更改的内容参考SVN手册注意:SVN对文件属性的更改和文件内容的更改是分开管理的,提交修改,一般在提交修改之前,必须运行一下update操作来合并别人作出的新更改。提交用commit命令-message 参数:说明本次提交的有关信息,如为什么要作出这个修改等等。参考SVN book,5 Subversion高级操作,SVN的高级操作主要包括分支(Branch/Tag)以及合并(Merge)操作分支操作切换URL合并操作,为什么需要分支?,你在开发一个软件,基于Windows平台。有一天,老板找到你,希望你把这个软件移植到Linux平台下,同时又不放弃原有版本,怎么管理代码?你的产品即将发布,需要进行一段时间的Alpha,Beta测试直至正式版Release。同时,市场的竞争迫使你必须马不停蹄的开发下一个新版本,增加许多新的特性。两个工作必须同时进行,怎么管理代码?,什么是分支?,分支的概念,从图中可以看到,分支是开发的一条“支线”。它独立于其他开发的线路,并且和其他线路并行开发但是,所有的分支都有共同的历史,有着原先共同的主线,创建分支,创建分支使用copy命令语法:copy 源目录 目标目录方法方法1:先把目录checkout到本地,在本地执行copy命令后提交至版本库例:svn co svn:/localhost/svn copy trunk/branches/mybranch svn commit m“My branch created”方法2:直接用copy命令对版本库中两个URL进行操作例:svn copy svn:/localhost/trunk svn:/localhost/branches/mybranch m“My branch”,创建分支前后版本库的变化,之前 之后,在分支上工作,要想在分支上工作,需要一个对应于分支的工作拷贝。有两种方法可以获得这种工作拷贝方法1:直接从分支的URL上Checkout出工作拷贝(适用于没有工作拷贝的情况)方法2:使用switch命令切换工作拷贝对应的URL(在有工作拷贝的基础上),Switch操作,Switch操作可以使工作拷贝在不同的分支之间或者在 位于不同服务器上 相同的 版本库 的 分支间切换。它的作用是改变工作拷贝对应的URLSwitch&Update:Update命令是Switch命令的一个子集语法:switch-relocate 目标URL慎用-relocate选项,分支的合并(1),分支的合并是指把修改从分支拷贝到主干或者把主干的修改拷贝到分支的过程。传统方法:diff+patch例子:svn diff r 2000:2007 svn:/localhost/trunk patchfile patch p0 patchfile这个例子取出主干2000版到2007版的修改,然后把它应用到工作拷贝(工作拷贝这个时候一般对应于某个分支)只适用于文件内容,对于目录树结构无能为力,分支的合并(2)Merge操作,Merge操作和传统方法十分类似,但是它能够处理目录树的修改,而不限于单个文件内容语法:merge 初始版本树 最终版本树 目标常用语法:merge 初始版本:最终版本 版本库URL 目标作用:取出初始版本到最终版本的修改,然后把它应用到当前工作拷贝例子merge svn:/localhost/trunk2000 svn:/localhost/trunk2007 my_wcmerge r 2000:2007 svn:/localhost/trunk my_wc,SVN版本库常用目录组织结构,6 Subversion其他操作及命令行客户端演示,log,list,import,cleanup,info等命令参考SVN Book,7 图形界面客户端的使用及演示,常见的图形界面客户端:Tortoise SVN(Windows),Subclipse(Eclipse插件,Linux/Windows)观看演示参考各个客户端的文档,