什么是版本控制系統(VCS)
版本控制系統 (VCS) 是一個軟件,幫助軟件開發人員團隊工作並維持他們完整的工作歷史。 下面是版本控制系統(VCS) 的目標
- 允許開發者們同時工作
- 不會重寫每個人的改變
- 維持每個版本的全部的歷史
VCS 被分成兩種
- 集中版本控制系統 (CVCS)
- 分散或不集中的版本控制系統 (DVCS)
學習svn用到的術語
倉庫: 倉庫是任何一個版本系統的核心,它是開發者們保存工作的總部,倉庫不止處理文件還有歷史記錄,它需要訪問網絡,扮演服務器的角色,版本控制工具扮演客戶端的角色,客戶端可以連接倉庫,那么他們就可以從倉庫中存儲或者提取。通過保存這些更改,一個客戶端的更改可以被其他人檢索到,一個客戶端可以讓其他人的更改作為一個工作副本。 主干:trunk 是主要開發所在的目錄,經常被項目開發者們查看。 標簽:tags 目錄用於儲存項目中被命名的快照,標簽操作允許給予對倉庫中特定版本一個描述和一個難忘的名字。比如,LAST_STABLE_CODE_BEFORE_EMAIL_SUPPORT 比 Repository UUID: 7ceef8cb-3799-40dd-a067-c216ec2e5247 和Revision: 13 更令人難忘。 分支:分支操作用於創建開發的另一條線,當你想把開發進程復制進兩個不同的方向是很有用的。比如,當你發布 5.0 版本時,你可能想從 5.0 的 bug 修復中分離出來創建一個開發 6.0 功能的分支。 工作副本:工作副本是倉庫的一個快照。這個倉庫被所有的成員共享,但人們不直接修改它,相反每個開發者檢查這個工作副本,工作副本是一個私人的工作空間,這里開發者可以獨立於其他成員做自己的工作。 提交更改:提交是一個保存更改的過程,從私人工作空間到中央服務器。提交后,更改對全部成員可用,通過更新工作副本其他開發者提取這些更改。提交是一個原子操作,要么全部提交成功要么回滾,用戶絕不會看到一半完成提交。
svn
1.SVN
1.1簡介
SVN是Subversion的簡稱,是一個開放源代碼的跨平台的開源的版本控制系統,相較於RCS、CVS,它采用了分支管理系統,它的設計目標就是取代CVS。互聯網上很多版本控制服務已從CVS遷移到Subversion。說得簡單一點SVN就是用於多個人共同開發同一個項目,共用資源的目的
svn版本管理工具管理隨着時間改變的各種數據,這些數據放置在一個中央資料檔案庫中,svn會備份並記錄每個文件每一次的修改變動,這樣我們就可以把任意一個時間點的檔案恢復到一個舊的版本。
svn相關站點:
svn客戶端:http://www.tortoisesvn.net
官方手冊:http://svnbook.red-bean.com
svn與git的區別
svn:是集中式的版本控制系統,存在一個中央版本庫,所有開發人員本地開發所使用的代碼都是來源版本庫,提交代碼也必須要提交到這個版本庫
svn的備份要備份所有代碼數據,以及所有更改的版本記錄,也可以直接備份中央代碼庫
git:是分布式的版本控制系統,在git中,已經沒有了中央版本庫的說法了,但是有遠程和本地的完整的git倉庫,用來開發小組的代碼共享
其中本地和遠程倉庫中的代碼是等價的,沒有主從之分
1.2 運行方式,訪問方式和數據存儲
svn服務器有3種運行方式:
獨立服務器 :svn://svn.test.com/object
apache運行:http://svn.test.com/object
1.單獨安裝svn和apache服務器
2.第二種是csvn(apache+svn),是一個單獨整合個軟件,帶web界面的svn軟件
svn服務器本地直接訪問:file:///application/svndata/sadoc
svn客戶端的訪問方式:

數據存儲
svn存儲版本數據也有2種方式:BDB(一種事務安全型表類型)和FSFS(一種不需要數據庫的存儲系統)。因為BDB方式在服務器中斷時,有可能鎖住數據,所以還是FSFS方式更安全一點。
在svn1.2以前的版本使用BDB,1.2以后使用FSFS
SVN是基於關系數據庫的(BerkleyDB)或一系列二進制文件的(FS_FS)。一方面這解決了許多問題 (例如,並行讀寫共享文件)以及添加了許多新功能(例如運行時的事務特性。)。然而另一方面,數據存儲由此變得不透明。
1.3 svn版本系統邏輯架構原理

1.4 集中式管理工作的流程圖
集中式代碼管理的核心是服務器,所有開發者在開始新一天的工作之前必須從服務器獲取代碼,然后開發,最后解決沖突,提交。所有的版本信息都放在服務器上。如果脫離了服務器,開發者基本上可以說是無法工作的。下面舉例說明: 開始新一天的工作: 1、從服務器下載項目組最新代碼。 2、進入自己的分支,進行工作,每隔一個小時向服務器自己的分支提交一次代碼,很多人都有這個習慣。因為有時候自己對代碼改來改去,最后又想還原到前一個小時的版本,或者看看前一個小時自己修改了哪些代碼,就需要這樣做了。 3、下班時間快到了,把自己的分支合並到服務器主分支上,一天的工作完成,並反映給服務器。 這就是經典的svn工作流程,從流程上看,有不少缺點,但也有優點。優缺點參考
集中式管理工作的流程圖
2.配置SVN服務
2.1查看系統環境
[root@node1 /]# cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core) [root@node1 /]# uname -a Linux node1 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux [root@node1 /]# uname -r 3.10.0-693.el7.x86_64 [root@node1 /]# uname -m x86_64 [root@node1 /]#
2.2安裝svn(subversion)
檢查是否安裝了svn
[root@node1 /]# svn --version
-bash: svn: command not found
安裝svn
[root@node1 /]# yum install subversion -y
yum安裝rpm包本地不清除的方法
[root@node1 /]# cat /etc/yum.conf
keepcache=0 #0修改為1,rpm包下載后不清除
查看版本
[root@node1 /]# rpm -qa subversion
subversion-1.7.14-14.el7.x86_64
配置並啟動
1.建立svn版本庫數據存儲的目錄(svndata)及用戶,密碼權限目錄(svnpassword)
[root@node1 /]# mkdir -p application/svndata #數據存儲的根目錄
[root@node1 /]# mkdir -p application/svnpasswd #用戶密碼權限目錄
2.使用命令svnserve啟動服務
[root@node1 /]# svnserve -d -r /application/svndata || pkill svnserve 停止svn服務
svnserve -d -r 目錄 --listen-port 端口號
-d:表示啟動以守護進程的方式啟動
-r:配置方式決定了版本庫訪問方式
--listen-port:指定SVN監聽端口,不加此參數,SVN默認監聽3690
--listen-host:指定SVN監聽的host,不加此參數,默認全部監聽
--pid-file:存放進程號文件
更多svnserve參數:man svnserve
3.查看是否啟動,端口為3690
[root@node1 /]# ps -ef |grep svn
root 16304 1 0 18:59 ? 00:00:00 svnserve -d -r /application/svndata/
4.創建版本庫(可以創建多個,放置不同的代碼)
[root@node1 /]# svnadmin create /application/svndata/sadoc
svnadmin --help 可以查看svnadmin用法
5.調整svn配置文件及權限文件
[root@node1 conf]# cd /application/svndata/sadoc/conf #版本庫的配置文件目錄
[root@node1 conf]# ll
total 12
-rw-r--r-- 1 root root 1080 Nov 8 20:03 authz #用戶權限驗證文件
-rw-r--r-- 1 root root 309 Nov 8 20:03 passwd #用戶密碼文件
-rw-r--r-- 1 root root 3090 Nov 8 20:03 svnserve.conf #sadoc版本庫主配置文件,並且包含上面兩個配置文件
修改之前要做備份 tar -zcvf ./back_tar.gz .
編輯svnserve.conf修改以下四項:注意修改后要重新啟動
anon-access = none #不允許匿名訪問,read是允許匿名訪問
auth-access = write #是否支持用戶可寫
password-db = /application/svnpasswd/passwd #指定用戶密碼數據庫,方便統一管理
authz-db = /application/svnpasswd/authz #用戶權限數據庫
將用戶模板copy到配置文件指定的路徑里面
[root@node1 conf]# cp authz passwd /application/svnpasswd/
進入/application/svnpasswd修改文件屬性,增加安全性,只有root用戶可讀
[root@node1 svnpasswd]# chmod 700 *
編輯passwd添加賬號密碼,因為賬號密碼是明文的,所以上一步修改文件權限,修改后不用重新啟動
[root@node1 svnpasswd]# vim passwd
p0st = 123456
shuang = 123456
配置用戶權限文件
注意:
權限配置文件中出現的用戶名必須是已在用戶配置文件中定義過的
對權限配置文件的修改立即生效,不必重新啟動svn
[groups] #gtoups下面的變量就是組名,后面可抱哈你多個用戶名,用逗號隔開
# harry_and_sally = harry,sally
# harry_sally_and_joe = harry,sally,&joe
ett_wang = p0st,shuang
# [repository:/baz/fuz] 版本庫:/版本庫項目/項目目錄 #所以這里既可以給整個組賦權限,也可以給單個用戶賦權限
# @harry_and_sally = rw 用戶組名:權限
# * = r 用戶名:權限
[sadoc:/]
@ett_wang = rw
p0st = rw
shuang = r
其中方括號內部有很多種寫法
[/],表示根目錄及以下,這里的根目錄指的是svnserve啟動時指定的,[/]就表示對全部版本庫的設置權限
[svndata:/]表示對版本庫svndata設置權限
[svndata:/sadoc]表示對版本庫svndata中的sadoc設置權限
[svndata:/sadoc/test]表示對版本庫svndata中的sadoc項目的test項目設置權限
權限主體可以是用戶組,用戶,或者*,用戶組在前面加@。*表示全部用戶
權限可以是w,r,wr和空,空代表沒有任何權限
對於組,要以@開頭,用戶不需要@開頭
使用diff authz authz.bak 可以進行對比,查看文件不同
6.重啟svn服務:
[root@node1 svnpasswd]# pkill svnserve
[root@node1 svnpasswd]# svnserve -d -r /application/svndata/
注意: 更改svnserve.conf需要重啟svn,更改authz、passwd文件時不需要重啟;
檢查3690端口是否處於監聽狀態,至此svn服務器搭建完成;下面是svn客戶端的安裝與使用;
只有更改了svnserve.conf才需要重啟服務,剩下的更改都是立即生效的不需要重啟
2.3svn啟動方式
svnserve -d -r 目錄 --listen-port 端口號
-r: 配置方式決定了版本庫訪問方式。
--listen-port: 指定SVN監聽端口,不加此參數,SVN默認監聽3690
方式一:-r直接指定到版本庫(稱之為單庫svnserve方式)
svnserve -d -r /opt/svn/runoob
在這種情況下,一個svnserve只能為一個版本庫工作。
authz配置文件中對版本庫權限的配置應這樣寫:[groups]
admin=user1
dev=user2
[/]
@admin=rw
user2=r
使用類似這樣的URL:svn://192.168.0.1/ 即可訪問runoob版本庫
方式二:指定到版本庫的上級目錄(稱之為多庫svnserve方式)
svnserve -d -r /opt/svn
這種情況,一個svnserve可以為多個版本庫工作
authz配置文件中對版本庫權限的配置應這樣寫:
[groups]
admin=user1
dev=user2
[runoob:/]
@admin=rw
user2=r
[runoob01:/]
@admin=rw
user2=r
如果此時你還用[/],則表示所有庫的根目錄,同理,[/src]表示所有庫的根目錄下的src目錄。
使用類似這樣的URL:svn://192.168.0.1/runoob 即可訪問runoob版本庫。
2.3 連接svn服務器
windows:
下載tortoisesvn(windos上面svn工具),安裝,如果英文看不懂,可以安裝中文包漢化
輸入用戶名和密碼,復選框能讓tortoisesvn的缺省目錄:%APPDATA%\Subversion\auth的三個子目錄內保存認證信息
svn.simple:里面包含了進本的認證方式所需的認證信息,注意,密碼是通過wincrpty的api加密的不是明文
svn.ssl.server:里面包含了ssl服務器認證
svn.username:里面包含了用戶名的認證信息(不需要提供密碼)
新建一個文件夾用來接收svn現在的內容,在文件夾上右鍵就有很多功能了
linux:
在linux使用svn時,要安裝svn
查看svn中的數據
svn list svn://192.168.10.231/sadoc --username=p0st --password=123456
svn ls svn://192.168.10.231/sadoc --username=p0st --password=123456
svn ls svn://192.168.10.231/sadoc --username=p0st --password=123456 --verbose #可以顯示詳細的信息
svn cat svn://192.168.10.231/sadoc/hosts --username=p0st --password=123456 #可以查看文件內容
checkout:檢出文件到本地
svn checkout svn://192.168.10.231/sadoc /tmp --username=p0st --password=123456
命令 下載 地址 下載到哪里(本地服務器) 賬號密碼
add:往版本庫中添加新的文件,但是還沒提交進去
svn add hosts
將添加或者改動的文件提交到版本庫
svn commit -m “LogMessage“ [-N] [--no-unlock] PATH(如果選擇了保持鎖,就使用–no-unlock開關)
svn commit -m hosts
備注:提交多個文件中間用空格隔開如 svn ci -m "哈哈~~" test.php test2.php style.css
如果出現編碼錯誤的話,需要制定utf-8的編碼方式
export LC_CTYPE="en_US.UTF-8"
export LC_ALL=
locale
導入svn原始目錄樹 trunk(主干) branch(分支)tag(確定之后的版本號)
svn import
mkdir -p /svn/trunk /svn/branch /svn/tag
svn import /svn file:////application/svndata/ -m "import"
svn import /svn svn://192.168.10.231/sadoc/ --username=p0st --password=123456 -m “import是注釋”
將主干保存為分支
svn copy svn://192.168.10.231/sadoc/trunk svn://192.168.10.231/sadoc/branch/branch_cms_110623 -m "create a branch by p0st"
查看當前svn版本庫的信息svn info
svn://192.168.10.231/sadoc --username=p0st --password=123456
注意:要是用svn help 或者svn help add 等命令來查看怎么使用
3.svn鈎子腳本
3.1鈎子簡介
鈎子腳本的具體寫法就是操作系統中shell腳本程序的寫法,所謂鈎子就是與一些版本庫事件觸發的程序,例如新修訂版本的創建,或是未版本化屬性的修改。每個鈎子都會被告知足夠多的信息,包括那是什么事件,所操作的對象,和觸發事件的用戶名。通過鈎子的輸出或返回狀態,
鈎子程序能讓工作繼續、停止或是以某種方式掛起。類似inotify和sersync
對每種Subversion版本庫支持的鈎子的都有一個模板,通過查看這些腳本的內容,你能看到是什么事件觸發了腳本及如何給傳腳本傳遞數據。同時,這些模版也是如何使用這些腳本,結合Subversion支持的工具來完成有用任務的例子。要實際安裝一個可用的鈎子,
你需要在 repos/hooks目錄下安裝一些與鈎子同名(如 start-commit或者post-commit)的可執行程序或腳本。
提示:
由於安全原因,Subversion版本庫在一個空環境中執行鈎子腳本—就是沒有任何環境變量,甚至沒有$PATH或%PATH%。由於這個原因,許多管理員會感到很困惑,它們的鈎子腳本手工運行時正常,可在Subversion中卻不能運行。
要注意,必須在你的鈎子中設置好環境變量或為你的程序指定好絕對路徑。
必須要去掉項目里面鈎子的后綴名
3.2鈎子腳本
注意:svn鈎子的目錄在/application/svndata/sadoc/hooks下,該目錄已經提供了幾個鈎子的模板
常用的鈎子腳本
post-commint:在提交完成成功之后執行該鈎子,提交已經完成不會更改,因此,本腳本的返回值被忽略,不可更改,提交完成時觸發事物
1.svn更新自動周知,msn,郵件或者短信
2.svn更新觸發checkount程序,然后rsync實時推送到服務器等
#此腳本是在commit之后,svn版本庫進行更新,並且將版本庫里面的內容通過rsync推送到/oldboy備份
#!/bin/bash
#REPOS='$1'
#REV='$2'
#export LANG=en_US.UTF-8
#export LC_ALL=
#LOGPATH="/app/log.log"
#[ ! d $LOGPATH ] && mkdir ${LOGPATH} -p
#update content from svn
SVN=/usr/bin/svn
$SVN update --username p0st --password 123456 /tmp --no-auth-cache
#$SVN update --username p0st --password 123456 /tmp --no-auth-cache >>$LOGPATH 2>&1
if [[ $? -eq 0 ]]; then
/usr/bin/rsync -az --delete /tmp /oldboy/
fi
注意:
1.鈎子使用時,要去掉后綴名,可以cp post-commit.tmpl post-commit
2.如果是在windos寫的腳本,在linux上執行腳本要進行轉換格式 dos2unix post-commint 或者使用編輯器打開時:set ff=unix,然后:wq
3.鈎子要有執行權限,通常是700,如果有亂碼,可以將腳本中的文件系統的編碼注釋去掉,特別要注意環境變量的使用,可以查看狗子的模板中是怎么使用的
pre-commit:提交完成前執行該腳本
1.用作限制文件上傳大小和擴展名,控制提交要輸入的信息等
start-commit:在客戶端還沒有向服務器提交數據之前,即還沒有建立subversion transaction縮寫為(txn)之前,執行該鈎子(腳本)
不常用的鈎子腳本
svn通過ldap統一認證
4.大中小企業代碼發布解決方案
4.1svn目錄組織結構說明
[root@node1 svndata]# pwd /application/svndata [root@node1 svndata]# ls -al drwxr-xr-x 6 root root 58 Nov 9 20:06 . drwxr-xr-x 4 root root 38 Nov 9 17:22 .. drwxr-xr-x 2 root root 6 Nov 9 20:06 branch #分支,為測試使用,幾天上線的項目必須開分支,測試需要本分支通過,主線合並到分支通過,才能合並到主線進行測試 drwxr-xr-x 6 root root 86 Nov 9 17:23 sadoc #版本庫 drwxr-xr-x 2 root root 6 Nov 9 20:06 tags #版本記錄使用 drwxr-xr-x 2 root root 6 Nov 9 20:06 trunk #主線,與正式線相對應,當天不上線文件不允許提交
4.2大中小企業上線解決方案
小型企業上線架構方案

小型企業上線構架方案建議
1.開發人員需在個人電腦上搭建lamp環境測試開發號的網站代碼,並且在辦公室或idc機房的測試環境測試通過,最好有專職的測試人員
2.程序代碼上線要規定時間。例如,三天一上線,如網站需經常更新課每天下午17點上線,這個看網站業務性質而定,原則上就是能最小的影響用戶體驗最好
3.代碼上線之前需要備份。網站程序出了問題方便回退。另外,從上線技巧上講,上傳代碼是盡可能的先上傳到網站的臨時目錄,上傳完整之后一步mv過去,或者通過ln做軟連接,比較嚴格的更新代碼,將服務器從集群下線(平滑下線),然后更新
4.盡量由運維人員管理上線,對於代碼的功能性開發人員更在意,而對於代碼的性能和服務的穩定運維更在意。因此如果網站問題歸運維管,就要讓運維上線,這樣更科學,否則,開發隨意更新,出了問題運維負責,這樣就錯了
中型企業上線架構方案
中型企業上線構架方案建議
一般是規范運維人員操作步驟,指定統一的上線操作腳本,備份文件名稱,備份文件路徑。使操作人性化,統一化,自動化
大型企業上線架構方案
在大型集群環境一般有數台集群機器,因此要分批更新。
下面是java環境代碼上線:
1.本地開發人員從svn中抽取代碼,當天上線的提交到trunk,否則,長期項目單開分支開發,然后合並主線(trunk)
2.辦公內網開發測試時,由開發人員或者配置管理員通過部署jenkins實現統一部署(即在部署平台式控制開發機器從SVN版本庫中checkout代碼,編譯,打包,發布到開發機,idc_dep.war)
3.開發人員和測試人員一起測試程序,沒有出現問題后,打上新的tag標記
4.配置管理員,根據上步的tag標記,checkout出上線代碼,平配置好idc測試環境的所有配置,執行編譯,打包(mvn,ant,php不需要打包),然后發布到idc內的統一分發服務器,這里要注意,不同的配置文件是隨着代碼同時發布的
5.配置管理員或sa上線人員,把分發的程序代碼內容推送到相關的測試服務器(包名如:idc_test.war),然后通知開發及測試人員進行測試,如果有問題向上回滾到內網開發測試從新測試修改
6.如果測試沒有問題,繼續打好tag標記,此時配置管理員根據上步的tag標記,checkout出測試好的代碼,並配置好idc正式環境的所有配置,執行編譯,打包(mvn,ant),然后發布到idc內的統一分發服務器主機上,准備批量發布
7.配置管理員和sa上線人員,把分發的內容推送到相關的正式服務器(包名:idc_product.war),然后通知開發以及測試人員進行測試,如果有問題,直接發布回滾指令
注意:idc正式上線的過程對於java程序來說,可以將集群上的服務器分為ab兩組分批上線的思路,即在流量較少的時候平滑下線一半的服務器,在測試集群掛上服務器。然后進行代碼測試,無問題后,在正式集群掛上服務器,同時在平滑下線另一半的服務器,然后發布更新代碼測試(或者直接發布就上線)如果前端有dns智能解析,上線還可以分地區的若干服務器,逐漸普及到全國的服務器,這個稱為灰度發布
4.3大中小企業上線注意事項
代碼上線解決方案注意事項:
1.上線的流程里,辦公測試環境->idc測試環境->正式生產環境,所有的環境中所有的軟件版本統一,盡量單一。例如:操作系統,web服務器,jdk版本,php,tomcat,resin等版本
2.開發團隊小組辦公內部測試環境測試(該測試環境屬於開發小組維護,或定時自動更新代碼),代碼有問題返回給開發人員重新開發
3.有專門的測試工程師,程序有問題直接返回給開發人員(此時返回的一般為程序的bug,稱為bug庫),無問題則進行idc測試
4.idc測試有測試人員和運維人員參與,叫idctest,進行程序的壓力測試,有問題直接返回給開發人員,無問題直接環境上線
5.書台服務器代碼分發上線(java程序)
1)假設有六台服務器,將服務器分為ab兩組,a三台,b三台,先對a組從負載均衡服務器上平滑下線,b組正常提供服務器,避免服務器因線上影響業務
2)下線過程中通過腳本將a組服務器從集群中踢出,避免負載均衡器將請求發給a組服務器
3)將代碼發到a租服務器的站點目錄下,對a組服務器在測試負載均衡器上線並重啟,並有專門的測試人員進行訪問測試,測試成功后,在正式負載均衡器上掛上a租服務器的同事,下線b組服務器,b組服務器做和a組等同操作,期間也要及時觀察上線服務器的裝魯昂,有問題及時回滾
6.如果php上線:發布代碼時,可以直接發布到正式服務器的臨時目錄,然后mv或者直接link的方式發布到正式線目錄,不需要重啟服務,當然測試也是少不了的,測試出了測試是否正常以外,還需要測試各個相關業務接口
7.大多數門戶網站的前端都已經靜態化或者cache了,因此動態的部分訪問平時就不會特別多,流量低谷時就號了,再加上是平滑上下線,用戶感知更小
php程序上線的具體方案 對於php上線:發布代碼時,可以直接發布到正式服務器的臨時目錄,然后mv或者直接link的方式發布到正式線目錄,不需要重啟服務
4.4svn服務器上到底要包含什么?
1)svn上存放代碼(不含資源,大公司的網站資源和程序都是分離的),在上線的時候盡可能要全量上線,因為我們要保證svn的代碼是最新的 2)存放服務的配置文件(lamp環境等配置) 開發小組測試使用的配置文件 辦公環境測試使用的配置文件 idc環境測試使用的配置文件 線上應用使用的配置文件