Subversion

其实我们所说的SVN就是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS、CVS,它采用了分支管理系统,它的设计目标就是取代CVS。互联网上很多版本控制服务已从CVS迁移到Subversion。说得简单一点SVN就是用于多个人共同开发同一个项目,共用资源的目的(代码仓库)。

  运行方式

svn服务器有2种运行方式

  1. 独立服务器

  2. 借助apache运行

两种方式各有利弊,但目前主要以第一种方式的居多,而Web界面用户可以自行选择使用WebSVN代替,这个工具可以运行在Nginx上也可以运行在Apache上

  存储方式

svn存储版本数据也有2种方式

  1. BDB  (事务安全型表类型)

  2. FSFS (不需要数据库的存储系统)

因为BDB方式在服务器中断时,有可能锁住数据,所以还是FSFS方式更安全一点。

  工作方式

SVN他是集中式的管理方式运行的,集中式代码管理的核心是服务器,所有开发者在开始新一天的工作之前必须从服务器获取代码,然后开发,最后解决冲突,提交。所有的版本信息都放在服务器上。如果脱离了服务器,开发者基本上可以说是无法工作的,下面举一个简单的例子:

开始新一天的工作:
首先,从服务器下载项目组最新代码,开发者进入自己的分支,进行工作,每隔一个小时向服务器自己的分支提交一次代码(很多人都有这个习惯。因为有时候自己对代码改来改去,最后又想还原到前一个小时的版本,或者看看前一个小时自己修改了哪些代码,就需要这样做了)最后,下班时间快到了,把自己的分支合并到服务器主分支上,一天的工作完成,并反映给服务器

  优点与缺点

缺点:

  1. 服务器压力太大,数据库容量暴增

  2. 如果不能连接到服务器上,基本上不可以工作,看上面第二步,如果服务器不能连接上,就不能提交,还原,对比等等。

  3. 不适合开源开发(开发人数非常非常多,但是Google app engine就是用svn的)。但是一般集中式管理的有非常明确的权限管理机制(例如分支访问限制),可以实现分层管理,从而很好的解决开发人数众多的问题

优点:

  1. 管理方便,逻辑明确,符合一般人思维习惯。

  2. 易于管理,集中式服务器更能保证安全性。

  3. 代码一致性非常高。

  4. 适合开发人数不多的项目开发。

  5. 大部分软件配置管理的大学教材都是使用svn和vss。

  Yum部署

SVN可以部署在任意的平台上,它支持Linux、Windows、UNIX,Windows版本的SVN可以搜索VisualSVN

安装命令:

yum -y install subversion

安装是极其的简单,但是主要的是配置好每个项目,安装完成后我们需要创建项目

#创建SVN数据目录 
mkdir /usr/local/subversion 

#创建项目版本库 
svnadmin create /usr/local/subversion/MyProject

创建完之后就应该到配置了,我们创建完成后可以使用tree命令看到对应生成的文件,但主要配置的只有conf下面的三个

tree 
/usr/local/subversion/MyProject 
MyProject/ 
├── conf 
│ ├── authz --- 认证文件 
│ ├── passwd --- 用户密码文件 
│ └── svnserve.conf --- 配置文件 

#配置authz认证文件 
[groups]   #定义组 
rw_group = Kemin 
r_group = Guest 

[MyProject:/]   #定义项目 
@rw_group = rw   #定义对应的权限,权限分为三种r=读,rw读写,空=无权限 
@r_group = r 

#配置passwd认证文件,格式为[用户名 = 密码] 
Kemin = 123456 

#配置svnserve.conf文件 
anon-access = none  #不允许匿名访问 
auth-access = write   #允许认证用户拥有访问权限 
password-db = passwd   #默认读取项目下的conf/passwd 
authz-db = authz  #默认读取项目下的conf/authz

  Linux下上使用SVN

这里不对Windows进行演示,主要的还是Linux下的命令操作,和一些相关性的报错解决,但还是为大家提供Windows安装包和语言包的连接
安装包:https://osdn.net/projects/tortoisesvn/storage/1.10.1/Application/TortoiseSVN-1.10.1.28295-x64-svn-1.10.2.msi
中文语言包:https://osdn.net/projects/tortoisesvn/storage/1.10.1/Language%20Packs/LanguagePack_1.10.1.28295-x64-zh_CN.msi

Linux下的客户端操作:

#检出
svn checkout svn://127.0.0.1/MyProject /data/MyProject/ --username=Kemin --password=123456 

#更新
svn update svn://127.0.0.1/MyProject /data/MyProject/ --username=Kemin --password=123456 

#查看
svn list svn://127.0.0.1/MyProject --username=Kemin --password=123456 --verbose 
--verbose 显示更详细的信息 

#提交
svn add system_cat.sh svn commit -m "系统登录信息输出脚本脚本"

[报错:Can't Convert string from utf-8]
原因:报这个错误是因为linux下不支持中文
解决:调整字符集
export LC_CTYPE="en_US.UTF-8"
export LC_ALL=
使用locale命令查看
LANG=en_US.UTF-8
LC_CTYPE=en_US.UTF-8
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

  关于钩子

前面没有介绍到SVN的另一个特点,那就是钩子,这里最后给大家补充一个钩子的内容,钩子其实就是一个脚本

比较常用的钩子:

钩子脚本说明
post-commit在提交完成并且成功创建版本之后执行该钩子,提交已经完成,不可更改,因此,本脚本的返回值可以忽略(提交完成时触发事务)
pre-commit提交完成前触发执行该脚本
start-commit在客户端还没有向服务器提交数据之前,即还没有建立Subversion transaction之前,执行该脚本(提交前触发事务)
pre-revprop-change在修改revision属性之前,执行改脚本
post-revprop-change在修改revision属性之后,执行改脚本,因为修改稿已经完成,不可更改,因此本脚本的返回值被忽略
pre-unlock对文件进行解锁操作之前执行该脚本
post-unlock对文件进行解锁操作之后执行该脚本
pre-lock对文件进行加锁操作之前执行该脚本
post-lock对文件进行加锁操作之后执行该脚本

下面进行两个svn钩子生产的应用场景举例

  1. pre-commit:限制上传的文件扩展名已经文件的大小,强制要求提交时输入信息

  2. post-commit:提交代码后进行自动周知,并且触发checkout程序,然后实时rsync推送到服务器

钩子的默认每个项目下面的hooks目录下

[root@A-node hooks]# pwd /usr/local/subversion/MyProject/hooks 
[root@A-node hooks]# ls 
post-commit.tmpl post-lock.tmpl post-revprop-change.tmpl post-unlock.tmpl pre-commit.tmpl pre-lock.tmpl
pre-revprop-change.tmpl pre-unlock.tmpl start-commit.tmpl

其实每个钩子都是一个脚本,可以看到模板都是#!/bin/sh开头的

示例一:限制上传的文件大小,强制要求提交时输入信息

vim pre-commit 

#!/bin/bash 

REPOS="$1" 
TXN="$2" 

#定义文件的大小限制,这里设置为5M 
MaxSize=5242880 

#定义snvlook的命令路径 
SVNLOOK=/usr/bin/svnlook 

#统计提交的信息字符个数 
Messages=`$SVNLOOK log -t "$TXN" "$REPOS" | wc -c` 

#判断字符数是否大于8个字节数 
if [ "$Messages" -lt 9 ];
    then         
        echo -e "nLog message can't be empty,you must input more than 8 chars as comment! " 1>&2         
        exit 1 
fi 

#查看文件的大小 
FileSize=`$SVNLOOK cat -t "$TXN" "$REPOS" "$f" | wc -c` 

#判断文件大小是否超过5M 
if [ "$FileSize" -gt 5 ]; 
    then
        echo "File $f is too large (must <=$Max_Size) B" >&2
        exit 1
fi

示例二:提交代码后进行自动触发checkout程序,然后实时rsync推送到服务器

vim post-commit 

#!/bin/bash 

#默认内置定义 
REPOS="$1" 
REV="$2" 

#调整字符集,防止带中文的文件不支持 
export.UTF-8 

#定义日志的路径 
LogPath="/usr/local/subversion/KJ-Project/log" 

#判断日志路径是否存在,如果不存在,则自动创建 
[ ! -d ${LogPath} ] && mkdir ${LogPath} -p 

#定义svn命令的路径,并且拉取代码 
SVN="/usr/bin/svn" 
$SVN update --username svnuser --password kemin-cloud.com /data/KJ-Project 

#判断上一个步骤是否执行成功,如果成功则执行Rsync推送 
if [ $? -eq 0 ];
    then
        /usr/bin/rsync -az --delete /data/KJ-Project /var/web/html/ 
fi