Web-第二十七天 SVN使用【悟空教程】
SVN使用手册
一、如果开发过程中没有SVN?
软件研发过程中,任意一个项目都是由一个团队完成的,而不能依靠单一个体完成。
在团队开发过程中,资料数据的共享与同步将成为开发过程中比较突出的问题。
原始开发管理模式(COPY模式)
缺点:
- 代码管理混乱
- 备份多个版本,占用磁盘空间大
- 解决代码冲突困难
- 容易引发BUG
- 难于追溯问题代码的修改人和修改时间
- 难于恢复至以前正确版本
- 无法进行权限控制
- 项目版本发布困难
为保障团队开发过程中人员沟通各方面成本的降低,必须使用一种有效的方式减少沟通环节,提高开发效率,对资源的共享进行管理。
现阶段的开发管理模式(Tools模式)
相关概念:
- 服务器 server 专用的硬件服务器
- 仓库 repository 专用于某个项目的磁盘空间,位于硬件服务器中
- 检出 checkout 一次性工作,下载代码并完成与服务器间的关联
- 上传/提交 commit 多次工作
- 更新 update 多次工作
- 记录日志 logger 记录操作相关的信息,包括动作,用户,时间,信息
- 版本号码 version 记录文件被操作的次数,即版本数
作为一个管理共享资源的工具必须具备以下几点:
- 能够记录日常事务中所有的文件的新建,编译,删除
- 能够记录文件的操作人,操作时间,操作描述信息
- 对于同一个文件,能够提供更多的历史版本供适用者参考
- 对于不同的文件,能够提供更高的管理权限,限制用户的使用能力
- 对于不同的项目/Case,能够提供更多的空间管理模式
- 对于不同的用户,提供远端访问支持,使用户更快捷进行资源共享
二、什么是版本控制
版本控制(Revision control)是维护工程蓝图的标准做法,能追踪工程蓝图从诞生到定案的过程。是一种记录多个文件内容变化,以便将来查阅特定版本修订情况的系统。
三、主流的版本控制工具
VSS:Visual Source Safe(Microsoft Visual Studio成员)主要任务是负责项目文件的管理
CVS:march-hare出品的一套用于进行文件版本控制软件
SVN:Apache软件基金会名下的一套用于进行文件版本控制软件
在2000年初,开发人员要写一个CVS的自由软件代替品,它保留CVS的基本思想,但没有它的错误和局限,保留CVS的基本特性但去除CVS的bug和不好的特性。
在2000年2月,他们联系《使用CVS开发开源项目》(Open Source Development with CVS)(Coriolis, 1999)的作者Karl Fogel,并征求了他是否愿意在这个新的项目中担任一个角色。巧合的是,当时Karl已经和他的朋友Jim Blandy讨论了一个关于新的版本控制系统的设计。在1995年,这两人就成立了Cyclic Software,一个提供CVS的商业支持的软件公司。虽然他们经营商业服务,但是仍然在每天都在工作中使用CVS。使用CVS的挫折感使得Jim认真思考更好的方法来管理数据,不但确定名字为“Subversion”,而且完成了Subversion档案库的基础设计。
当CollabNet的电话到来时,Karl立即答应了加入项目中,而且Jim让他的雇主RedHat Software同意让他在这个项目中不定期工作。CollabNet雇用了Karl和Ben Collins-Sussman,并在5月开始了详细设计工作。在得到了来自CollabNet的Brian Behlendorf、Jason Robbins和Greg Stein(当时是一名活跃在WebDAV/DeltaV规范过程的自由程序员)很多创意的帮助下,Subversion很快地引起了一个活跃开发者社区的注意。它找出并欢迎很多同样在CVS上受到挫折的社员能来为这个项目做点什么。
Subversion 最初的设计Team定下了几个简单的目标。 它必须在功能上可取代 CVS,也就是说, 所有 CVS 可做到的事, 它都要能够作到。 在修正最明显的瑕疵的同时, 还要保留相同的开发模式。 还有, Subversion 应该要和 CVS 很相像, 任何 CVS 使用者只要花费少许的力气, 就可以很快地上手。
经过十四个月的编码后, Subversion 于2001年8月31日开始实现 “自行管理”。 也就是说, 开发人员不再使用 CVS 来管理 Subversion 的代码, 而以 Subversion 自己来管理。
2009年11月,Subversion被Apache Incubator专案所接收。
2010年1月,正式成为Apache软件基金会的一个顶级专案,所以为Apache Subversion.
目前Apache Subversion的主席为Greg Stein, 项目领导者Release manager为Wandisco公司。
四.1 SVN是什么
SVN(subversion)是近年来崛起的版本管理工具,是cvs的接班人。目前,绝大多数开源软件都使用SVN作为代码版本管理软件。不要狭义的理解只服务于软件研发,很多公司都适用SVN管理整个公司的文档
四.2 SVN的作用
针对软件研发企业的软件生产过程而言,SVN用于管理整个开发过程中的源码,进行版本控制。
五、SVN体系结构图
六、SVN下载与安装
目录层次结构
七、SVN服务端指令
SVN服务端指令是指在服务器端进行操作用于对服务器进行系统级设定与操作
1.查看svn版本信息
svnadmin --version
2.创建数据仓库
svnadmin create E:repositorysvnjavahelp
准备工作
1. 首先手动创建磁盘目录作为总数据仓库:E:repositorysvn
2. 再手动创建磁盘目录作为具体的数据仓库:E:repositorysvnjavahelp
3. 执行指令将指定目录设置为具体的数据仓库
指令结果
将设置指定目录为SVN仓库路径,用于保存共享数据
conf | 目录 | 存放版本库所用配置文件的目录 |
---|---|---|
authz | 文件 | 授权信息 |
passwd | 文件 | 用户安全信息,包含用户名与密码 |
svnserve.conf | 文件 | 服务相关信息 |
db | 目录 | 版本数据存储目录 |
hooks | 目录 | 存放版本库勾子目录 |
locks | 目录 | 存储库锁目录,用来跟踪库的访问者 |
注意事项
创建数据仓库对应的路径必须存在,而被创建的仓库名称路径则自动创建
1.启动SVN服务器(单仓库)
svnserve –d –r E:repositorysvnjavahelp
准备工作
必须存在该路径,且是一个有效的SVN数据仓库
指令结果
启动对应的数据仓库,作为服务,等待响应用户的SVN管理操作
2.启动SVN服务器(多仓库)
svnserve –d –r E:repositorysvn
准备工作
必须存在该路径,并且其中包含有效的SVN数据仓库路径
指令结果
启动对应目录下所有的数据仓库,作为服务,等待响应
注意事项
多仓库启动模式下只有有效的仓库路径才可以被加载
【补】window指令:
查询当前计算机启动服务列表,SVN默认端口为3690
netstat –an
创建SVN服务器启动为window服务
sc create SVN-Service binpath= "D:Program FilesSubversionbinsvnserve.exe --service -r E:repositorysvn" displayname= "SVN-Service" start= auto depend= Tcpip
注意:上述指令为DOS指令,格式要求严谨,不能随意修改sc delete 服务名称
八、SVN客户端指令
SVN客户端指令是指在客户端进行操作用于对完成与服务器信息的交互
1.检出数据仓库信息(单仓库)
svn checkout svn://192.168.1.100 .
准备工作
磁盘中创建一个目录,用于存放与SVN服务器进行交互的数据
执行指令时,将当前路径设置为上述目录
指令结果
将指定的SVN服务器中的信息检出到当前目录,并在当前目录中生成与SVN服务器的连接数据,方便下一次与SVN服务器的连接。该目录中的不能手工修改
注意事项
如果执行指令时,没有进入到保存数据的目录,需要将指令修改为保存到指定路径的格式
svn checkout svn://192.168.1.100 E:workjt
本机操作时,可能存在有多个IP地址,不妨换用localhost识别当前计算机
svn checkout svn://localhost E:workjt
连接时,可以添加端口号进行,默认可以不加,自动访问3690端口
svn checkout svn://localhost:3690 E:workjt
指令的最后一个参数,也就是同步的目录如果省略,默认为当前,等同于输入了.作为当前目录
svn checkout svn://localhost:3690 .
svn checkout svn://localhost:3690
2.检出数据仓库信息(多仓库)
svn checkout svn://192.168.1.100/javahelp .
准备工作
磁盘中创建一个目录,用于存放与SVN服务器进行交互的数据
执行指令时,将当前路径设置为上述目录
指令结果
将指定的SVN服务器指定仓库中的信息检出到指定目录,并在指定目录中生成与SVN服务器的连接数据,方便下一次与SVN服务器的连接。
注意事项
所有注意事项参看单仓库提供模式
由于多仓库启动模式下,提供有多个仓库可使用,因此在指定了SVN服务器位置后,必须指定仓库名称
多仓库检出后会在检出目录中产生一个与被检出仓库相同名称的目录
3.将本地文件/目录加入版本控制
svn add User.java
准备工作
在本地目录中创建文件/目录,用于加入版本控制
指令结果
将本地文件/目录加入到版本控制,受SVN管理。
注意事项
未加入版本控制的文件/目录,无法与服务器进行交互
目录加入到版本控制后,目录中的所有文件与目录都将一并加入版本控制
如果是多仓库检出,需要设定仓库名称,然后设定文件名称
svn add javahelp/User.java
或进入对应目录,使用add指令加入版本控制
4.将加入版本控制的文件/目录提交到服务器
svn commit User.java
准备工作
在本地目录中存在有已加入版本控制的文件/目录
指令结果
将指定文件或目录提交到SVN服务器,并记录相关日志描述信息
注意事项
由于日志信息是SVN进行版本控制中的重要信息,因此不能省略
只有加入SVN版本控制的文件/目录才可以进行提交,未加入SVN版本控制的文件/目录不参与提交,因此执行前必须保障add操作的完成
提交版本到SVN服务器时,需要进行权限认证,除进行正常的登录认证,也可以使用匿名用户进行操作,需要修改匿名用户的访问权限
开启匿名用户的操作功能
打开数据仓库中conf/svnserve.conf文件的anon-access = write选项,并设定对应的操作权限
SVN服务器的认证操作是在每次与SVN服务器进行数据交换时完成,因此无需重启服务器
提交后的文档不接受重复提交,SVN服务器发现当前代码与服务器代码版本相同时,不进行提交操作
SVN服务器中保存的文档不是源文件格式,
5.更新本地版本为SVN服务器最新版本
svn update
指令结果
将本地文件/目录信息更新到与服务器相同版本信息
注意事项
更新时,如果不添加指定的文件/目录名称,则更新整个数据仓库
svn update fileName.txt
如果本地版本与服务器相同,则不进行任何操作
6.删除本地文件
svn delete User.java
准备工作
在本地目录中存在有将要被删除的SVN控制文件/目录
指令结果
将本地文件/目录信息删除
注意事项
delete指令只能删除本地文件,并没有提交/同步到SVN服务器
该指令删除的文件/目录,在未进行提交之前可通过revert指令进行恢复
7.恢复本地文件
svn revert User.java
准备工作
在本地目录中存在有使用delete指令删除的SVN控制文件/目录且未提交到SVN服务器
指令结果
将本地被删除文件/目录信息恢复
注意事项
revert指令只能恢复未提交的数据
1.获取服务器信息
svn info
2.获取服务器目录层次结构
svn list
3.获取服务器状态信息
svn status
4.获取svn指令帮助
svn help
九、SVN图形用户界面操作——TortoiseSVN
TortoiseSVN是一款基于SVN服务器的图形化操作用户界面工具。TortoiseSVN提供了基于鼠标操作为主导的SVN版本控制管理工具
安装完毕后,对当前操作系统重新启动,启动完成后,系统主菜单加入了使用TortoiseSVN对SVN服务器进行管理的工具
使用TortoiseSVN完成SVN版本控制管理
十、服务器相关操作
1.创建数据仓库
svnadmin create E:repositorysvnjavahelp
在任意不是SVN数据仓库的目录中右键打开菜单,选择将当前目录创建为数据仓库
注意:满足如下条件之一,将弹出如下错误提示
- 当前目录已经是数据仓库
- 当前目录是数据仓库的子目录
2.启动SVN服务器(单仓库)
svnserve –d –r E:repositorysvnjavahelp
日常工作中,SVN服务器多采用独立硬件服务器构建,并发布为服务启动,因此无需进行手工启动服务器的操作
3.启动SVN服务器(多仓库)
svnserve –d –r E:repositorysvn
日常工作中,SVN服务器多采用独立硬件服务器构建,并发布为服务启动,因此无需进行手工启动服务器的操作
十一、客户端相关操作
1.检出数据仓库信息(多仓库)
svn checkout svn://192.168.1.100/javahelp .
创建新目录,用于本地保存SVN服务器对应的本地文件,并在目录中执行如下操作,即可创建于SVN服务器的关联
设置SVN服务器仓库名称与检出保存到对应的目录路径
与SVN服务器进行有效关联后,对应的文件夹将以特殊图标的形式呈现
2.将本地文件/目录加入版本控制
svn add User.java
在本地仓库中新创建的文件/目录,不受SVN服务器控制,需要先将其加入版本控制,对新建文件/目录点击右键,通过菜单完成加入版本控制
加入版本控制后,对应的文件/目录将以特殊图标的形式呈现
此时,由于本地仓库中存在有与SVN服务器中不同步的信息,因此图标发生变化
3.将加入版本控制的文件/目录提交到服务器
svn commit User.java
在待提交的文件上面通过右键菜单,完成对SVN服务器的提交操作
选择提交后,打开提交对话框,输入提交日志信息
提交成功后,返回提交成功信息回执,同时被提交文件/目录的图标发生变化
提交失败后,返回提交失败错误原因
4.更新本地版本为SVN服务器最新版本
svn update
在待更新的文件/目录/工程上面通过右键菜单,完成从SVN服务器进行更新的操作
更新完毕后,弹出对应的提示信息
5.删除本地文件
svn delete User.java
在待删除的文件/目录上面通过右键菜单,完成本地文件/目录的删除操作,该操作在未提交之前是可恢复的
6.恢复本地文件
svn revert User.java
对已删除的文件/目录,在未进行提交操作之前,可以对其进行恢复。在任意位置通过右键菜单完成。
选择恢复后,出现对话框,选择要恢复的文件/目录,然后完成恢复操作
选择确认操作后,完成恢复操作
7.提交冲突问题
在进行正常的提交时,如果本地版本与服务器版本不相同,会引发冲突问题。
解决冲突问题共分为三个步骤:
步骤一:获取服务器最新版本
同时,针对版本不统一的文件信息,会生成对应的文件,供用户查看
带有黄色惊叹号的文件表示当前文件与SVN服务器中的文件冲突,并已将冲突内容进行了合并,需要用户手工修改。
.mine后缀的文件是用户在更新之前的最后修改版本内容,可通过原始编辑器查看
.r*后缀的文件是当前文件对应的各个版本的文件内容,r后面的数字是版本号,可通过原始编辑器查看
步骤二:查看并修改冲突文件
打开原始文件,其中包含有冲突内容,用户根据需要进行调整
步骤三:删除冲突备份信息,并进行提交
将除冲突文件之外所生成的所有文件进行删除,并对原始文件进行合并冲突处理后,原始文件状态由冲突状态转换为已编辑状态。
此时即可正常提交,实际开发此现象大多发生在公共配置文件或系统配置文件上。
界面操作解决方案:
步骤一:获取服务器最新版本(同上)
步骤二:查看并修改冲突文件
针对冲突代码进行建议处理
选中冲突行(红色标识)
步骤三:标识解决冲突
确认解除冲突,操作完毕后,临时文件将被删除
8.避免提交冲突——为文件加锁(基于权限)
对不希望出现冲突的文件添加属性
添加新的属性
添加svn:needs-lock属性
确认添加属性
加锁操作是为文件设置了一种状态,也属于对文件的修改,因此需要进行提交。加锁前与加锁后,文件的显示状态发生变化。
提交冲突问题是使用SVN等版本控制工具中令用户最为头疼的问题,为避免提交冲突,可以为任何一个加入版本控制的资源提供锁,避免多用户同时操作同一文件引发冲突。由于文件锁定后,只能由一个用户操作,实际开发中没有实用性,不推荐使用。
对加锁文件的操作分为三个步骤:
步骤一:获取锁
获取锁后,显示当前被文件被某个用户锁定
此时其他用户再次获取当前文件锁时出现冲突,同时无法对文件进行操作
此时锁定文件的用户显示文件被锁定
步骤二:操作编辑文件,并提交,提交完毕后,恢复未锁定状态。
十二、用户权限管理
svnserve.conf svn服务器配置
anon-access = write
匿名用户访问版本库权限,可选值read/write/none
auth-access = write
授权用户访问版本库权限,可选值read/write/none
password-db = passwd
用户名密码文件,可以使用绝对路径,如果使用相对路径指相对于conf目录的位置路径。
注意:如果该选项不开启,用户名密码文件将失效
authz-db = authz
授权管理文件,可以使用绝对路径,如果使用相对路径指相对于conf目录的位置路径。
注意:如果该选项不开启,授权管理将失效
realm = My First Repository
版本库认证域名称,也就是需要认证的仓库名
passwd 用户名密码管理
[users]
设定用户信息
harry = harryssecret
用户名 = 密码
注意:用户名与密码间的空白
authz 授权管理
[groups]
设定用户组,便于管理
harry_and_sally = harry,sally
用户组名 = 用户名1,用户名2,用户名3,……
[/foo/bar]
设定访问权限按目录结构进行设定,根结构写为[/]
harry = rw
用户名 = 读写权限 r-读 w-写
@ harry_and_sally = rw
@用户组名 = 读写权限
* =
除上述设定外,其他用户权限为无
十三、SVN本地导入与导出
1.导入
使用导入功能,可以快速为SVN仓库添加资源文件或目录层次结构,对某个要导入的文件夹执行如下右键功能
注意:导入的资源仅包含指定目录内的内容,不包含所选中目录
2.导出
SVN管理的文件,每个目录中都有一个隐含文件,记录了与SVN相关的信息,导出时,此类文件夹将被过滤掉,不跟随导出。对某个要导出的SVN本地工厂执行如下右键功能
然后选择导出位置,此时保存的目录将不携带SVN管理目录
十四、SVN整合MyEclipse
为Eclipse/MyEclipse添加SVN插件支持,共分五个步骤
步骤一: 通过官网subclipse.tigris.org下载插件文件
eclipse_svn_site-1.6.5.zip myeclipse-svn-site-1.6.16.zip
步骤二:解压压缩包中features与plugins文件夹,并复制到任意目录X。注意目录中不能包含有中文或空格字符。
步骤三:在MyEclipse安装目录的dropins目录下,创建文本文件,文件名任意,扩展名为.link,录入svn.link,并编辑内容如下:
path=X 注意:路径中的分隔符使用\
path=E:\MyEclipse\myPlugin\svn
步骤四:删除MyEclipse安装目录下的configurationorg.eclipse.update目录,重新加载配置信息
步骤五:启动MyEclipse,视图中添加了SVN的管理视图模式
SVN实用操作
工程层次目录
repositoryName
trunk 用于保存开发主线
branches 用于保存支线副本
tags 用于保存标签副本
共享工程
检出工程
提交
更新
恢复删除物理删除
恢复历史版本
历史版本比对
同步
冲突
Subversion 提供了主线、分支管理技术,使得在软件开发中可以更方便、灵活的对项目的进度、版本的发布、版本的维护、软件功能的拓展与定制进行管理。
主线(trunk):一个项目建立时就存在,并伴随着项目的成长而不断的成长,直到项目完全结束。
分支(branch):一般是指功能分支,例如:我们的某个项目要添加一个模块,但这个模块又比较复杂,实现难度比较大。为了不影响主线的稳定,我们就可以创建一个功能分支来专门开发这个模块,当这个模块开发完成以后,并通过测试部门的各项测试,再合并到主线中去。再比如,我们的交警 GPS 项目已经开发完成了,但是这个项目是给泉州交警做的,现在我们又接到了一个交警项目,不过是要给厦门交警大队的。现在厦门交警大队要求我们给他们定制一些功能。我们又不想再主线上进行修改,这个时候,我们也可以创建一个分支,并在这个分支上开发,这时是不会对主线造成影响的。等给厦门开发完成了以后,我们发现,他们要求的有些功能其实很好,以后别的地方可能也需要同样的功能。这个时候我们就可以根据我们的需要,将有用的模块有选择的合并到主线中来。
标签(tag):标签和分支一样,也是一个目录,不过这个目录中一般存放的是发布的信息(当然我们也可以只用分支,但是用标签更清楚明了一些)。还是拿我们的交警项目来举个例子:我们的交警项目开发完成了以后,要拿给泉州交警大队用了,也就是要发布(release),假设这个版本叫做1.0.2。这个时候,我们就要创建一个标签,当泉州交警大队用了三个月,发现了一个 BUG,我们只需要签出这个标签中的代码(它和我们刚提供给泉州交警大队时候的是一模一样的),进行调试,并修正这个 BUG。然后再发布一个版本,假设叫做1.1.0,这个时候我们就在创建一个 1.1.0的标签……
要注意,标签目录里面的代码,要进行严格的控制,除了修正 BUG 外,不能做任何其他的事情。
十五、SVN服务器整合
使用SVN进行版本控制需要基于SVN服务,实际开发中还存在另一种常见的服务提供方式,即将SVN部署到HTTP服务器中,通过http协议访问。由于SVN管理的仅仅是文件,不存在动态资源,因此使用HTTP服务器即可。
- Apache服务器安装与测试
1.下载Apache服务器安装客户端
apache_2.2.14-win32-x86-no_ssl.msi
2.安装Apache服务器
3.安装过程中会进行服务的注册,连续弹出三次DOS提示框。
4.此时快捷任务栏会添加Apache服务器的图标,默认为开启状态。
5.通过右键菜单可以控制Apache服务器。
6.控制窗口设置服务器状态。
7.通过浏览器访问http://localhost,测试服务器安装是否成功。
- Apache服务器整合SVN,将SVN服务器访问权限交由Apache管理控制
1.修改Apache配置文件confhttpd.conf,开启下列两行配置(L:83 L:84)
LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so
注:上述配置中的文件可以在Apache安装目录的modules目录中查找到
2.将下列两行配置添加到上述内容后面
LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so
注:上述配置中的文件有SVN提供,可以在SVN的安装目录中bin目录中查找到
3.将SVN目录下bin目录中上述两个文件拷贝到Apache安装目录的modules目录中
4.使用Apache安装目录bin目录中的htpasswd指令为Apache服务器添加SVN访问权限
创建文件,保存用户权限,格式:htpasswd -cb [filename] [username] [password]
htpasswd -cb svn.pwd jock 123
添加用户权限到指定文件,格式:htpasswd -b [filename] [username] [password]
htpasswd –b svn.pwd jockme 123
注:操作完成后,会生成svn.pwd文件,该文件可以使用任意名称
5.将生成的密码文件svn.pwd移动到指定的SVN仓库配置路径conf目录下,与之前的三个配置文件同层
注:该文件是使用MD5加密后的文件,可以查阅,但不能修改,否则无法使用
密码文件存放的位置不是SVN安装路径,是SVN仓库路径
6.在Apache服务器中添加SVN配置
添加到Apache服务器安装路径下的conf目录中的httpd.conf文件的最后,内容如下:
#配置虚拟目录#
<location /svn/project>
#引用远程访问模块
DAV svn
#项目版本库路径#
SVNPath E:repositorysvnjavahelp
#授权文件#
AuthzSVNAccessFile E:repositorysvnjavahelpconfauthz
#所有用户都需要身份验证#
Satisfy Any
Require valid-user
#验证方式#
AuthType Basic
#项目的名称#
AuthName "project"
#用户文件#
AuthUserFile E:repositorysvnjavahelpconfsvn.pwd
</location>
说明:
<location /svn/project>
通过该路径访问SVN仓库,根据需要进行修改
SVNPath E:repositorysvnjavahelp
SVN仓库路径,即保存SVN版本文件的目录路径
AuthzSVNAccessFile E:repositorysvnjavahelpconfauthz
SVN访问授权文件
AuthUserFile E:repositorysvnjavahelpconfsvn.pwd
Apache整合SVN专用授权用户文件
7.重启服务器,通过Apache服务器访问SVN版本管理
http://localhost/svn/project
- 使用Apache服务器整合SVN仓库
通过TortoiseSVN访问Apache服务器
通过MyEclipse访问Apache服务器
十六、CVS简介(了解)
安装
配置
登录
set cvsroot=:pserver:Jock@127.0.0.1/project
cvs login
添加用户
cvs passwd -a jockme
cvs passwd -a zhangsan
cvs passwd -a lisi
cvs passwd -a -r jock zhangsan
cvs passwd -a -r jockme lisi
MyEclipse使用CVS