版本控制工具——SVN
一、需求
需求之一:备份
小明负责的模块就要完成了,就在即将Release之前的一瞬间,电脑突然蓝屏,硬盘光荣牺牲!几个月来的努力付之东流
需求之二:代码还原
这个项目中需要一个很复杂的功能,老王摸索了一个星期终于有眉目了,可是这被改得面目全非的代码已经回不到从前了。什么地方能买到哆啦A梦的时光机啊?
需求之三:协同修改
小刚和小强先后从文件服务器上下载了同一个文件:Analysis.java。小刚在Analysis.java文件中的第30行声明了一个方法,叫count(),先保存到了文件服务器上;小强在Analysis.java文件中的第50行声明了一个方法,叫sum(),也随后保存到了文件服务器上,于是,count()方法就只存在于小刚的记忆中了
需求之四:多版本项目文件管理
老许是一位项目经理,我会告诉你他把每一个版本都保存一份吗?我会告诉你这些工程里其实有很多文件都是重复的吗?我会告诉你老许为这事删了很多电影吗?
需求之五:追溯问题代码的编写人和编写时间
老王是另一位项目经理,每次因为项目进度挨骂之后,他都不知道该扣哪个程序员的工资!就拿这次来说吧,有个该死的Bug调试了30多个小时才知道是因为相关属性没有在应用初始化时赋值!可是二胖、王东、刘流和正经牛都不承认是自己干的!
需求之六:权限控制
小温这两天幸福的如同掉进了蜜罐里,因为他成功的得到了前台MM丽丽的芳心,可他郁闷的是这几天总是收到QA小组的邮件,要求他修正程序中存在的Bug,可他自己本地电脑上是没有这些Bug的,“难道我的代码被哪个孙子给改了?”。是的,小温没来的时候,丽丽是QA小组小郑的女朋友啊!
由此,引出我们这里得主角:版本控制工具:SVN
一个版本管理工具,常用于软件开发项目中,实现代码、文档等的历史版本保存、共享和权限管理
二、SVN基本介绍
1.工作原理
SVN的工作原理:采取客户端/服务器模式——在服务器的版本库中保存项目文件的各个版本,所有参与协同开发的程序员在自己本地电脑上保存一个工作副本。SVN支持程序员将本地副本更新到服务器端的最新版本,也支持将本地副本的最新改变更新到服务器端,而且后面的更新不会覆盖前面的更新,而是作为一个新的版本被保存下来——SVN甚至支持将本地工作副本恢复为服务器端保存的某一个历史版本。
2.基本操作
(1) 检出(checkout):将一个服务器端创建好的项目整个下载到本地,这是到项目组后参与开发的第一步,只需执行一次。
>这样svn上最新的数据会被传送到这个文件夹, 目录结构会自动建好,svn上的文件会自动出现在对应的文件夹中。当然如果你愿意也可以选择一个旧的版本,或者只包含一层目录或者只是这个文件夹中的文 件。
(2) 更新(update):将本地文件更新为服务器端的最新版本,通常为每天上班时或修改公共文件之前执行一次。
>把他人上传的代码更新到本地环境,你在这个环境下把自己的代码合并到这个版本中。
>在这个过程中如果有人删除了文件,它会你机器上的文件删除,如果别人改了某个文件,会将这个文件更新。如果你
修改了某个文件,别人删除了它,则这个文件不会被删除,只会和svn没关系了。如果你修改了某个文件,而这个文件别人也修改了,
在更新的过程中就会试图自 动将你的修改合并,如果成功,他的内容就是你修改的和别人修改的内容的并集,如果失败,svn就会将这个文件标记为冲突。
(3)提交(commit):将本地修改提交到服务器端。通常每天下班前或每实现一个功能、完成一个模块时执行一次。
>将合并好的版本提交到svn,他人再根据你提交的版本开发,保证代码不会冲突。
值得注意的是,使用SVN的目的是多人共享一个最新的目录,你在提交的时候最好先更新,更新到最新版本的核对之后再提交。
因为如果你不更新直接提交,这段时间有可能他人更新后已经提交了,你没有更新还是老得版本,直接提交后会把他人更新的覆盖掉。
>commit 的过程仅仅是将你本地的一些修改提交到svn中让svn上的和你的一 致,在提交之前必须已经解决了需要提交文件已有的冲突才行
更多更详细得SVN操作请参见:http://blog.chinaunix.net/uid-20321537-id-1966870.html
<h2>三、安装</h2>
推荐的组合安装版本:http://www.cnblogs.com/xiaobaihome/archive/2012/03/20/2407610.html
一路next next即可。(会自动创建系统环境变量)(注意客户端和服务端的不同)
四、常用命令
1.配置版本库
svnadmin create path
例如:(需要先进入我们创建的版本库的路径,可以配置一个根目录作为仓库根路径)
2.将svn注册为windows服务
//命令行窗口启动暂不介绍(因关闭窗口服务即停止)
示例:
sc create MySVNService binpath= "F:\Program Files (x86)\Subversion\bin\svnserve.exe --service -r F:\svn_repository" start= auto depend= Tcpip
这样,我们就可以使用windows来控制svn的服务启动与停止了!
服务的开启与关闭:(需要管理员权限)
sc start 服务名 ——开启服务
sc start MySVNService
sc stop 服务名 ——关闭服务
sc stop MySVNService
sc delete 服务名
sc delete MySVNService
五、客户端插件的使用
//命令行的检出更新等操作暂不列出。
eclipse的插件的安装:
下载插件:
使用下载好的插件压缩包eclipse_svn_site-1.10.5.zip,这个压缩包是从http://subclipse.tigris.org/servlets/ProjectDocumentList?folderID=2240/网站(subclipse是这款Eclipse插件的名称)上下载的。安装方法是:
将解压出来的文件夹放到 Eclipse安装目录/dropins/eclipse_svn_site-1.10.5下(整个解压出来的文件夹放过去即可)
//重启eclipse,完成安装(卸载同理)
在eclipse的Team下可以看到插件成功安装:
集成SVN后报错 failed to load...
1.windows->preferences->Team->SVN->SVN接口
2.选择SVNKit (Pure Java) xxxxxx
接下来使用插件来进行提交等操作:
为了显示,先建立一个工程:
然后,右击项目-> Team-> share project-> SVN
//由于之前没有创建资源库,这里进行新的资源库的创建
//后面需要用到版本库的地方,请根据实际情况将localhost更改为合适的地址
URL地址必须为带conf db等文件夹的资源库地址
若出现认证失败,请打开匿名写的权限:(临时方式)
这样我们就进入了SVN的视图,想要上传哪个文件直接右击选择提交即可,这里我们提交整个项目:
//点击OK完成提交
如果我们想看看服务器上到底有啥,我们可以打开SVN资源库研究的透视图即可:
//如果是Web工程,build目录(编译后的一些class文件等)将不会被纳入版本控制(将不会显示一个小金色的桶)
更多图标的含义请参见:
https://wenku.baidu.com/view/42030a0976c66137ee0619f2.html
小乌龟也有自带的图标集:
如何进行检出checkout操作
在空白处右击 import 选择从SVN检出:
可以选择作为工作空间的项目导出操作:
//如果是Web工程,将会提示build文件夹为 ? ,表示未纳入版本控制,可以在build上右键 ignore,忽略此目录,不纳入版本控制。
如何进行更新操作:
我们先进行文件的更改:
//这个时候是可以看到变成了一颗黑色的星星(意思就是:已修改,未提交,更多图标含义见上文链接)
提交完成后,在另外一个需要更新的端,右击LoveClass文件,选择更新即可!
【如何导出maven项目】:
1.从svn导入“作为工作空间中的项目检出”---》Finish
2.如“1”操作后,会自动的在MyEclipse中添加一个Maven项目,此时删掉自动到如的那个maven项目。
3."Existing Maven Project"导入
4.找到你之前通过MyEclipse的插件导入到workspace中的maven项目,导入即可。
六、冲突问题(confict)
发生冲突的情况:
<1>两个开发人员,Harry和Sally,分别从服务器端下载了文件A。
<2>Harry修改之后,A变成了A’,Sally修改之后,A变成了A’’。
<3>Harry先一步提交,使服务器端文件的版本也变成了A’
<4>Sally本地的文件A’’已经过时了,此时她已无法提交文件,服务器会要求她先进行一次更新操作。
<5>此时Sally的更新操作有两种可能
(1)Sally所做的修改与Harry不是同一个位置,更新操作尝试合并文件成功。
(2)Sally所做的修改与Harry恰好是同一个位置,更新操作尝试合并文件失败,发生冲突。
<6>发生冲突后,本地工作副本会发生如下变化
public static void main(String[] args) {
System.out.println("Edit By Command!");
System.out.println("Edit By Command!");
<<<<<<< .mine
System.out.println("Edit By Eclipse!");
=======
System.out.println("Edit By Command!New Edit");
>>>>>>> .r14
System.out.println("Edit By Command!");
System.out.println("Edit By Command!");
}
其中,从<<<<<<< .mine到=======之间是发生冲突时本地副本的内容。从=======到>>>>>>> .r14是发生冲突时服务器端的最新内容。注意这里r后面的数字是发生冲突时服务器端的版本号,有可能是任何整数值,r14只是一个例子。
同时文件图标变成一个“黄色的!”。
(2)与冲突文件同目录下新增文件,扩展名为.mine,其内容是发生冲突时本地副本的文件内容。
(3)与冲突文件同目录下新增文件,扩展名为.r小版本号,例如MyCRM.java.r13,其内容是冲突发生之前,服务器端的文件内容,可以作为解决冲突的参照。——安全的版本(没有提交相同地方时安全的版本)
(4)与冲突文件同目录下新增文件,扩展名为.r大版本号,例如MyCRM.java.r14,其内容是冲突发生时,服务器端的文件内容。
如何解决冲突
在发生冲突的文件上右键->Team->编辑冲突,打开对比的视图:
之后,根据需要和实际情况将本地内容更正,然后点击保存完成操作
在冲突文件上点右键→Team→标记为解决:
此时.mine文件和.r版本号文件都会被自动删除,冲突文件的图标变为“*”,表示可以提交。
提交文件,文件图标变为“金色圆柱体”
由此我们可以提出一点解决冲突的技巧:在修改之公共文件前进行更新
七、权限问题
我们先把之前的匿名访问关闭(对应版本库的svnserver.conf文件),把授权访问打开:
//注意一定要顶格写!
再把密码保存和授权信息保存打开:
我们打开passwd文件(conf目录下),可以添加用户:
打开authz文件设置相关的权限信息:
其中,group是设置一个组,单个用户在用户里配置了也可以单独存在,不配置组
[/foo/bar] 是设置一个目录的权限(图中是根目录),然后对权限进行管理,使用@+组名设置某个组的权限,也可以单独使用用户名设置单个用户权限,例如:jerrt = r ,设置jerrt为只读权限,组后的 * = 表示除了配置的信息外,其他用户没有任何权限!
设置好了之后,我们在eclipse中修改文件,进行提交,会弹出对话框,输入用户名与密码:
输入拥有写权限的用户名和密码后便可以正常提交了!
八、时光机
这里直接查看历史版本会报出一个错误信息,需要我们在conf文件中显式的指定匿名的权限(注释了也不可行,无奈)
之后我们右击文件->Team->显示资源历史记录即可:
如果我们需要放弃本次更改,还原到上次提交时
//重新提交后刷新历史版本即可看到新提交的
九、SVN独立客户端:TortoiseSVN
下载安装程序:http://tortoisesvn.net/downloads.html
也可以安装语言包:
Win64位语言包:LanguagePack_1.8.7.25475-x64-zh_CN.msi
整个安装过程一直next next 即可!(注意中间勾选是否需要命令行的选项)
注意:插件与客户端版本需要匹配!