SVN是Subversion的简称,是一个开放源代码的版本控制系统,能够超越时间的管理文件和目录。文件保存在中央版本库,除了能记住文件和目录的每次修改之外,版本库很是像普通的文件服务器。你能够将文件恢复到过去的版本,而且能够经过检查历史知道数据作了哪些修改,谁作的修改。这就是为何许多人将 Subversion 和版本控制系统看做一种“时间机器”。说得简单一点SVN就是用于多我的共同开发同一个项目,共用资源的目的。
svn与git的区别
svn
svn版本控制系统是集中式的数据管理,存在一个中央版本库。全部开发人员本地开发使用的代码都是来自这个版本库,提交代码也都必须提交到这个中央版本库。
svn工做流程:
一、在中央版本库中建立一个项目,项目中包含主干和分支,分支是从主干复制的;
二、开发人员从中央版本库check out下这个分支的代码;
三、增长本身的代码、修改或删除现存的代码;
四、commit 代码,若是修改期间其余人提交了代码,就会提示过时没法提交,就须要先up,以后再提交;若是up代码时出现冲突,就须要解决冲突以后在提交(开发人员协商解决冲突);
五、测试环境测试,解决问题以后合并到主干中,在以后更新生产环境代码;
缺点:
一、严重依赖网络环境,链接不到中央版本库时没法工做;
二、须要备份-------->须要备份数据和修改的历史记录
git
git是分布式版本控制系统,没有中央版本库的说法,和svn不一样的是,开发者本地有一个完整的git仓库,可是实际使用中须要创建一个远程的git仓库,以方便共享代码和版本控制;
git工做流程:
一、本地建立一个git库,并将其add到远程git库中;
二、在本地添加、删除、修改文件,而后commit,此时commit是提交到本地git仓库中;
三、将本地git库分支push到远程git库的分支,若是此时远程已经有别人push过,那远程git将不容许你push,必须先pull。并解决冲突以后才能在push到远程git库;
优势:
一、开发时不依赖网络,随时commit到本地,和随时查看修改历史,只有在合并代码时才须要链接远程git仓库;
二、svn仍是主流,git正在发展,未来会成为主流,都掌握会更好;
svn运维人员须要掌握的程度:
一、安装、部署、维护、排障;
二、简单使用,不少公司都是有开发来管理,包括创建仓库和添加删除帐号。
三、对于版本控制系统---->运维至关于开发商,开发人员是业主,运维搭建的系统为开发人员服务。
svn之运行方式和访问方式:
服务端运行方式:
一、独立服务器访问:(svn://svn.etiantian.org/www/)
二、和apache等http服务结合:(http://svn.etiantian.org/www/)
a、单独安装apache+svn;
b、csvn()是一个整合好的一体软件,带有web管理页面的svn软件;
三、本地直接访问:(file://application/data/www/)
客户端访问方式:
访问方式 说明
file:// 直接访问本地磁盘或网络磁盘访问版本库
http:// 经过webdav协议访问支持subversion的apache服务器
https:// 与http://相似,只是用了ssl加密访问
svn:// 经过TCP/IP自定义协议访问subversion服务器
svn+ssh:// 经过认证并加密的TCP/IP自定义协议访问subversion服务器
SVN中的一些概念 :
(1). repository(源代码库)
源代码统一存放的地方
(2). Checkout (提取)
当你手上没有源代码的时候,你须要从repository checkout一份
(3). Commit (提交)
当你已经修改了代码,你就须要Commit到repository
(4). Update (更新)
当你已经Checkout了一份源代码, Update一下你就能够和Repository上的源代码同步,你手上的代码就会有最新的变动。
php
安装配置SVN服务:
[root@moban ~]# cat /etc/redhat-release
CentOS release 6.8 (Final)
[root@moban ~]# uname -r
2.6.32-642.el6.x86_64
[root@moban ~]# rpm -qa subversion
[root@moban ~]# yum -y install subversion
[root@moban ~]# sed -i 's/keepcache=0/keepcache=1/g' /etc/yum.conf
[root@moban ~]# grep "keepcache" /etc/yum.conf
keepcache=1 //rpm包下载安装后不清除
[root@moban ~]# mkdir -p /application/svndata <==数据存储的根目录
[root@moban ~]# mkdir -p /application/svnpasswd <==用户及密码和权限目录
[root@moban ~]# svn
svn svnlook svnversion
svnadmin svnserve
svndumpfilter svnsync
[root@moban ~]# svnserve --help
usage: svnserve [-d | -i | -t | -X] [options]
Valid options:
-d [--daemon] //以守护进程的方式运行 : daemon mode
-r [--root] ARG //指定存储的根目录 : root of directory to serve
其它剩余参数省略。。。。。。
[root@moban ~]# svnserve -d -r /application/svndata/ #启动SVN服务并指定数据存储的根目录
[root@moban ~]# ps -ef| grep svn|grep -v grep
root 8554 1 0 23:48 ? 00:00:00 svnserve -d -r /application/svndata/
[root@moban ~]# netstat -tunlp|grep svn
tcp 0 0 0.0.0.0:3690 0.0.0.0:* LISTEN 8554/svnserve
[root@moban ~]# lsof -i:3690
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
svnserve 8554 root 3u IPv4 20242 0t0 TCP *:svn (LISTEN)
建立项目版本库:
[root@moban ~]# svnadmin --help
general usage: svnadmin SUBCOMMAND REPOS_PATH [ARGS & OPTIONS ...]
Type 'svnadmin help <subcommand>' 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@moban ~]# svnadmin help create
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@moban ~]# svnadmin create /application/svndata/sadoc
[root@moban ~]# ll /application/svndata/
total 4
drwxr-xr-x. 6 root root 4096 Oct 26 23:58 sadoc
[root@moban ~]# tree /application/svndata/
/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
html
调整svn配置文件及权限文件:
[root@moban ~]# cd /application/svndata/sadoc/conf/
[root@moban conf]# cp svnserve.conf svnserve.conf.bak
[root@moban conf]# grep "^[a-Z]" /application/svndata/sadoc/conf/svnserve.conf
anon-access = none
auth-access = write
password-db = /application/svnpasswd/passwd
authz-db = /application/svnpasswd/authz
[root@moban conf]# diff svnserve.conf.bak svnserve.conf
12,13c12,13
< # anon-access = read //匿名用户访问权限
< # auth-access = write //认证用户访问权限
---
> anon-access = none
> auth-access = write
20c20
< # password-db = passwd //密码认证文件
---
> password-db = /application/svnpasswd/passwd
27c27
< # authz-db = authz
---
> authz-db = /application/svnpasswd/authz //权限配置数据文件
[root@moban conf]# egrep "\-access|\-db =" svnserve.conf
anon-access = none
auth-access = write
password-db = /application/svnpasswd/passwd
authz-db = /application/svnpasswd/authz
[root@moban conf]# ls
authz passwd svnserve.conf svnserve.conf.bak
[root@moban conf]# cp authz passwd /application/svnpasswd/
[root@moban conf]# ll /application/svnpasswd/
total 8
-rw-r--r--. 1 root root 1080 Oct 27 00:29 authz
-rw-r--r--. 1 root root 309 Oct 27 00:29 passwd
[root@moban conf]# cd /application/svnpasswd/
[root@moban svnpasswd]# ll
total 8
-rw-r--r--. 1 root root 1080 Oct 27 00:29 authz
-rw-r--r--. 1 root root 309 Oct 27 00:29 passwd
[root@moban svnpasswd]# chmod 700 * //修改密码文件(passwd)、权限配置文件(authz)的文件权限为700,提升安全。安全无小事,可是,重视的运维却少的可怜。
[root@moban svnpasswd]# ll
total 8
-rwx------. 1 root root 1080 Oct 27 00:29 authz
-rwx------. 1 root root 309 Oct 27 00:29 passwd
[root@moban svnpasswd]# vi passwd
[users]
# harry = harryssecret
# sally = sallyssecret
linuxzkq = 123456 //添加用户与密码,注意必须在[users]标签下添加。
guest = guest //添加用户与密码,等号前面是用户名,后面是密码。前端
提示:更改svnserve.conf文件时,须要重启svn,更改passwd、authz文件时不须要重启。
[root@moban svnpasswd]# vi authz
在最下面添加配置权限以下:
[groups]
linux = linuxzkq,guest //定义用户组及所包含的用户,其中,1个用户组能够包含1个或多个用户,用户间以逗号分隔。
[sadoc:/]
linuxzkq = rw //用户访问权限
guest = r
@linux = r //用户组访问权限
* = //* = 表示,除了linuxzkq、guest用户、linux用户组,任何人都被禁止访问版本库
注意:
权限配置文件中出现的用户名必须已在用户配置文件中定义。
用户组格式:
[groups]
= ,
其中,1个用户组能够包含1个或多个用户,用户间以逗号分隔。
java
版本库目录格式:
[<版本库>:/项目/目录]
@<用户组名> = <权限>
<用户名> = <权限>
其中,方框号内部分能够有多种写法:
[/],表示根目录及如下,根目录是svnserve启动时指定的,[/]就是表示对所有版本库设置权限。
权限主体能够是用户组、用户或*,用户组在前面加@
权限能够是w、r、wr和空,空表示没有任何权限。
重启svn命令<非必需>:
kill -USR1 `cat /application/svndata/svn.pid`
svnserve -d -r /application/svndata/ --pid-file=/application/svndata/svn.pid
[root@moban svnpasswd]# pkill svnserve
[root@moban svnpasswd]# svnserve -d -r /application/svndata/ --pid-file=/application/svndata/svn.pid
客户端软件windows安装使用:
windows 64位的话下载:TortoiseSVN-1.7.6.22632-x64-svn-1.7.4.msi
windows 32位的话下载:TortoiseSVN-1.6.5.16974-win32-svn-1.6.5.msi
具体的下载文件能够在网上下载下,一找一大堆
经过客户端进行访问,地址以下:
svn://{your-server-ip}/sadoc
用户名:guest
密码:guest
linux下Svn客户端命令的使用:
[root@moban ~]# svn --help
usage: svn <subcommand> [options] [args]
Subversion command-line client, version 1.6.11.
Type 'svn help <subcommand>' for help on a specific subcommand.
Type 'svn --version' to see the program version and RA modules
or 'svn --version --quiet' to see just the version number.
Most subcommands take file and/or directory arguments, recursing
on the directories. If no arguments are supplied to such a command, it recurses on the current directory (inclusive) by default.
Available subcommands:
add
blame (praise, annotate, ann)
cat
changelist (cl)
checkout (co) //从源码库提取一个工做版本的拷贝,经常使用的
cleanup
commit (ci) //提交当前工做拷贝的更改。这个地方是有可能出现代码冲突的。经常使用的
copy (cp) //作一个工做拷贝的拷贝
delete (del, remove, rm) //删除本地或者svn server response上的文件或目录
diff (di) //比较某个文件与库中的对应文件的不一样,相似于系统的diff命令。
export //导出一个无版本控制的目录树拷贝。通常用于导出发行,或者投入运行的版本
help (?, h)
import //将本地当前目录下的文件导入到svn response中。
info //当前目录工做拷贝中某文件信息,如URL,版本,修改日期等。
list (ls) //列出当前工做拷贝下的文件,至关于系统ls命令。
lock
log
merge //将两个来源之间的差别应用到工做拷贝路径。
mergeinfo
mkdir //在本地或者svn reponse上新建一个文件夹。
move (mv, rename, ren)
propdel (pdel, pd)
propedit (pedit, pe)
propget (pget, pg)
proplist (plist, pl)
propset (pset, ps)
resolve
resolved
revert
status (stat, st) //svn工做拷贝当前状态,与svn server上的源码比较的结果。
switch (sw)
unlock
update (up) //将svn server端文件同步到本地,经常使用的。
Subversion is a tool for version control.
For additional information, see http://subversion.tigris.org/
[root@c6 ~]# mkdir /svndata
[root@c6 ~]# svn co svn://192.168.0.111/sadoc/ /svndata/ --username=guest --password=guest
-----------------------------------------------------------------------
ATTENTION! Your password for authentication realm:
<svn://192.168.0.111:3690> 10073e1b-bf6e-4d4c-b01f-1358a1a9a561
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
A /svndata/22.txt
Checked out revision 1.
Checked out revision 1.
[root@c6 ~]# ll /svndata/
total 0
-rw-r--r--. 1 root root 0 Oct 27 23:41 22.txt
[root@c6 ~]# svn up svn://192.168.0.111/sadoc/ /svndata/ --username=guest --password=guest
Skipped 'svn://192.168.0.111/sadoc'
A /svndata/33.bmp
Updated to revision 2.
Summary of conflicts:
Skipped paths: 1
[root@c6 ~]# ll /svndata/
total 0
-rw-r--r--. 1 root root 0 Oct 27 23:41 22.txt
-rw-r--r--. 1 root root 0 Oct 27 23:49 33.bmp
[root@c6 ~]# svn up svn://192.168.0.111/sadoc/ /svndata/ --username=guest --password=guest
Skipped 'svn://192.168.0.111/sadoc'
A /svndata/22
Updated to revision 3.
Summary of conflicts:
Skipped paths: 1
[root@c6 ~]# ll /svndata/
total 4
drwxr-xr-x. 3 root root 4096 Oct 27 23:51 22
-rw-r--r--. 1 root root 0 Oct 27 23:41 22.txt
-rw-r--r--. 1 root root 0 Oct 27 23:49 33.bmp
[root@c6 ~]# svn co svn://192.168.0.111/sadoc/ /svndata/ --username=guest --password=guest
A /svndata/666.txt
Checked out revision 4.
[root@c6 ~]# ll /svndata/
total 4
drwxr-xr-x. 3 root root 4096 Oct 27 23:51 22
-rw-r--r--. 1 root root 0 Oct 27 23:41 22.txt
-rw-r--r--. 1 root root 0 Oct 27 23:49 33.bmp
-rw-r--r--. 1 root root 0 Oct 27 23:53 666.txt
[root@moban ~]# svn co file:///application/svndata/sadoc //在服务端本地以文件的方式访问提取,文件提取只适用于服务端本地访问。
A sadoc/666.txt
A sadoc/22.txt
A sadoc/33.bmp
A sadoc/22
Checked out revision 4.
[root@c6 ~]# svn list svn://192.168.0.111/sadoc
linux
22/
22.txt
33.bmp
666.txt
新建文本文档 (2).txt
新建文本文档.txt
[root@c6 ~]# touch /svndata/{a..d}
[root@c6 ~]# cd /svndata/
[root@c6 ~]# touch /svndata/{a..d}
[root@c6 svndata]# svn add a b c d e f g
A a
A b
A c
A d
svn: warning: 'e' not found
svn: warning: 'f' not found
svn: warning: 'g' not found
[root@c6 svndata]# svn ci -m "svn ci data" /svndata/ --username=linuxzkq --password=123456
-----------------------------------------------------------------------
ATTENTION! Your password for authentication realm:
<svn://192.168.0.111:3690> 10073e1b-bf6e-4d4c-b01f-1358a1a9a561
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
Adding a
Adding b
Adding c
Adding d
Transmitting file data ....
Committed revision 7.
[root@c6 svndata]# svn ci -m "svn ci data" /svndata/
Adding {rr..tt}.txt
Transmitting file data .
Committed revision 8.
[root@c6 svndata]# svn list svn://192.168.0.111/sadoc
22/
22.txt
33.bmp
666.txt
a
b
c
d
{rr..tt}.txt
新建文本文档 (2).txt
新建文本文档.txt
[root@c6 svndata]# svn up svn://192.168.0.111/sadoc /svndata
Skipped 'svn://192.168.0.111/sadoc'
D /svndata/新建文本文档 (2).txt
A /svndata/新建 Microsoft Excel 工做表.xlsx
Updated to revision 9.
Summary of conflicts:
Skipped paths: 1
[root@c6 svndata]# ll
total 12
drwxr-xr-x. 3 root root 4096 Oct 28 00:40 22
-rw-r--r--. 1 root root 0 Oct 27 23:41 22.txt
-rw-r--r--. 1 root root 0 Oct 27 23:49 33.bmp
-rw-r--r--. 1 root root 0 Oct 27 23:53 666.txt
-rw-r--r--. 1 root root 0 Oct 28 00:35 a
-rw-r--r--. 1 root root 0 Oct 28 00:35 b
-rw-r--r--. 1 root root 0 Oct 28 00:35 c
-rw-r--r--. 1 root root 0 Oct 28 00:35 d
-rw-r--r--. 1 root root 0 Oct 28 00:45 {rr..tt}.txt
-rw-r--r--. 1 root root 6327 Oct 28 00:54 新建 Microsoft Excel 工做表.xlsx
-rw-r--r--. 1 root root 0 Oct 28 00:03 新建文本文档.txt
[root@c6 svndata]# svn up svn://192.168.0.111/sadoc /svndata
Skipped 'svn://192.168.0.111/sadoc'
D /svndata/22
D /svndata/新建 Microsoft Excel 工做表.xlsx
D /svndata/{rr..tt}.txt
A /svndata/888l.xlsx
Updated to revision 10.
Summary of conflicts:
Skipped paths: 1
[root@c6 svndata]# svn up /svndata
git
D /svndata/新建文本文档.txt
A /svndata/777.txt
Updated to revision 11.
[root@c6 svndata]# ll
total 8
-rw-r--r--. 1 root root 0 Oct 27 23:41 22.txt
-rw-r--r--. 1 root root 0 Oct 27 23:49 33.bmp
-rw-r--r--. 1 root root 0 Oct 27 23:53 666.txt
-rw-r--r--. 1 root root 0 Oct 28 00:58 777.txt
-rw-r--r--. 1 root root 6327 Oct 28 00:56 888l.xlsx
-rw-r--r--. 1 root root 0 Oct 28 00:35 a
-rw-r--r--. 1 root root 0 Oct 28 00:35 b
-rw-r--r--. 1 root root 0 Oct 28 00:35 c
-rw-r--r--. 1 root root 0 Oct 28 00:35 d
[root@c6 svndata]# svn help copy
copy (cp): Duplicate something in working copy or repository, remembering
history.
usage: copy SRC[@REV]... DST
When copying multiple sources, they will be added as children of DST,
which must be a directory.
SRC and DST can each be either a working copy (WC) path or URL:
WC -> WC: copy and schedule for addition (with history)
WC -> URL: immediately commit a copy of WC to URL
URL -> WC: check out URL into WC, schedule for addition
URL -> URL: complete server-side copy; used to branch and tag
All the SRCs must be of the same type.
WARNING: For compatibility with previous versions of Subversion,
copies performed using two working copy paths (WC -> WC) will not
contact the repository. As such, they may not, by default, be able
to propagate merge tracking information from the source of the copy
to the destination.
Valid options:
-r [--revision] ARG : ARG (some commands also take ARG1:ARG2 range)
A revision argument can be one of:
NUMBER revision number
'{' DATE '}' revision at start of the date
'HEAD' latest in repository
'BASE' base rev of item's working copy
'COMMITTED' last commit at or before BASE
'PREV' revision just before COMMITTED
-q [--quiet] : print nothing, or only summary information
--ignore-externals : ignore externals definitions
--parents : make intermediate directories
-m [--message] ARG : specify log message ARG
-F [--file] ARG : read log message from file ARG
--force-log : force validity of log message source
--editor-cmd ARG : use ARG as external editor
--encoding ARG : treat value as being in charset encoding ARG
--with-revprop ARG : set revision property ARG in new revision
using the name[=value] format
Global options:web
--username ARG : specify a username ARG
--password ARG : specify a password ARG
--no-auth-cache : do not cache authentication tokens
--non-interactive : do no interactive prompting
--trust-server-cert : accept unknown SSL server certificates without
prompting (but only with '--non-interactive')
--config-dir ARG : read user configuration files from directory ARG
--config-option ARG : set user configuration option in the format:
FILE:SECTION:OPTION=[VALUE]shell
For example:apache
servers:global:http-library=serf
svn钩子:
钩子脚本的具体写法就是操做系统中shell脚本程序的写法,可根据本身的SVN所在的操做系统和shell程序进行相应的开发。
钩子脚本就是被某些版本库事件触发的程序,例如:建立新版本或修改未被版本控制的属性。每一个钩子都能掌管足够的信息来了解发生了什么事件,操做对像是什么以及触发事件用户的帐号。相似inotify或sersync。
经过钩子的输出或返回状态,钩子程序能让该动做继续执行、中止或是以某种方式挂起。
默认状况下,钩子的子目录中包含各类版本库钩子模板。以下:
[root@moban ~]# tree /application/svndata/sadoc/hooks/
/application/svndata/sadoc/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 //开始提交的
0 directories, 9 files
对每种Subversion版本库支持的钩子都有一个模板,经过查看这些脚本的内容,你能看到是什么事件触发了脚本及如何传脚本,传递数据。
要实际安装一个可用的钩子,你须要在 repos/hooks目录下安装一些与钩子同名(如 start-commit或者post-commit)的可执行程序或脚本。注意:去掉模板的扩展名。
重要提示:
因为安全缘由,Subversion版本库在一个空环境中执行钩子脚本—就是没有任何环境变量,甚至没有$PATH或%PATH%。因为这个缘由,许多管理员会感到很困惑,它们的钩子脚本手工运行时正常,可在Subversion中却不能运行。要注意,必须在你的钩子中设置好环境变量或为你的程序指定好绝对径。
windows
经常使用钩子脚本:
1.post-commit
在提交成功完成、建立版本以后执行该钩子,提交已经完成,不可更改。所以,本脚本的返回值被忽略。提交完成时触发事务。
2.pre-commit
提交完成前触发执行该脚本。
3.start-commit
在客户端尚未向服务器提交数据以前,即尚未创建Subversion transaction(缩写为txn)以前,执行该脚本(提交前触发事务)
svn钩子生产应用场景举例:
pre-commit
1.限制上传文件扩展名及大小,控制提交要输入的信息等。
post-commit
2.SVN更新自动通知,MSN,邮件或短信通知。
3.SVN更新触发checkout程序,而后实时rsync推送到服务器等。
svn钩子生产应用实战:
1、rsync与svn钩子结合实现数据实时同步(某企业小案例)
1.创建同步web目录
mkdir /data/www
[root@c6 ~]# mkdir /data/www -p
[root@c6 ~]# ll /data/www/
total 0
2.将SVN中内容checkout到web目录一份。
[root@c6 ~]# svn co svn://192.168.0.111/sadoc /data/www --username=guest --password=guest
-----------------------------------------------------------------------
ATTENTION! Your password for authentication realm:
<svn://192.168.0.111:3690> 10073e1b-bf6e-4d4c-b01f-1358a1a9a561
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
A /data/www/666.txt
A /data/www/888l.xlsx
A /data/www/a
A /data/www/22.txt
A /data/www/b
A /data/www/33.bmp
A /data/www/777.txt
A /data/www/c
A /data/www/d
Checked out revision 11.
[root@c6 ~]# ll /data/www
total 8
-rw-r--r--. 1 root root 0 Oct 28 08:28 22.txt
-rw-r--r--. 1 root root 0 Oct 28 08:28 33.bmp
-rw-r--r--. 1 root root 0 Oct 28 08:28 666.txt
-rw-r--r--. 1 root root 0 Oct 28 08:28 777.txt
-rw-r--r--. 1 root root 6327 Oct 28 08:28 888l.xlsx
-rw-r--r--. 1 root root 0 Oct 28 08:28 a
-rw-r--r--. 1 root root 0 Oct 28 08:28 b
-rw-r--r--. 1 root root 0 Oct 28 08:28 c
-rw-r--r--. 1 root root 0 Oct 28 08:28 d
3.利用钩子同步程序到远程服务器
[root@moban ~]# cd /application/svndata/sadoc/hooks
[root@moban hooks]# cp post-commit.tmpl post-commit
[root@moban hooks]# mv post-commit post-commit.ori
[root@moban hooks]# vi post-commit
建立svn钩子脚本(post-commit):
#!/bin/sh
#设定环境变量,若是没有设定可能会出现update报错
export LC_CTYPE="en_US.UTF-8"
export LC_ALL=
REPOS="$1"
REV="$2"
SVN_PATH="/usr/bin/svn"
WEB_PATH="/data/www"
LOG_PATH="/app/log"
RSYNC_PATH="/usr/bin/rsync"
#/usr/bin/svn update --username user --password password $WEB_PATH --no-auth-cache
#echo "\n##############开始提交" `date "+%Y-%m-%d %H:%M:%S"` '##################' >>$LOG_PATH
#echo `whoami`,$REPOS,$REV >>$LOG_PATH
[ ! -d ${LOG_PATH} ] && mkdir ${LOG_PATH} -p
#update content from svn
$SVN_PATH update --username linuxzkq --password 123456 $WEB_PATH >>$LOG_PATH/up_$(date +%F_%H:%M:%S).log 2>&1
if [ $? -eq 0 ]
then
$RSYNC_PATH -az --delete $WEB_PATH /tmp/
fi
[root@moban hooks]# chmod 700 post-commit
[root@moban hooks]# ll /tmp
total 0
-rw-------. 1 root root 0 Oct 26 21:56 yum.log
[root@moban hooks]# ll /tmp/www
total 16
-rw-r--r--. 1 root root 0 Oct 27 13:45 100.txt
-rw-r--r--. 1 root root 0 Oct 27 13:28 123.bmp
-rw-r--r--. 1 root root 6327 Oct 27 13:45 200.xlsx
-rw-r--r--. 1 root root 0 Oct 27 13:28 22.txt
-rw-r--r--. 1 root root 0 Oct 27 13:36 55.txt
-rw-r--r--. 1 root root 0 Oct 27 13:36 66.bmp
-rw-r--r--. 1 root root 0 Oct 27 13:34 7.txt
-rw-r--r--. 1 root root 0 Oct 27 13:42 8888.bmp
写svn钩子脚本的一些注意事项:
1.钩子脚本的权限要容许svn执行,通常能够设置chmod 700 post-commit。
2.写钩子脚本时要尽量定义环境变量,主要是用过的命令的全路径。由于svn考虑安全问题,不会调用系统环境变量,因此若是发现手动执行post-commit没有问题,但SVN自动执行也可能会没法执行。
3.老男孩老师提供的案例脚本,在SVN update以前必定要先手动checkout一份出来,还有尽量要加上用户名和密码,若是只是手动同样会更新,但自动触发可能就不能更新了。
4.加上了对前一个命令的判断,若是update的时候出了问题,程序没有退出的话还会继续同步代码到WEB服务器上,这样会形成代码有问题。
5.记得要设置所属用户,由于rsync能够同步文件属性,并且咱们的WEB服务器通常都不是root用户,用户不正确会形成WEB程序没法正常工做。
6.建议最好记录日志,出错的时候能够很快的排错。
7.最后最关键的数据同步,rsync的相关参数必定要清楚,这个就不说了。注意几个场景:
场景1、若是目的WEB服务器为综合的混杂的,像只有一个WEB静态资源,用户提交的,自动生成的都在WEB的一个目录下,建议不要用--delete这个参数
上面这个程序就是这样,实现的是源服务器到目的服务器的更新和添加,而没有删除操做,WEB服务器的内容会多于源SVN的服务器的
场景2、实现镜像,即目的WEB服务器与源SVN服务器同样的数据,SVN上任何变化WEB上同样的变化,就须要--delete参数
场景3、不须要同步某些子目录,可能有些目录是缓存的临时垃圾目录,或者是专用的图片目录(而不是样式或者排版的)要用exclude这个参数
注意:这个参数的使用不用写绝对路径,只要目录名称就行 aa表明文件 aa/ 表明目录 ,缺点就是若是有多个子目录都是同样的名称 那么这些名称就都不会被同步
建议用--exclude-from=/home/svn/exclude.list 用文件的形式能够方便的添加和删除
exclude.list
利用SVN的钩子还能够写出不少的程序来控制SVN 如代码提交前查看是否有写日志,是否有tab,有将换成空格,是否有不容许上传的文件,是否有超过限制大小的文件等等。
最重要的是看帮助,如看post-commit默认的帮助
[root@moban hooks]# more post-commit.tmpl
#!/bin/sh
# POST-COMMIT HOOK
#
# The post-commit hook is invoked after a commit. Subversion runs
# this hook by invoking a program (script, executable, binary, etc.)
# named 'post-commit' (for which this file is a template) with the
# following ordered arguments:
#
# [1] REPOS-PATH (the path to this repository)
# [2] REV (the number of the revision just committed)
#
# The default working directory for the invocation is undefined, so
# the program should set one explicitly if it cares.
#
# Because the commit has already completed and cannot be undone,
# the exit code of the hook program is ignored. The hook program
# can use the 'svnlook' utility to help it examine the
# newly-committed tree.
#
# On a Unix system, the normal procedure is to have 'post-commit'
# invoke other programs to do the real work, though it may do the
# work itself too.
#
# Note that 'post-commit' must be executable by the user(s) who will
# invoke it (typically the user httpd runs as), and that user must
# have filesystem-level permission to access the repository.
#
# On a Windows system, you should name the hook program
# 'post-commit.bat' or 'post-commit.exe',
# but the basic idea is the same.
#
# The hook program typically does not inherit the environment of
# its parent process. For example, a common problem is for the
# PATH environment variable to not be set to its usual value, so
# that subprograms fail to launch unless invoked via absolute path.
# If you're having unexpected problems with a hook program, the
# culprit may be unusual (or missing) environment variables.
#
# Here is an example hook script, for a Unix /bin/sh interpreter.
# For more examples and pre-written hooks, see those in
# the Subversion repository at
# http://svn.apache.org/repos/asf/subversion/trunk/tools/hook-scripts/ and
# http://svn.apache.org/repos/asf/subversion/trunk/contrib/hook-scripts/
2、利用pre-commit限制上传文件扩展名及大小
参考:
http://blog.chinaunix.net/uid-22646981-id-2921564.html
http://blog.chinaunix.net/uid-22646981-id-2921557.html
[root@moban ~]# svnlook --help
general usage: svnlook SUBCOMMAND REPOS_PATH [ARGS & OPTIONS ...]
Note: any subcommand which takes the '--revision' and '--transaction'
options will, if invoked without one of those options, act on
the repository's youngest revision.
Type 'svnlook help <subcommand>' for help on a specific subcommand.
Type 'svnlook --version' to see the program version and FS modules.
Available subcommands:
author
cat
changed
date
diff
dirs-changed
help (?, h)
history
info
lock
log
propget (pget, pg)
proplist (plist, pl)
tree
uuid
youngest
[root@moban ~]# svnlook help log
log: usage: svnlook log REPOS_PATH
Print the log message.
Valid options:
-r [--revision] ARG : specify revision number ARG
-t [--transaction] ARG : specify transaction name ARG
[root@moban ~]# cd /application/svndata/sadoc/hooks/
[root@moban hooks]# vi pre-commit
#!/bin/sh
REPOS="$1"
TXN="$2"
#此处更改大小限制,为5M
MAX_SIZE=5242880
#此处限制文件后缀名
FILTER='\.(zip|rar|o|obj|tar|gz)$'
# Make sure that the log message contains some text.
SVNLOOK=/usr/bin/svnlook
######svnlook log/cat
#svn提交时有个参数 -m 用来记录提交信息,下面这一段是为了验证提交信息长度(规范操做嘛,不然svn里真的是一堆垃圾了)
#LOGMSG=`$SVNLOOK log -t "$TXN" "$REPOS"|grep "[a-zA-Z0-9]"|wc -c`
LOGMSG=`$SVNLOOK log -t "$TXN" "$REPOS"|wc -c`
if [ "$LOGMSG" -lt 9 ];
then
echo -e "Log message cann't be empty! you must input more than 8 chars as comment!" 1>&2
exit 1
fi
files=$($SVNLOOK changed -t "$TXN" "$REPOS"|cut -d " " -f 4-)
#echo "$files">&2
#echo "$r">&2
#exit 1
rc=0
echo "$files"|while read f;
do
#check file type
if echo $f|tr A-Z a-z|grep -Eq $FILTER;
then
echo "File $f is not allow ($FILTER) file" 1>&2
exit 1;
fi
#check file size
filesize=`$SVNLOOK cat -t "$TXN" "$REPOS" "$f"|wc -c`
if [ "$filesize" -gt "$MAX_SIZE" ];
then
echo "File $f is too large(must <=$MAX_SIZE) Byte" 1>&2
exit 1
fi
done
#All checks passed,so allow the commit.
if [ $? -eq 1 ];
then
exit 1
else
exit 0
fi
[root@moban hooks]# chmod 700 pre-commit
大中小型企业上线解决方案:
SVN目录组织结构说明
trunk <==主线(分支),与正式线相对应,当天不上线文件不容许提交。
branches <==分支,为测试时使用,几天以上的项目必须开分支,测试须要本分支经过,主线合并到分支经过,才能合并到主线进行测试。
tags <==版本记录用
SVN上线解决方案说明:
1.小型公司代码上线案例(经过FTP随时随地上传更新代码)
一、通常公司人员少,为了方便都随时随地更新,发布快;
二、常常不经测试人员测试就上线,拿用户来测试,用户体验较差;
三、据统计网站中50%的故障都是和代码有关,但都是运维人员承担责任。
建议:
a、开发人员需在我的电脑搭建LNMP/LAMP环境进行测试代码,而且在办公室或IDC机房的测试环境测试经过,最好有专职测试人员。
b、规定代码上线时间,好比三天一上线,知足需求的同时也要有原则,一切为了客户体验度;
c、代码上线以前须要备份,出了问题方便回滚(新浪作法:先传到临时目录,传完整后再直接mv过去,或作软连接)
线上更新代码的思路。若是严格更新,把应用服务器从集群节点平滑下线,而后再更新。
d、上线尽可能由运维人员管理操做上线,对于代码的功能性,开发人员更在乎,而对于代码的性能优化和上线后服务器的稳定,运维更在乎服务器的稳定,所以,若是网站宕机问题归运维管,就要让运维控制上线更科学。不然开发随意更新上传,出了问题运维负责,这样就太不科学了。
2.中型企业上线解决方案
中型企业上线,通常是规范运维人员的步骤,制定统一的上线脚本、备份脚本、回滚脚本,备份文件名称,备份文件路径,下降损失。使操做人性化,统一化,自动化。
3.大型企业上线解决方案
大型企业上线,通常制度和流程控制较多,比较严谨。
1.特别是JAVA代码环境,上线时,有数台机器同时须要更新或者分批更新:
1).本地开发人员取svn代码。当天上线提交到trunk,不然,长期项目单开分支开发,而后在合并主线(trunk)
2).办公内网开发测试时,由开发人员或配置管理员经过部署平台jenkins实现统一部署,(即在部署平台上控制开发机器从svn取代码,编译,打包,发布到开发机,包名如idc_dep.war).
3).开发人员通知或和测试人员一块儿测试程序,没有问题后,由配置管理员打上新的tag标记。这里要注意,不一样环境的配置文件是随代码同时发布的。
4).配置管理员,根据上一步的tag标记,checkout出上线代码,并配置好IDC测试环境的全部配置,执行编译,打包(mvn,ant)(php不须要打包),而后发布到IDC内的统一分发服务器。
5).配置管理员或SA上线人员,把分发的程序代码内容推送到相关测试服务器(包名如idc_test.war),而后通知开发及测试人员进行测试。若是有问题向上回退,继续修改。
6).若是IDC测试没有问题,继续打好tag标记,此时,配置管理员,根据上步的tag标记,checkout出测试好的代码,并配置好IDC正式环境的全部配置,执行编译,打包(mvn,ant)(php不须要打包),而后发布到IDC内的统一分发服务器主机,准备批量发布。
7).配置管理员或SA上线人员,把分发的内容推送到相关正式服务器(包名如idc_product.war),而后通知开发及测试人员进行测试。若是有问题直接发布回滚指令。
IDC正式上线的过程对于JAVA程序,能够是AB组分组上线的思路,即平滑下线一半的服务器,而后发布更新代码,重启测试,无问题后,挂上更新后的服务器,同时再平滑下线另外一半的服务器,而后发布更新代码测试(或者直接发布后,重启,挂上线)
php程序代码上线的具体方案:
对于PHP上线方法:发布代码时(也须要测试流程)能够直接发布到正式线临时目录 ,而后mv或更改link的方式发布到正式上线目录 ,不须要重启http服务。这是新朗,赶集的上线方案。
JAVA程序代码上线的具体方案:
对于java上线方法:较大公司须要分组平滑上线(如从负载均衡器上摘掉一半的服务器),发布代码后,重启服务器测试,没问题后,挂上上好线的一半,再下另一半。若是前端有DNS智能解析,上线还能够分地区上线若干服务器,逐渐普及到全国的服务器,这个被称为“灰度发布”,在后面门户网站上线的知识里咱们在讲解。
代码上线解决方案注意事项: 1).上线的流程里,办公室测试环境-->IDC测试环境-->正式生产环境,全部环境中的全部软件均应版本统一,其次尽可能单一,不然将后患无穷,开发测试成功,IDC测试就可能有问题(如:操做系统,web服务器,jdk,php,tomcat,resin等版本) 2).开发团队小组办公内部测试环境测试(该测试环境属于开发小组维护,或定时自动更新代码),代码有问题返回给某开发人员从新开发。 3).有专门的测试工程师,程序有问题直接返回给开发人员(此时返回的通常为程序的BUG,称为BUG库),无问题进行IDC测试 4).IDC测试由测试人员和运维人员参与,叫IDCtest,进行程序的压力测试,有问题直接返回给开发人员,无问题进行线上环境上线。 5).数台服务器代码分发上线方案举例(JAVA程序) A:假设同业务服务器有6台,将服务器分为A,B两组,A组三台,B组三台,先对A组进行从负载均衡器上平滑下线,B组正常提供服务,避免服务器因上线影响业务。 B:下线过程是经过脚本将A组服务器从RS池(LVS,NGINX,HAPROXY,F5等均有平滑方案)中踢出,避免负裁均衡器将请求发送给A组服务器(此时的时间应该为网站流量少时,通常为晚上) C:将代码分发到A组服务器的站点目录下,对A组服务器上线并重启服务,并由专业的测试人员进行访问测试,测试成功后,挂上A组的服务器,同时下线B组服务器,B组代码上线操做测试等和A组相同,期间也要观察上线提供服务的服务器情况,有问题及时回滚。 6).特别说明:若是是PHP程序,则上线能够简单化,直接将上线代码(最好全量)发布到全部上线服务器的特定目录后,分发完成后,一次性mv或ln到站点目录,固然测试也是少不了的。测试除了人员测试外,还有各类测试脚本测试各个相关业务接口。 7).大多数门户公司的前端页面都已经静态化或者cache了,所以,动态的部分访问平时就不会特别多,流量低谷时就更少了。再加上是平滑上下线,所以基本上是对用户体验无影响的,固然,也有上线出问题的状况,这个是避免不了的。 8)SVN上包含代码和配置 (1)、SVN上存放程序代码(不含资源,大公司基本资源和程序都是分离的) 尽量全量上线的缘由:由于咱们务必要保证SVN的代码是最新的。 (2)、存放全部服务的配置文件(LAMP环境,如:apache的httpd.conf配置文件) a)、开发小组测试环境使用的配置文件 b)、办公测试环使用配置文件 c)、IDC测试使用的配置文件 d)、线上应用使用的配置文件在上线不一样环境时,由配置管理员协调上线。什么时配置管理员? 就是在开发和运维中间起一个链接纽带的一个职位,这个职位通常在大公司里会设置,负责SVN的管理,上线管理,流程申请,业务协调等工做。平滑代码上线是什么? 就是在网站代码更新时,不影响正在浏览用户的正常浏览网页或其正使用的其余相关应用。