SVN是Subversion的簡稱,是一個開放源代碼的版本控制系統,可以超越時間的管理文件和目錄。文件保存在中央版本庫,除了能記住文件和目錄的每次修改以外,版本庫非常像普通的文件服務器。你可以將文件恢復到過去的版本,並且可以通過檢查歷史知道數據做了哪些修改,誰做的修改。這就是爲什麼許多人將 Subversion 和版本控制系統看作一種「時間機器」。說得簡單一點SVN就是用於多個人共同開發同一個項目,共用資源的目的。

svn與git的區別
svn
  svn版本控制系統是集中式的數據管理,存在一箇中央版本庫。所有開發人員本地開發使用的代碼都是來自這個版本庫,提交代碼也都必須提交到這個中央版本庫。
svn工作流程:
1、在中央版本庫中創建一個項目,項目中包含主幹和分支,分支是從主幹複製的;
2、開發人員從中央版本庫check out下這個分支的代碼;
3、增加自己的代碼、修改或刪除現存的代碼;
4、commit 代碼,如果修改期間其他人提交了代碼,就會提示過期無法提交,就需要先up,之後再提交;如果up代碼時出現衝突,就需要解決衝突之後在提交(開發人員協商解決衝突);
5、測試環境測試,解決問題之後合併到主幹中,在之後更新生產環境代碼;
缺點:
1、嚴重依賴網絡環境,連接不到中央版本庫時無法工作;
2、需要備份-------->需要備份數據和修改的歷史記錄

git
  git是分佈式版本控制系統,沒有中央版本庫的說法,和svn不同的是,開發者本地有一個完整的git倉庫,但是實際使用中需要建立一個遠程的git倉庫,以方便共享代碼和版本控制;
git工作流程:
1、本地創建一個git庫,並將其add到遠程git庫中;
2、在本地添加、刪除、修改文件,然後commit,此時commit是提交到本地git倉庫中;
3、將本地git庫分支push到遠程git庫的分支,如果此時遠程已經有別人push過,那遠程git將不允許你push,必須先pull。並解決衝突之後才能在push到遠程git庫;
優點:
1、開發時不依賴網絡,隨時commit到本地,和隨時查看修改歷史,只有在合併代碼時才需要連接遠程git倉庫;
2、svn還是主流,git正在發展,將來會成爲主流,都掌握會更好;

svn運維人員需要掌握的程度:
1、安裝、部署、維護、排障;
2、簡單使用,很多公司都是有開發來管理,包括建立倉庫和添加刪除賬號。
3、對於版本控制系統---->運維相當於開發商,開發人員是業主,運維搭建的系統爲開發人員服務。

svn之運行方式和訪問方式:
服務端運行方式:
1、獨立服務器訪問:(svn://svn.etiantian.org/www/)
2、和apache等http服務結合:(http://svn.etiantian.org/www/)
    a、單獨安裝apache+svn;
    b、csvn()是一個整合好的一體軟件,帶有web管理頁面的svn軟件;
3、本地直接訪問:(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上的源代碼同步,你手上的代碼就會有最新的變更。

安裝配置SVN服務:
[[email protected] ~]# cat /etc/redhat-release
CentOS release 6.8 (Final)
[[email protected] ~]# uname -r                
2.6.32-642.el6.x86_64
[[email protected] ~]# rpm -qa subversion
[[email protected] ~]# yum -y install subversion
[[email protected] ~]# sed -i 's/keepcache=0/keepcache=1/g' /etc/yum.conf
[[email protected] ~]# grep "keepcache" /etc/yum.conf
keepcache=1  //rpm包下載安裝後不清除
[[email protected] ~]# mkdir -p /application/svndata <==數據存儲的根目錄
[[email protected] ~]# mkdir -p /application/svnpasswd <==用戶及密碼和權限目錄
[[email protected] ~]# svn
svn            svnlook        svnversion
svnadmin       svnserve       
svndumpfilter  svnsync   
[[email protected] ~]# svnserve --help
usage: svnserve [-d | -i | -t | -X] [options]
Valid options:
  -d [--daemon] //以守護進程的方式運行 : daemon mode
  -r [--root] ARG //指定存儲的根目錄   : root of directory to serve
其它剩餘參數省略。。。。。。
[[email protected] ~]# svnserve -d -r /application/svndata/ #啓動SVN服務並指定數據存儲的根目錄
[[email protected] ~]# ps -ef| grep svn|grep -v grep
root       8554      1  0 23:48 ?        00:00:00 svnserve -d -r /application/svndata/
[[email protected] ~]# netstat -tunlp|grep svn
tcp        0      0 0.0.0.0:3690                0.0.0.0:*                   LISTEN      8554/svnserve  
[[email protected] ~]# lsof -i:3690
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
svnserve 8554 root    3u  IPv4  20242      0t0  TCP *:svn (LISTEN)

創建項目版本庫:
[[email protected] ~]# 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
[[email protected] ~]# 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
[[email protected] ~]# svnadmin create /application/svndata/sadoc
[[email protected] ~]# ll /application/svndata/
total 4
drwxr-xr-x. 6 root root 4096 Oct 26 23:58 sadoc
[[email protected] ~]# 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


調整svn配置文件及權限文件:
[[email protected] ~]# cd /application/svndata/sadoc/conf/
[[email protected] conf]# cp svnserve.conf svnserve.conf.bak
[[email protected] 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  
[[email protected] 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  //權限配置數據文件
[[email protected] conf]# egrep "\-access|\-db =" svnserve.conf
anon-access = none
auth-access = write
password-db = /application/svnpasswd/passwd
authz-db = /application/svnpasswd/authz
[[email protected] conf]# ls
authz  passwd  svnserve.conf  svnserve.conf.bak
[[email protected] conf]# cp authz passwd /application/svnpasswd/
[[email protected] 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
[[email protected] conf]# cd /application/svnpasswd/
[[email protected] 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
[[email protected] svnpasswd]# chmod 700 *  //修改密碼文件(passwd)、權限配置文件(authz)的文件權限爲700,提高安全。安全無小事,但是,重視的運維卻少的可憐。
[[email protected] svnpasswd]# ll
total 8
-rwx------. 1 root root 1080 Oct 27 00:29 authz
-rwx------. 1 root root  309 Oct 27 00:29 passwd
[[email protected] svnpasswd]# vi passwd
[users]
# harry = harryssecret
# sally = sallyssecret
linuxzkq = 123456   //添加用戶與密碼,注意必須在[users]標籤下添加。
guest = guest   //添加用戶與密碼,等號前面是用戶名,後面是密碼。

提示:更改svnserve.conf文件時,需要重啓svn,更改passwd、authz文件時不需要重啓。
[[email protected] svnpasswd]# vi authz
在最下面添加配置權限如下:
[groups]
linux = linuxzkq,guest  //定義用戶組及所包含的用戶,其中,1個用戶組可以包含1個或多個用戶,用戶間以逗號分隔。
[sadoc:/]
linuxzkq = rw   //用戶訪問權限
guest = r
@linux = r   //用戶組訪問權限
* =   //* = 表示,除了linuxzkq、guest用戶、linux用戶組,任何人都被禁止訪問版本庫
注意:
權限配置文件中出現的用戶名必須已在用戶配置文件中定義。

用戶組格式:    
[groups]
= ,
其中,1個用戶組可以包含1個或多個用戶,用戶間以逗號分隔。

版本庫目錄格式:
[<版本庫>:/項目/目錄]
@<用戶組名> = <權限>
<用戶名> = <權限>
其中,方框號內部分可以有多種寫法:
[/],表示根目錄及以下,根目錄是svnserve啓動時指定的,[/]就是表示對全部版本庫設置權限。
權限主體可以是用戶組、用戶或*,用戶組在前面加@
權限可以是w、r、wr和空,空表示沒有任何權限。

重啓svn命令<非必需>:
kill -USR1 `cat /application/svndata/svn.pid`
svnserve -d -r /application/svndata/ --pid-file=/application/svndata/svn.pid
[[email protected] svnpasswd]# pkill svnserve
[[email protected] 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客戶端命令的使用:
[[email protected] ~]# 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/
[[email protected] ~]# mkdir /svndata
[[email protected] ~]# 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.
[[email protected] ~]# ll /svndata/
total 0
-rw-r--r--. 1 root root 0 Oct 27 23:41 22.txt
[[email protected] ~]#  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
[[email protected] ~]# 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
[[email protected] ~]#  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
[[email protected] ~]# 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
[[email protected] ~]#  svn co svn://192.168.0.111/sadoc/ /svndata/ --username=guest --password=guest
A    /svndata/666.txt
Checked out revision 4.
[[email protected] ~]# 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
[[email protected] ~]# 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.
[[email protected] ~]# svn list svn://192.168.0.111/sadoc      

22/
22.txt
33.bmp
666.txt
新建文本文檔 (2).txt
新建文本文檔.txt
[[email protected] ~]# touch /svndata/{a..d}
[[email protected] ~]# cd /svndata/
[[email protected] ~]# touch /svndata/{a..d}
[[email protected] 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
[[email protected] 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.
[[email protected] svndata]#  svn ci -m "svn ci data" /svndata/
Adding         {rr..tt}.txt
Transmitting file data .
Committed revision 8.
[[email protected] 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
[[email protected] 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
[[email protected] 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
[[email protected] 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
[[email protected] svndata]# svn up /svndata                   

D    /svndata/新建文本文檔.txt
A    /svndata/777.txt
Updated to revision 11.
[[email protected] 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
[[email protected] 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:

--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]

For example:

servers:global:http-library=serf

svn鉤子:
  鉤子腳本的具體寫法就是操作系統中shell腳本程序的寫法,可根據自己的SVN所在的操作系統和shell程序進行相應的開發。
  鉤子腳本就是被某些版本庫事件觸發的程序,例如:創建新版本或修改未被版本控制的屬性。每個鉤子都能掌管足夠的信息來了解發生了什麼事件,操作對像是什麼以及觸發事件用戶的賬號。類似inotify或sersync。
  通過鉤子的輸出或返回狀態,鉤子程序能讓該動作繼續執行、停止或是以某種方式掛起。
  默認情況下,鉤子的子目錄中包含各種版本庫鉤子模板。如下:
[[email protected] ~]# 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中卻不能運行。要注意,必須在你的鉤子中設置好環境變量或爲你的程序指定好絕對徑。

常用鉤子腳本:
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鉤子生產應用實戰:
一、rsync與svn鉤子結合實現數據實時同步(某企業小案例)
1.建立同步web目錄
mkdir /data/www
[[email protected] ~]# mkdir /data/www -p
[[email protected] ~]# ll /data/www/
total 0
2.將SVN中內容checkout到web目錄一份。
[[email protected] ~]# 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.
[[email protected] ~]# 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.利用鉤子同步程序到遠程服務器
[[email protected] ~]# cd  /application/svndata/sadoc/hooks
[[email protected] hooks]# cp post-commit.tmpl post-commit
[[email protected] hooks]# mv post-commit post-commit.ori
[[email protected] 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
[[email protected] hooks]# chmod 700 post-commit
[[email protected] hooks]# ll /tmp
total 0
-rw-------. 1 root root 0 Oct 26 21:56 yum.log
[[email protected] 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的相關參數一定要清楚,這個就不說了。注意幾個場景:
場景一、如果目的WEB服務器爲綜合的混雜的,像只有一個WEB靜態資源,用戶提交的,自動生成的都在WEB的一個目錄下,建議不要用--delete這個參數
上面這個程序就是這樣,實現的是源服務器到目的服務器的更新和添加,而沒有刪除操作,WEB服務器的內容會多於源SVN的服務器的

場景二、實現鏡像,即目的WEB服務器與源SVN服務器一樣的數據,SVN上任何變化WEB上一樣的變化,就需要--delete參數

場景三、不需要同步某些子目錄,可能有些目錄是緩存的臨時垃圾目錄,或者是專用的圖片目錄(而不是樣式或者排版的)要用exclude這個參數

  注意:這個參數的使用不用寫絕對路徑,只要目錄名稱就行 aa代表文件 aa/ 代表目錄 ,缺點就是如果有多個子目錄都是一樣的名稱 那麼這些名稱就都不會被同步
  建議用--exclude-from=/home/svn/exclude.list 用文件的形式可以方便的添加和刪除
exclude.list
  利用SVN的鉤子還可以寫出很多的程序來控制SVN 如代碼提交前查看是否有寫日誌,是否有tab,有將換成空格,是否有不允許上傳的文件,是否有超過限制大小的文件等等。
  最重要的是看幫助,如看post-commit默認的幫助

 [[email protected] 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/

二、利用pre-commit限制上傳文件擴展名及大小
參考:
http://blog.chinaunix.net/uid-22646981-id-2921564.html
http://blog.chinaunix.net/uid-22646981-id-2921557.html

[[email protected] ~]# 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
[[email protected] ~]# 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
[[email protected] ~]# cd /application/svndata/sadoc/hooks/
[[email protected] 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
[[email protected] hooks]# chmod 700 pre-commit

大中小型企業上線解決方案:
SVN目錄組織結構說明
trunk <==主線(分支),與正式線相對應,當天不上線文件不允許提交。
branches <==分支,爲測試時使用,幾天以上的項目必須開分支,測試需要本分支通過,主線合併到分支通過,才能合併到主線進行測試。
tags <==版本記錄用

SVN上線解決方案說明:
1.小型公司代碼上線案例(通過FTP隨時隨地上傳更新代碼)
wKiom1gWP0ThewUpAAHYZmD_S0k454.png-wh_50

1、一般公司人員少,爲了方便都隨時隨地更新,發佈快;
2、經常不經測試人員測試就上線,拿用戶來測試,用戶體驗較差;
3、據統計網站中50%的故障都是和代碼有關,但都是運維人員承擔責任。

建議:
a、開發人員需在個人電腦搭建LNMP/LAMP環境進行測試代碼,並且在辦公室或IDC機房的測試環境測試通過,最好有專職測試人員。
b、規定代碼上線時間,比如三天一上線,滿足需求的同時也要有原則,一切爲了客戶體驗度;
c、代碼上線之前需要備份,出了問題方便回滾(新浪做法:先傳到臨時目錄,傳完整後再直接mv過去,或做軟鏈接)

 線上更新代碼的思路。如果嚴格更新,把應用服務器從集羣節點平滑下線,然後再更新。
d、上線儘量由運維人員管理操作上線,對於代碼的功能性,開發人員更在意,而對於代碼的性能優化和上線後服務器的穩定,運維更在意服務器的穩定,因此,如果網站宕機問題歸運維管,就要讓運維控制上線更科學。否則開發隨意更新上傳,出了問題運維負責,這樣就太不科學了。

2.中型企業上線解決方案

wKioL1gWP4PiS40EAAEQuqFaA6Q733.png-wh_50

  中型企業上線,一般是規範運維人員的步驟,制定統一的上線腳本、備份腳本、回滾腳本,備份文件名稱,備份文件路徑,降低損失。使操作人性化,統一化,自動化。

3.大型企業上線解決方案

wKiom1gWP_WgaaHkAANkX2s4Wz8705.png-wh_50

大型企業上線,一般制度和流程控制較多,比較嚴謹。
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的管理,上線管理,流程申請,業務協調等工作。

平滑代碼上線是什麼?
  就是在網站代碼更新時,不影響正在瀏覽用戶的正常瀏覽網頁或其正使用的其他相關應用。