一. SVN概述
1. SVN 简介
Subversion 版本控制系统 简称 SVN。
SVN 是一个跨平台开放源代码的集中式版本控制系统,可以实现文件及目录的保存及版本回溯。
SVN 管理着随时间改变的各种数据,这些数据放置在一个中央档案库(repository)中,这个档案库很像一个普通的文件服务器或者FTP服务器,不过它会记录每一次文件的变动。这样你就可以把档案恢复到旧的版本,或是浏览文件的变动历史。
SVN 是一个通用的软件系统,它不但可以用来管理程序源码,也可以管理任何类型的文件。
SVN 是一种集中式的版本控制系统,它的核心是中央版本库(repository),存储所有的数据,版本库按照文件树形式存储数据(包括文件和目录),任意数量的的客户端可以连接到版本库,读写这些文件。通过写数据,别人可以看到这些,通过读数据,可以看到别人的修改。
2. svn 运行方式和访问方式
2.1 运行方式
- 独立服务器 访问方式:svn://svn.etiantian.org/www
- 和 apache 等 http 服务结合 访问方式:http[s]://svn.etiantian.org/www
- csvn(Apache + SVN)是一个整合好的软件,带有web管理页面的svn软件;
- 本地直接访问 访问方式:file://application/data/www/
2.2 访问方式
- file:// 直接访问本地磁盘或网络磁盘访问版本库
- http:// 通过webdav协议访问支持subversion的apache服务器
- https:// 与http:// 类似,只是用了ssl加密访问
- svn:// 通过TCP/IP自定义协议访问subversion服务器
- svn+ssh:// 通过认证并加密的TCP/IP自定义协议访问subversion服务器
3. svn 版本库数据存储格式
SVN 存储的数据不能看到文件实体
-
BDB:(伯克利 DB)
subversion 1.2 版本以前默认的存储方式;可能出现锁住数据的的问题; - FSFS:
一个专用于 SVN 版本库的文件系统后端,可以使用网络文件系统(NFS,SMBFS),1.2 版本及以后的默认存储格式。
4. svn 逻辑架构原理图
5. SVN 工作流程
SVN 是一种集中式版本控制系统。集中式管理的工作流程如下图:
集中式代码管理的核心是SVN服务器,开发者在开始新一天工作之前必须先在本地update一下代码,然后开发、解决冲突、合并、提交。所有的版本信息都放在SVN服务器上面。
下面举例说明:
开始新一天的工作:
- 从服务器下载项目组最新代码。
- 进入自己的分支,进行工作,每个一个小时向服务器上自己的分支提交一次代码(很多人都有这个习惯。因为有时候自己对代码改来改去,最后又想还原到前一恶搞小时的版本,或者看看前一个小时自己修改了哪些代码,就需要这样做了。)
- 下班时间快到了,把自己的分支合并到服务器主分支上,一天的工作完成,并反映给服务器。
这就是经典的svn 工作流程,从流程上看,有缺点,也有优点。
缺点:
- 服务器压力大,SVN 数据库容易暴增
- 如果不能连接到服务器上,基本上不可以工作,看上面第二步,如果服务器不能连接上,就不能提交、还原、对比等等。
- 不适合开源开服(开发人数非常非常多)。但是一般集中式管理的有非常明确的权限管理机制(例如分支访问限制),可以实现分层管理,从而很好的解决开发人数众多的问题。
优点:
- 管理方便,逻辑明确,符合一般人思维习惯。
- 代码一致性和安全性非常高。
- 适合开发人数不多的项目开服。
- 大部分软件配置管理的大学教材都是使用svn。
- 学习简单、使用简单
二. SVN 安装
1. SVN 下载
官网 http://subversion.apache.org/
最新稳定版:subversion-1.9.7.tar.gz
在windows环境下,最常用VisualSVN server 服务端和 TortoiseSVN(简称TSVN)客户端搭配使用
2. SVN 服务端安装
[root@Node1 ~]# yum install subversion
[root@Node1 ~]# rpm -ql subversion
/etc/bash_completion.d
/etc/bash_completion.d/subversion
/etc/rc.d/init.d/svnserve
/etc/subversion
/usr/bin/svn # 客户端命令
/usr/bin/svnadmin # 服务端svn 版本库管理工具(创建、导出、导入、删除等)
/usr/bin/svndumpfilter
/usr/bin/svnlook # 服务端查看版本库的信息等
/usr/bin/svnserve # 服务端命令,控制svn服务的启动等
/usr/bin/svnsync
/usr/bin/svnversion
/usr/lib64/libsvn_client-1.so.0
/usr/lib64/libsvn_client-1.so.0.0.0
/usr/lib64/libsvn_delta-1.so.0
/usr/lib64/libsvn_delta-1.so.0.0.0
/usr/lib64/libsvn_diff-1.so.0
/usr/lib64/libsvn_diff-1.so.0.0.0
/usr/lib64/libsvn_fs-1.so.0
3. 配置并启动 SVN
建立svn版本库根目录(svndata)
[root@Node1 ~]# mkdir -p /application/svndata
[root@Node1 ~]# tree /application/
/application/
├── svndata
1 directories, 0 files
启动svn 服务指定服务的 SVN 根目录:
[root@Node1 ~]# svnserve --help
usage: svnserve [-d | -i | -t | -X] [options]
Valid options:
-d [--daemon] : daemon mode
-i [--inetd] : inetd mode
-t [--tunnel] : tunnel mode
-X [--listen-once] : listen-once mode (useful for debugging)
-r [--root] ARG : root of directory to serve
-R [--read-only] : force read only, overriding repository config file
--config-file ARG : read configuration from file ARG
--listen-port ARG : listen port
[mode: daemon, listen-once]
--listen-host ARG : listen hostname or IP address
[mode: daemon, listen-once]
-T [--threads] : use threads instead of fork [mode: daemon]
--foreground : run in foreground (useful for debugging)
[mode: daemon]
--log-file ARG : svnserve log file
--pid-file ARG : write server process ID to file ARG
[mode: daemon, listen-once]
--tunnel-user ARG : tunnel username (default is current uid's name)
[mode: tunnel] # 这里为什么会变成红色?
-h [--help] : display this help
--version : show program version information
[root@Node1 ~]# svnserve -d -r /application/svndata/
[root@Node1 ~]# ps aux|grep svn
root 6784 0.0 0.1 160996 920 ? Ss 11:10 0:00 svnserve -d -r /application/svndata/
root 6786 0.0 0.1 103244 856 pts/0 S+ 11:10 0:00 grep svn
[root@Node1 ~]# netstat -tunap|grep svn
tcp 0 0 0.0.0.0:3690 0.0.0.0:* LISTEN 6784/svnserve
4. 建立版本库
[root@Node1 ~]# svnadmin --help
general usage: svnadmin SUBCOMMAND REPOS_PATH [ARGS & OPTIONS ...]
Type 'svnadmin help ' for help on a specific subcommand.
Type 'svnadmin --version' to see the program version and FS modules.
Available subcommands:
crashtest
create
deltify
dump
help (?, h)
hotcopy
list-dblogs
list-unused-dblogs
load
lslocks
lstxns
pack
recover
rmlocks
rmtxns
setlog
setrevprop
setuuid
upgrade
verify
[root@Node1 ~]# svnadmin create --help
create: usage: svnadmin create REPOS_PATH
Create a new, empty repository at REPOS_PATH.
Valid options:
--bdb-txn-nosync : disable fsync at transaction commit [Berkeley DB]
--bdb-log-keep : disable automatic log file removal [Berkeley DB]
--config-dir ARG : read user configuration files from directory ARG
--fs-type ARG : type of repository: 'fsfs' (default) or 'bdb'
--pre-1.4-compatible : use format compatible with Subversion versions
earlier than 1.4
--pre-1.5-compatible : use format compatible with Subversion versions
earlier than 1.5
--pre-1.6-compatible : use format compatible with Subversion versions
earlier than 1.6
[root@Node1 ~]# svnadmin create /application/svndata/sadoc
[root@Node1 ~]# tree /application/
/application/
├── svndata
│ └── sadoc
│ ├── conf # 配置文件
│ │ ├── authz # 用户权限文件
│ │ ├── passwd # 用户密码文件
│ │ └── svnserve.conf # 服务配置文件
│ ├── db # 数据库
│ │ ├── current
│ │ ├── format
│ │ ├── fsfs.conf
│ │ ├── fs-type
│ │ ├── min-unpacked-rev
│ │ ├── rep-cache.db
│ │ ├── revprops
│ │ │ └── 0
│ │ │ └── 0
│ │ ├── revs
│ │ │ └── 0
│ │ │ └── 0
│ │ ├── transactions
│ │ ├── txn-current
│ │ ├── txn-current-lock
│ │ ├── txn-protorevs
│ │ ├── uuid
│ │ └── write-lock
│ ├── format
│ ├── hooks # 钩子文件夹
│ │ ├── 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
│ ├── locks # 锁文件
│ │ ├── db.lock
│ │ └── db-logs.lock
│ └── README.txt
三. SVN配置文件详解
svnserve通过配置文件来设置用户和口令,以及按路径控制版本库访问权限。
1. svnserve 配置文件概述
下面详细学习svnserve配置文件svnserve.conf的格式,并说明如何使用配置文件控制版本库访问权限。
1.1 svnserve 配置文件通常由以下3个文本文件组成:
svn服务配置文件:
该文件版本库目录的conf目录下,文件名为svnserve.conf。
用户密码配置文件:
该文件名在文件svnserve.conf中指定,缺省为同目录下的passwd。
用户权限配置文件:
该文件名也在文件svnserve.conf中指定,缺省为同目录下的authz。
2. svn 服务配置文件
svn服务配置文件为版本库目录中conf/svnserve.conf 文件。该文件仅由[general]和[sasl]配置段组成。
[general]配置段中配置行格式如下:
<配置项> = <值>
配置项分为以下5项:
- anon-access 控制非鉴权用户(匿名用户)访问版本库的权限。取值范围为"write"、"read"和"none"。即"write"为可读可写,"read"为只读,"none"表示无访问权限。缺省值:read
- auth-access 控制鉴权用户访问版本库的权限。取值范围为"write"、"read"和"none"。即"write"为可读可写,"read"为只读,"none"表示无访问权限。缺省值:write
- password-db 指定用户名口令文件名。除非指定绝对路径,否则文件位置为相对conf目录的相对路径。缺省值:passwd
- authz-db 指定权限配置文件名,通过该文件可以实现以路径为基础的访问控制。除非指定绝对路径,否则文件位置为相对conf目录的相对路径。缺省值:authz
- realm 指定版本库的认证域,即在登录时提示的认证域名称。若两个版本库的认证域相同,建议使用相同的用户名口令数据文件。 缺省值:一个UUID(Universal Unique IDentifier,全局唯一标示)。
注意: svnserve.conf 文件必须中必须顶格写(注释行也必须顶格写),否则报错。
[root@Node1 conf]# ls
authz passwd svnserve.conf
[root@Node1 conf]# cp -a svnserve.conf svnserve.conf.`date +%F`.bak
[root@Node1 conf]# ls
authz passwd svnserve.conf svnserve.conf.2017-12-13.bak
[root@Node1 conf]# vim svnserve.conf
[general]
#anon-access = read
anon-access = none
# auth-access = write
auth-access = write
password-db = /application/svndata/sadoc/conf/passwd
authz-db = /application/svndata/sadoc/conf/authz
realm = test1
版本库认证域:
在使用svn客户端访问svnserve服务器时,若需要用户登录,则提示信息如下:
[root@Python data]# svn checkout svn://192.168.10.1/sadoc
Authentication realm: 3b1cbe24-4dd1-455c-9f6b-b1150c555260
Password for 'root':
在上述第2行"Authentication realm:
如果在配置文件中指定了如下配置项:realm = test1
将在svn客户端提示如下:
[root@Python data]# svn checkout svn://192.168.10.1/sadoc
Authentication realm: test1
Password for 'root':
3. 用户密码文件
用户名密码文件由svnserve.conf的配置项password-db指定,缺省为conf目录中的passwd。该文件仅由一个[users]配置段组成。
[users]配置段的配置行格式如下:
<用户名> = <口令>
注意:配置行中的口令为未经过任何处理的明文。
例2:用户名口令文件conf/passwd的内容如下:
[root@Node1 conf]# cp -a passwd passwd.`date +%F`.bak
[root@Node1 conf]# vim passwd
[users]
# harry = harryssecret
# sally = sallyssecret
admin = admin
xxj = 123456
ops = 111
dev = 222
该文件中配置了两个用户,用户名分别为"admin"等四个用户。其中"admin"用户的口令为"admin"。
4. 权限配置文件
权限配置文件由svnserve.conf的配置项authz-db指定,缺省为conf目录中的authz。该配置文件由一个[groups]配置段和若干个版本库路径权限段组成。
[groups]配置段中配置行格式如下:
<用户组> = <用户列表>
用户列表由若干个用户组或用户名构成,用户组或用户名之间用逗号","分隔,引用用户组时要使用前缀"@"(如:引用用户组"all"要使用字符串"@all")。
注意: 用户列表中的用户是要在用户密码文件中定义的用户
版本库路径权限段的段名格式如下:
[<版本库名>:<项目/目录>]
其中,方框号内部分可以有多种写法:
- [/],表示根布幕及以下,根目录是svnserve启动时指定的,我们指定为/application/svndata,[/]就是表示对全部版本库设置权限
- [repos:/],表示对版本库repos设置权限
- [repos:/sadoc] 表示对版本库repos中sadoc目录设置权限
如版本库abc路径/tmp的版本库路径权限段的段名为"[abc:/tmp]"。
可省略段名中的版本库名。若省略版本库名,则该版本库路径权限段对所有版本库中相同路径的访问控制都有效。
如:段名为"[/tmp]"的版本库路径权限段设置了所有引用该权限配置文件的版本库中目录"/tmp"的访问权限。
版本库路径权限段中配置行格式有如下三种:
- <用户名> = <权限>
- @<用户组> = <权限>
-
- = <权限>
其中,"*"表示任何用户;权限的取值范围为''w"、'r'和'rw'和空,空表示对该版本库路径无任何权限,'r'表示具有只读权限,'rw'表示有读写权限。
- = <权限>
注意:每行配置只能配置单个用户或用户组。
例3:权限配置文件conf/authz的内容如下:
[groups]
ett_sa = admin,xxj
ett_dev = ops,dev
[sadoc:/]
@ett_sa = rw
@ett_dev = r
5. SVN 客户端连接服务器
[root@Python data]# svn checkout --username=xxj --password=123456 svn://192.168.10.1/sadoc
-----------------------------------------------------------------------
ATTENTION! Your password for authentication realm:
test1
can only be stored to disk unencrypted! You are advised to configure
your system so that Subversion can store passwords encrypted, if
possible. See the documentation for details.
You can avoid future appearances of this warning by setting the value
of the 'store-plaintext-passwords' option to either 'yes' or 'no' in
'/root/.subversion/servers'.
-----------------------------------------------------------------------
Store password unencrypted (yes/no)? yes
Checked out revision 0.
6. 总结
在本节中,详细介绍了svnserve程序的3个配置文件。SVN管理员可以通过这3个配置文件设置 SVN 服务的用户名口令以及对版本库路径的访问权限。这些配置文件保存后就立即生效,不需要重启svnserve服务。
需要强调的是本文介绍的配置文件只对svnserve服务有效,即客户端通过前缀为svn://或svn+ssh://的URL访问版本库有效,而对通过前缀http://、https://或file:///的URL无效。
本篇博客主要学习了 SVN 介绍和安装部署,下篇继续学习 SVN 客户端命令使用。
# 四、多版本库解决方案
当有多个软件开发项目时,而又只安排一台SVN服务器,为了各个项目不影响,就需要在一台SVN服务器上同时运行多个版本库,分别管理各个项目组的代码。
一台svn服务器上同时运行多个版本库有2种方案:
- 在SVN服务器上创建多个版本库,同时运行多个svnserve进程,分别监听不同的端口。客户端连接此服务器不同端口即可连接不同的版本库。
- SVN版本库起动方式,现在/data/svn_data下面有repo1,repo2两个版本库
单版本库起动 svnserve -d -r /data/svn_data/repo1
多版本库起动 svnserve -d -r /data/svn_data/