项目过程中需要规范代码,决定采用svn,(git 主要项目组内其他成员尚不熟悉,且当前已有多个项目在svn服务器中),我也有机会对此作了一定程度的学习,在这里记下笔记。
Subversion,简称 SVN,是一个开放源代码的版本控制系统,相对于的RCS、CVS,采用了分支管理系统,它的设计目标就是取代CVS。互联网上越来越多的控制服务从CVS转移到Subversion。
SVN使用过程中我主要参考这本书。
SVN改变了开发过程中代码版本迭代的过程,由传统的“锁定-修改-解锁”方案转变为“拷贝-修改-合并”方案。开发成员从中央版本库(服务器中)得到一份拷贝(又称为工作副本,在客户端)后,代码在每个开发成员手里都存在一份。因此每人都可以单独的修改自己工作副本中的代码,而不用在修改时顾及是否冲突,只要在合并时需要注意是否冲突;开发成员对代码并行修改,相对“锁定-修改-解锁”方案中的串行修改,大大加速了开发过程。
拷贝修改合并版本模型:
SVN客户端方面的工作周期包括:签出->修改[->更新]->提交[->合并],服务器方面,配置svn比较容易。关于svn客户端,我主要学习了两方面:基本操作与冲突解决。
##SVN基本操作
在项目中使用的命令也不多,涉及副本的签出、提交、更新、回滚;查看提交日志、修改内容、版本状态。
1.签出
svn checkout URL[@REV]... [PATH]
默认从中央版本库签出最新版本至本地的工作副本,如果指定 REV,那么它确定了从 URL 首先查找的版本。
如果省略路径参数,则 URL 最末尾的目录名作为目标目录名。如果指定多个 URL,则依次将其签出到 PATH 的子目录中,子目录名就是 URL 最末尾的目录名。
如果使用了 “–force” 选项,在工作副本中未版本控制的障碍路径,不会自动导致签出失败。 如果障碍路径与版本库中的对应路径类型相同(文件或目录),它将成为受版本控制的路径,但是内容不改变。它意味着障碍路径的孩子,如果也是障碍路径,那么也会受版本控制。对于障碍路径中的文件,如果与版本库内的不同,将视为工作副本发生本地修改。版本库中的所有属性都应用于障碍路径。
2.修改
SVN对于工作副本的修改包括对于文本的修改与对文件的修改,对文本的修改即指修改文件代码;而后者则包含文件的添加、移动、复制、删除。
修改文本:可以指定自己喜欢的编辑器,进行代码文本的修改(SVN目前主要用来管理文本文件,二进制文件也可以使用,但是SVN版本比较的核心是二进制代码的比较,如果管理非文本,其效率较慢)。
修改文件:
- add
当新添加一个文件时,使用svn add newfile
进行添加,但是请注意,此时新文件并非已真正添加至中央版本库,而是在本地工作副本中被标记为”A”。
- move
剪切或者重命名,svn move filename1 filename2
,file1name此时被标记为”D”,file2name此时被标记为”A”。
- copy delete mkdir
与前两者类似。
以上操作对于文件的修改,都是在本地工作副本中先进行标记,如果确定修改完成,运行svn commit
即可,则操作在中央版本库中生效。
3.回滚与还原
主要分为两种,修改尚未提交,要求还原;修改已提交,要求版本回滚;
- 还原
这里还原到本地最新的版本库。
svn revert [filename]
此命令是不用访问网络的(另两个不用访问网络的命令是diff、status),默认将当前修改恢复至签出的工作副本。
- 版本回滚
版本回滚可以理解为将当前修改的副本与历史版本进行合并。主要分为以下几步:
- 更新当前版本:
svn update
; - 查看版本日志:
svn log
,确认回滚版本号; - 执行回滚:
svn merge -r nowverNO:oldverNO
; - 提交回滚:
svn commit -m 'revert version'
- 回滚后,查看回滚状态:
svn status
;正常情况下,版本号更新为’nowverNO+1’;
**注意:**回滚之前一定要更新。
4.提交
提交之前最好进行工作副本的更新,以免本地工作副本过时。这里过时的概念是指从上次更新后,中央版本库与本地最新的版本已不一致,即从上次更新后中央版本库已接受其他开发成员的提交。
正常的文本修改主要指文本内整行的增加或者减少,这些SVN是可以处理的,当作正常的提交。正常的提交比较简单,执行”svn commit “,添加m参数则增加注释,如svn commit -m 'new version'
。
非正常的提交主要表现在提交前更新时出现冲突需要合并。冲突指在文本一行内,部分内容发生变化,这点SVN是无法智能识别的,需要依靠开发成员间的协调–解决冲突。
5.其他
查看版本状态: svn status
;
查看当前已修改: svn diff
;
查看提交日志: svn log
;默认以时间正序排列,在linux下可以svn log|tac
以倒序排列;
##解决冲突
解决冲突主要发生在文件一行内的部分内容发生变化,一般冲突解决需要比较-合并操作;SVN会采用第三方工具进行以上操作,我选择的是kdiff(本机开发环境是archlinux+kde4+vim),kdiff可以出色完成diff与merge工作。
更新前通过命令svn status -u
查看可能产生的冲突,也可以在提交前使用svn status
查看冲突,其中状态标记为C(onflict),表示冲突。
首先明确几个版本:本地签出的最新工作副本(LOCAL),本地刚完成修改的版本(MODIFY),中央版本库中的最新版本(HEAD);冲突主要表现在MODIFY与HEAD之间,
比如开发组内存在两名开发成员:1和2,时间线如下:
中央版本库中版本5中文件A内容:
svn is a tools
;成员1本地执行
svn update
得到版本5 A;svn is a tools
;成员2执行
svn commit -m 'modify tools to tool'
;则中央版本库更新为版本6:svn is a tool
;成员1修改A为
Svn is a tool
,
如果1此时执行commit,则SVN会提示版本过期,成员1需执行svn update
:此时SVN会存在A存在冲突,此时需要A与B一起进行合并操作。
合并时,1成员处打开kdiff时关于A有三个版本:
本地签出的最新工作副本(LOCAL 版本5)A:
svn is a tools
;修改的版本(MODIFY) A:
Svn is a tools
;中央版本库中的版本6 A(HEAD):
svn is a tool
;
此时成员1与2需要进行面对面的交流,进行代码的合并操作。
(完)