Subversion

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

运行方式

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

存储方式

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

  • BDB  (事务安全型表类型)
  • 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

SVNServer启动

svnserve -d -r /usr/local/subversion/

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=Kemin@0426 --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钩子生产的应用场景举例

  • pre-commit:限制上传的文件扩展名已经文件的大小,强制要求提交时输入信息
  • 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 LANG=en_US.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
最后修改:2019 年 05 月 19 日
-