SVN——subversion

      CVS 已经不再适合现代开发,这一点越来越明显。特别是 CVS 只能满足老式 C 程序员的 ASCII 需求,而对 Web 开发人员和其他非传统用户来说,CVS 实际上根本不起作用。于是svn出现以接替CVS。Subversion 是一种开放源码的全新版本控制系统,支持可在本地访问或通过网络访问的数据库和文件系统存储库。不但提供了常见的比较、修补、标记、提交、回复和分支功能性,Subversion 还增加了追踪移动和删除的能力。此外,它支持非 ASCII 文本和二进制数据,所有这一切都使 Subversion 不仅对传统的编程任务非常有用,同时也适于 Web 开发、图书创作和其他在传统方式下未采纳版本控制功能的领域。

1、subversion基本概念:

      版本库:Subversion 是一种集中的分享信息的系统,它的核心是版本库,它储存所有的数据,版本库按照文件树形式储存数据—包括文件和目录。任意数量的客户端可以连接到版本库,读写这些文件。通过写,别人可以看到这些信息,通过读数据,可以看到别人的修改。实际上,版本库是另一种文件服务器,而不是你常见的那一种。最特别的是Subversion 会记录每一次的更改,不仅针对文件也包括目录本身,包括增加、删除和重新组织文件和目录。

      版本模型:版本控制系统的核心任务是提供协作编辑和数据共享,但是不同的系统使用不同的策略来达到目的

      文件共享问题:所有的版本控制系统都需要解决这样一个基础问题:怎样让系统允许用户共享信息,而不会让他们因意外而互相干扰?

      锁定-修改-解锁 方案:许多版本控制系统使用锁定-修改-解锁这种机制解决上述这种问题,在这样的模型里,在一个时间段里版本库的一个文件只允许被一个人修改。首先在修改之前,第一个人Harry 要“锁定”住这个文件,锁定很像是从图书馆借一本书,如果Harry 锁住这个文件,第二个人Sally 不能做任何修改,如果Sally 想请求得到一个锁,版本库会拒绝这个请求。在Harry 结束编辑并且放开这个锁之前,她只可以阅读文件。Harry 解锁后,就要换班了,Sally 得到自己的轮换位置,锁定并且开始编辑这个文件。

      锁定-修改-解锁模型有一点问题就是限制太多,经常会成为用户的障碍:
     1).锁定可能导致管理问题。有时候Harry 会锁住文件然后忘了此事,这就是说Sally 一直等待解锁来编辑这些文件,她在这里僵住了。然后Harry 去旅行了,现在Sally 只好去找管理员放开锁,这种情况会导致不必要的耽搁和时间浪费。
     2).锁定可能导致不必要的线性化开发。如果Harry 编辑一个文件的开始,Sally 想编辑同一个文件的结尾,这种修改不会冲突,设想修改可以正确的合并到一起,他们可以轻松的并行工作而没有太多的坏处,没有必要让他们轮流工作。
     3).锁定可能导致错误的安全状态。假设Harry 锁定和编辑一个文件A,同时Sally 锁定并编辑文件B,如果A 和B 互相依赖,这种变化是必须同时作的,这样A 和B 不能正确的工作了,锁定机制对防止此类问题将无能为力,从而产生了一种处于安全状态的假相。很容易想象Harry 和Sally 都以为自己锁住了文件,而且从一个安全,孤立的情况开始工作,因而没有尽早发现他们不匹配的修改

      拷贝-修改-合并 方案:Subversion,CVS和一些版本控制系统使用拷贝-修改-合并模型,在这种模型里,每一个客户联系项目版本库建立一个个人工作拷贝——版本库中文件和目录的本地映射。用户并行工作,修改各自的工作拷贝,最终,各个私有的拷贝合并在一起,成为最终的版本,这种系统通常可以辅助合并操作,但是最终要靠人工去确定正误。发生冲突的时候,每个人可以看到冲突的修改集,并手工的选择保留一组修改。需要注意的是软件不能自动的解决冲突,只有人可以理解并做出智能的选择。

      工作拷贝:一个Subversion工作拷贝是你本地机器一个普通的目录,保存着一些文件,你可以任意的编辑文件,而且如果是源代码文件,你可以像平常一样编译,你的工作拷贝是你的私有工作区,在你明确的做了特定操作之前,Subversion不会把你的修改与其他人的合并,也不会把你的修改展示给别人,你甚至可以拥有同一个项目的多个工作拷贝。 当你在工作拷贝作了一些修改并且确认它们工作正常之后,Subversion提供了一个命令可以“发布”你的修改给项目中的其他人(通过写到版本库),如果别人发布了各自的修改,Subversion提供了手段可以把这些修改与你的工作目录进行合并(通过读取版本库)。一个工作拷贝也包括一些由Subversion创建并维护的额外文件,用来协助执行这些命令。通常情况下,你的工作拷贝每一个文件夹有一个以.svn为名的文件夹,也被叫做工作拷贝管理目录,这个目录里的文件能够帮助Subversion识别哪一个文件做过修改,哪一个文件相对于别人的工作已经过期了。为了得到一个工作拷贝,你必须检出(check out)版本库的一个子树,(术语“check out”听起来像是锁定或者保存资源,实际上不是,只是简单的得到一个项目的私有拷贝),之后你有了一个/calc的个人拷贝,有一个附加的目录—.svn—保存着前面提及的Subversion需要的额外信息。
      版本库的URL:Subversion可以通过多种方式访问—本地磁盘访问,或各种各样不同的网络协议,但一个版本库地址永远都是一个URL,下表“版本库访问URL”描述了不同的URL模式对应的访问方法。

模式访问方法
file:///直接版本库访问(本地磁盘)
http:///通过配置Subversion的Apache服务器的WebDAV协议
https://与http://相似,但是包括SSL加密
svn:///通过svnserve服务自定义的协议。
svn+ssh://与svn://相似,但通过SSH封装。

      提交(commit):假定你修改了button.c,因为.svn目录记录着文件的修改日期和原始内容,Subversion可以告诉你已经修改了文件,然而,在你明确告诉它之前,Subversion不会将你的改变公开。将改变公开的操作被叫做提交(committing,或者是checking in)修改到版本库。发布你的修改给别人,你可以使用Subversion的提交(commit)命令

      更新(update):假设你有个合作者,Sally,她和你同时取出了/calc的一个工作拷贝,你提交了你对button.c的修改,Sally的工作拷贝并没有改变,Subversion只在用户要求的时候才改变工作拷贝。要使项目最新,Sally可以要求Subversion更新她的工作备份,通过使用更新(update)命令,将结合你和所有其他人在她上次更新之后的改变到她的工作拷贝。svn update命令的输出表明Subversion更新了button.c的内容,注意,Sally不必指定要更新的文件,subversion利用.svn以及版本库的进一步信息决定哪些文件需要更新。

      修订版本(revision):一个svn commit操作可以作为一个原子事务操作发布任意数量文件和目录的修改,在你的工作拷贝里,你可以改变文件内容、删除、改名和拷贝文件和目录,然后作为一个整体提交。 在版本库中,每一次提交被当作一次原子事务操作:要么所有的改变发生,要么都不发生,Subversion努力保持原子性以应对程序错误、系统错误、网络问题和其他用户行为。 每当版本库接受了一个提交,文件系统进入了一个新的状态,叫做一次修订(revision),每一个修订版本被赋予一个独一无二的自然数,一个比一个大,初始修订号是0,只创建了一个空目录,没有任何内容。

      全局修订号 不像其他版本控制系统,Subversion的修订号是针对整个目录树的,而不是单个文件。每一个修订号代表了一次提交后版本库整个目录树的特定状态,另一种理解是修订号N代表版本库已经经过了N次提交。当Subversion用户讨论“foo.c的修订号5”时,他们的实际意思是“在修订号5时的foo.c”。需要注意的是,修订号N和M并不一定表示一个文件不同。而CVS使用每一个文件一个修订号的策略。

      工作拷贝如何追踪版本库:对于工作拷贝的每一个文件,Subversion在管理区域.svn/记录两项关键的信息: 
1)工作文件所作为基准的修订版本(叫做文件的工作修订版本)
2)一个本地拷贝最后更新的时间戳。
       给定这些信息,通过与版本库通讯,Subversion可以告诉我们工作文件是处与如下四种状态的那一种:
       未修改且是当前的 :文件在工作目录里没有修改,在工作修订版本之后没有修改提交到版本库。svn commit操作不做任何事情,svn update不做任何事情。
      本地已修改且是当前的 :在工作目录已经修改,从工作修订版本之后没有修改提交到版本库。本地修改没有提交,因此svn commit会成功的提交,svn update不做任何事情。 
      未修改且不是当前的了: 这个文件在工作目录没有修改,但在版本库中已经修改了。这个文件最终将更新到最新版本,成为当时的公共修订版本。svn commit不做任何事情,svn update将会取得最新的版本到工作拷贝。 
      本地已修改且不是最新的: 这个文件在工作目录和版本库都得到修改。一个svn commit将会失败,这个文件必须首先更新,svn update命令会合并公共和本地修改,如果Subversion不可以自动完成,将会让用户解决冲突。 这看起来需要记录很多事情,但是svn status命令可以告诉你工作拷贝中文件的状态。

2、SubVersion实战

      1)安装,下载安装软件svn-1.4.4-setup.exe(先用老版本做一下)和Setup-Subversion-1.7.8.msi(最新版本)
      2)双击svn-1.4.4-setup.exe进行安装,一路下一步到完成,选在安装路径:d:\program files\subversion,该目录下有bin子目录,所有执行命令都在该目录下,安装完毕后,程序会自动将d:\Program Files\Subversion\bin加到环境变量path中,所以可以直接在命令行输入命令执行。
      3)首先创建一个仓库(repository),假设我们的仓库创建位置为:E:\svn\repository目录下,我们需要先在硬盘上创建该目录。然后,命令行输入:svnadmin create E:\svn\repository,执行完命令后,SVN没有给出任何信息,这说明我们的版本库已经创建成功了,我们这时再到E:\svn\repository下去看看。

可以看到SVN已经在该目录下生成了很多文件夹和文件,这些文件就是SVN进行版本管理时所需要的,我们在日常开发中是不会直接接触到这些文件的。

      4)现在服务器端的仓库已经创建成功了,接下来就是在客户端创建一个项目,然后将该项目import到服务器端,将其纳入SVN的管理之下。不过在创建项目之前我们首先需要启动服务器,服务器启动后才会进行网络侦听,检查到客户端的相关命令请求。 在命令行中输入如下命令:svnserve –d –r E:\svn\repository,该命令含义为让SVN将此目录作为仓库,并侦听客户端的请求。其中-d的作用为后台模式,而-r的作用为指定服务器的仓库路径。
      5)创建如下目录作为我们的一个测试项目:e:\test\client,在此目录下建立一个child子目录和一个test.txt文本文件,首先将命令行的当前目录转到E:\test目录下,在命令行中输入如下命令:svn import svn://localhost,其中svn://localhost表示的是SVN服务器的ip地址,这里就表示是我的本机地址。另外SVN实现了自己独有的协议SVN协议,所以我们可以看到url形式是svn://localhost这样的,这个命令的作用就是将当前目录以及其所有子目录和文件import到服务器上去,纳入SVN的管辖范围中

这时会出现如下错误:

通过命令行的说明,该命令要求我们指定好一个记录日志的文件或者在系统环境变量中增加一个SVN_EDITOR的变量。二者选一就可以了,那么我们可以增加一个SVN_EDITOR的环境变量。该变量的值我们就取为系统自带的记事本就可以了。

设置好变量再次运行,会出现:

出现认证失败的信息,这说明我们已经连接到了SVN服务器,不过服务器认为我们的客户端没有相应的权限,所以这时我们改变一下SVN的认证权限。

      6)回到SVN仓库,即E:\svn\repository目录,找到conf目录,进入,用文本编辑器打开svnserve.conf文件

我们看到这里是关于访问SVN仓库的一些认证设定,找到第12行:anon-access = read,这表示匿名用户的访问权限是读,并且大家注意到,该行前面有一个警号:#。这表示该行是被注释掉的,这与Java的属性文件的注释方式是一致的,这也就说明了此时SVN服务器是不允许匿名登录的,那么我们现在可以将该行前的#号去掉。 不过现在客户端也只可以匿名读,我们的import操作是写操作,所以我们在该行下增加一行anon-access = write,保存,这时我们需要停止之前的svnserve的服务,然后重新启动,让它接受我们的改变,转到它的命令行窗口,用ctrl+c停止它,再重新启动。重新执行上述import操作

OK,可以看到,我们的import操作成功执行了。已经增加了三项,分别是client,child和text.txt。
      7)接下来,我们在本机再建一个目录,位置为E:\test2\client2,再里面创建一个文件夹child2和一个文本文件test2.txt,在test2中输入一些文本,然后打开命令行,执行以下命令:svn mkdir svn://localhost/project2

该命令的作用是在服务器端创建一个虚拟目录project2.今后我们的项目可以import到该目录下,现在我们就开始这个操作。将命令行窗口定位到E:\test2目录下,执行以下命令:svn import svn://localhost/project2

OK,执行成功了,这时我们可以到E:\svn\repository目录下去看看,我们发现这与CVS很不一样,我们现在看不到我们import的文件和目录在什么地方,实际上这都由SVN替我们做好了,我们不用去关心他了
      8)下面开始checkout操作,该操作与CVS一样,就是将服务器上的一个模块检出到本地,作为一个工作拷贝。 另外,大家可能注意到,每次执行一次SVN命令后,都会弹出一个notepad窗口,很不方便,这就是由于我们之前设置的SVN_EDITOR环境变量造成的,所以现在我们把该环境变量删除,不过删除后我们的命令就不能执行成功了,原因在前面我们已经遇到了,不过我们可以采用提示中的另一种方法,就是建立一个日志文件,然后输入命令时指定这个日志文件就可以了,不过这样的话就要求我们每次输入命令时都需要指定这个日志文件的位置,所以到底用哪种方式就看大家的喜好了。在C盘下建立一个文本文件作为日志文件log.txt,内容为空,并且删除SVN_EDITOR环境变量。
在E盘下新建一个目录myclient作为检出的项目的存放目录。将命令行当前目录转到该目录,输入如下命令:svn checkout svn://localhost/project2

已经成功检出了之前import的项目了。并且每一个文件夹下都有一个.svn的隐藏文件夹,这与CVS是类似的,是SVN记录文件版本的文件,我们不要改动或者删除他们。

      9)练习使用commit,对上述检出的test2.txt文件进行修改,保存,打开一个新的命令行窗口,转到E:\myclient\project2\client2目录下:输入命令:svn commit test2.txt,回车。会出现步骤5)错误,重新执行以下命令:svn commit test2.txt –F c:\log.txt

我们到E:\svn\repository\db\revs目录下去看看,这是SVN服务器的目录

实际上我们的当前版本的所有文件的信息都在这里面了,这种管理文件的方式与CVS是有较大差异的。

      10)练习使用update命令,在当前目录下执行svn update test2.txt。注意,由于update不是对服务器进行写操作,而是从服务器取文件,即读操作,所以不需要加上 –F C:\log.txt选项,这点一定要注意。

      11)使用检出命令在互联网上下载项目:练习检出jboss::svn checkout http://anonsvn.jboss.org/repos/jbossas/         ,这样我们就将开发中的JBOSS项目检出到本地,可以读它的源代码。我们从JBOSS检出项目时,指定的url形式是http://类型,而我们之前自己检出的项目url类型却是svn://形式,主要是由于JBOSS项目将Apache与SVN进行了整合,这个工作我们自己也可以进行的。

      12)如果在提交时提示锁定,可以使用svn cleanup进行解锁

      13)使用帮助:可以使用在命令行输入:svn help来获取帮助信息,对于每一个命令的使用,大家可以相同的方式进行查阅。在命令行输入svn checkout –help


from:http://blog.csdn.net/kaoa000/article/details/8554290

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐