爲什麼要使用SVN?
程序員在編寫程序的過程中,每個程序員都會生成很多不同的版本,這就需要程序員有效的管理代碼,在需要的時候可以迅速,準確取出相應的版本。
Subversion是什麼?
它是一個自由/開源的版本控制系統,一組文件存放在中心版本庫,記錄每一次文件和目錄的修改,Subversion允許把數據恢復到早期版本,或是檢查數據修改的歷史,Subversion可以通過網絡訪問它的版本庫,從而使用戶在不同的電腦上進行操作。
關於SVN
一、SVN工作原理
SVN(SubVersion)的基本工作思路是這樣的:在一臺服務器上建立一個源代碼庫,庫裏可以存放許多不同項目的源程序,由源代碼庫管理員統一管理這些源程序。
每個用戶在使用源代碼庫之前,首先要把源代碼庫裏的項目文件下載到本地(Checkout),然後用戶可以在本地任意修改,最後用svn命令進行提交(Commit),由svn源代碼庫統一管理修改。如下圖:
- SVN服務器:運行SubVersion服務的計算機,SubVersion支持Linux和Windows,更多的是安裝在Linux下。SVN提供服務有兩種方式(運行方式):獨立服務器和藉助Apache服務器,分別使用SVN協議和Http協議。
- SVN客戶端:用戶通過SVN客戶端同SVN服務器打交道,SVN客戶端分爲命令行工具和圖形化工具。最流行的客戶端是TortoiseSVN。也可以在Eclipse中使用SVN插件。
二、SubVersion的使用
可以在http://subversion.apache.org/packages.html下載SVN並安裝(本文使用windows版本,過程不多說)。在SVN中集成了服務器端和客戶端組件:
- 服務器組件(管理員用):svnadmin、svnserve
- 客戶端組件(程序員用):svn
這些組件命令都位於SubVersion安裝目錄下的bin目錄下。
友情提示:安裝完SVN後,通過”svnadmin –version”驗證是否安裝成功。如果出現錯誤“svnadmin不是內部或外部命令”,則需要手動將SVN的bin目錄加入到path環境變量下。
1、創建SVN倉庫
1)先創建一個目錄:E:\svnrepo\repoDemo1。後面就使用該目錄作爲SVN倉庫。
2)創建倉庫:svnadmin create E:\svnrepo\repoDemo1。創建倉庫後的目錄結構如下:
3)啓動SVN服務:svnserve -d -r E:\svnrepo\repoDemo1,如下圖:
這樣就啓動了repoDemo1這個倉庫的服務(單倉庫),如果在svnrepo目錄下還有其他倉庫,且要同時啓動多個倉庫,執行svnserve -d -r E:\svnrepo即可(多倉庫)。
一般情況下,訪問SVN倉庫的URL格式形如:svn://192.168.1.6/repoDemo1,但如果啓動的是單倉庫,則URL直接用:svn://192.168.1.6表示。svn協議的默認端口號爲3690。
小技巧:如果需要頻繁使用該倉庫,則可將該SVN服務註冊成windows服務,這樣在計算機開機時就可以啓動該服務。如下圖:
刪除該windows服務:sc delete svnService。
2、SVN客戶端操作(命令行)
重點:checkout(檢出)、commit(提交)、update(更新)
1)在E盤下建立user1、user2兩個目錄,模擬兩個協同工作的用戶的workspace。
2)檢出:第一次和SVN服務器交互時,需要使用checkout將倉庫檢出到本地。
說明:檢出一次,就建立了與SVN倉庫的連接。
3)提交:commit
在user1目錄下新建Demo1.java文件,將該文件提交到SVN倉庫。下圖演示了三種典型的錯誤提交。
4)更新:update
切換到user2的工作空間(user2目錄下),user2第一次使用SVN倉庫,需要檢出。user2修改Demo1.java後提交。切換到user1目錄,更新(update)。
5)刪除與恢復:delete、revert
說明:如果delete後,提交到服務器(commit),則服務器上的數據也被刪除了(慎用)。
三、SVN的目錄約定
- /trunck:開發主線
- /branches:支線副本
- /tags:標籤副本(一旦創建,不允許修改)
1)使用trunk作爲主要的開發目錄
一般的,我們的所有的開發都是基於trunk進行開發,當一個版本(release)開發告一段落(開發、測試、文檔、製作安裝程序、打包等結束後),代碼處於凍結狀態(人爲規定,可以通過hook來進行管理)。此時應該基於當前凍結的代碼庫,打tag。
當下一個版本/階段的開發任務開始時,繼續在trunk進行開發。此時,如果發現了上一個已發行版本(Released Version)有一些bug,或者一些很急迫的功能要求,而正在開發的版本(Developing Version)無法滿足時間要求,這時候就需要在上一個版本上進行修改了。解決方法是基於發行版對應的tag,做相應的分支(branch)進行開發。
2)下圖爲struts2的SVN倉庫目錄:
現在Struts2的代碼使用git管理,所以現在查看Struts2的SVN倉庫是空的。
TortoiseSVN是現在最流行的SVN客戶端工具,使用圖形化界面和SVN倉庫交互(作爲命令行方式的替代)。關於TortoiseSVN的安裝省略。
安裝完成後,在任意位置右擊都能看到TortoiseSVN選項。
1、基本操作
1)創建倉庫
創建目錄:E:\svnrepo\repoDemo2,進入該目錄下,右擊 — TortoiseSVN — Create repository here,並創建默認的SVN目錄結構,如下圖所示:
2)檢出:checkout
在E盤下建立user3、user4兩個目錄,模擬兩個協同工作的用戶的workspace。
進入user3目錄下,右擊 — SVN Checkout,在URL of repository中輸入:file:///E:/svnrepo/repoDemo2。【此時倉庫還沒有啓動SVN服務,所以使用file://】
3)提交:commit
在user3/trunk目錄下新建Demo1.java,在該文件上右擊 — TortoiseSVN — add,則將Demo1.java納入版本控制。然後右擊 — SVN Commit,提交至代碼倉庫。
4)更新:update
對user4進行上面的檢出操作。並修改user4目錄下的Demo1.java(如增加一個字段),並commit。
回到user3/trunk,右擊 — SVN Update。
5)啓動SVN服務。這步需要在命令行中輸入:svnserve -d -r E:\svnrepo
6)訪問SVN倉庫。在任意空白位置右擊 — TortoiseSVN — Repo browser,URL輸入:svn://192.168.1.6/repoDemo2即可瀏覽SVN倉庫中的內容,如下。
2、其他操作
下面的操作都位於右鍵菜單的TortoiseSVN中。
1)刪除:delete
刪除文件或目錄,不能直接用Windows的刪除命令來操作,那樣只是沒有顯示出來,實際並沒有刪除,在更新後,刪除的文件又會被更新出來的。要想從庫中 刪除,必須選中你要刪除的內容,TortoiseSVN — delete,這樣纔會將這個文件標記成要刪除的。確認需要刪除後,使用前面所講的提交命令,就會真正的在庫中刪除了。
2)重命名:rename
重命名也不能直接用Windows的重命名命令來操作,必須選中你要重命名的文件,TortoiseSVN — rename。修改後提交就可以更新到倉庫。
改名的處理方式相當於新增了一個以新名稱命名的文件,原名稱命名的文件進行了刪除。
3)還原:revert
在未提交之前,你對前面做的操作反悔了,可以使用revert來恢復。
4)檢查更新:Check for modifications
① 此功能可以顯示你所做的修改有哪些還沒有提交的。② 還可以看到版本庫裏的改動,即別人提交了哪些文件的改動,你還沒更新到本地。
5)導出:export
使用SVN的工作空間每個目錄下面都有一個.svn隱藏目錄,利用SVN的export命令可輕鬆地導出不含.svn目錄的工作空間。
3、衝突問題的解決(☆)
何時發生:接 着4.1節中的操作,假設user3和user4目錄下的Demo1.java都更新到了最新版本。user3修改Demo1.java,提交至倉庫。若 user4也修改Demo1.java並提交,此時user4的TortoiseSVN會報提交版本過時的錯誤,並提醒user4需要更新,更新時就會發 生衝突。如下圖:
對於每個更新衝突的文件,Subversion會在衝突文件所在目錄下放置了三個文件:
- Demo1.java.mine:發生衝突時的本地版本。
- Demo1.java.r3:最後更新之後的本地版本。
- Demo1.java.r4:倉庫中的最新版本。
解決方法 1:
① 在Demo1.java上右擊 — TortoiseSVN — Edit conflicts,這時你需要確定哪些代碼是需要的,做一些必要的修改然後保存。小技巧:編輯衝突時,可使用直接複製需要的代碼到Merged窗口即可。
② 編輯完成後保存,直接選擇Mark as resolved,即標記爲衝突已解決。退出編輯衝突窗口,發現衝突發生時生成的三個文件被自動刪除了,且Demo1.java變成了未提交狀態。
③ commit,OK。
解決方法 2:
直接修改Demo1.java,把其中的一些標記刪除即可(前提是服務器上的和本地的內容都需要保存)。
4、TortoiseSVN圖標
部分圖標的說明:
- normal:狀態正常
- modified:對本地的副本做了修改,需要提交到服務器
- conflicted:有衝突
- readonly:文件是隻讀的,要修改必須先獲取鎖
- locked:獲得鎖
- deleted:計劃從版本庫中刪除
- added:已被計劃納入版本控制
- non-versioned:未納入版本控制
5、認證與授權
所謂認證(Authentication),就是給使用該倉庫的用戶分配一個用戶名和密碼,用戶在連接倉庫的時候需要輸入用戶名/密碼。授權 (Authorization)就是爲指定用戶分配特定的權限,如只讀、讀寫等。認證與授權的設置需要修改倉庫conf目錄下的文件,如下:
- authz:認證文件,分配用戶名、密碼。
- passwd:授權文件,爲現有用戶分配組,併爲組分配權限。
- svnserve.conf:指定認證、授權文件的位置。
1)修改conf/svnserve.conf
2)修改conf/passwd
3)修改conf/authz
這樣,當用戶再次執行checkout、commit、update時,就會要求認證。
五、subclipse插件的使用
Eclipse提供了集成SVN的插件 — subclipse,本文重點關注subclipse的使用。Eclipse中插件的安裝不是這兒的重點。安裝成功後,可以看到下面的視圖 (Windows — Show View)和透視圖(Windows — Open Perspective):
下面的操作使用了4.1節中的資源庫(repoDemo2)。
1)關聯資源庫
進入SVN資源庫研究透視圖,在SVN資源庫面板上右鍵 — 新建 — 資源庫位置,URL中輸入:svn://192.168.1.6/repoDemo2。
2)共享項目:share Project
新建一個Java Project,名稱爲svnProject,在項目中新建一個Demo1.java。
共享項目:在項目上右鍵 — Team — Share Project…,將項目導入到repoDemo2。在輸入文件夾名時,一般選擇使用項目名稱作爲文件夾名。
3)提交:Commit
共享之後,項目並沒有提交到倉庫中,此時在項目上右鍵 — Team — Commit,就可以將現在的項目提交到倉庫中。
4)檢出:Checkout
新建一個workspace,模擬另外一個用戶(user2)。首先還是關聯資源庫,在svnProject上右鍵 — 檢出爲。
在Demo1.java中新增一個字段並提交(在user2的workspace中做的)。
5)更新:
切換到user1的工作空間,更新項目。不多說,Team — update
6)衝突處理
衝突的產生見4.3節。原則:提交之前先更新。
4.3節中的兩種解決方法也適用於subclipse,解決方法1對應着subclipse中的Synchronize視圖(View),解決方法2類同。
六、SVN與Apache整合(用到再看)
業務場景:在上面的Demo中,SVN倉庫對外提供服務都是通過SVN協議,最直觀的體現就是URL都是以svn://開頭的。在開源項目中使用的SVN倉庫對外提供服務時都是使用http協議,此時需要結合Apache服務器。
1)安裝Apache服務器(假定安裝在C:\Apache2.2)
2)修改C:\Apache2.2\conf\httpd.conf釋放掉註釋和增加紅色邊框的兩行(有順序要求)
3)從SVN安裝目錄的bin目錄下,拷貝mod_authz_svn.so和mod_dav_svn.so到C:\Apache2.2\modules目錄中
4)用Apache服務器的htpasswd創建密碼文件
5)拷貝project1_password到E:\repository\svn\project1\conf目錄下
6)拷貝以下內容到Apache\conf\httpd.conf最後
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
#配置虛擬目錄#
<location /svn/itheima>
#引用遠程訪問模塊
DAV svn
#項目版本庫路徑#
SVNPath E:/repository/svn/project1
#授權文件#
AuthzSVNAccessFile E:/repository/svn/project1/conf/authz
#所有用戶都需要身份驗證#
Satisfy Any
Require valid-user
#驗證方式#
AuthType Basic
#項目的名稱#
AuthName”project1”
#用戶文件#
AuthUserFile E:/repository/svn/project1/conf/project1_password
</location>
|
7)訪問http://localhost/svn/itheima/trunk即可訪問SVN倉庫。
SAE上所有的應用創建時,系統會自動爲該應用創建一個SVN倉庫。該SVN倉庫是所有代碼部署方式的最終入口。開發者可以使用SVN客戶端提交代碼來完成應用代碼的部署。或者使用在線代碼編輯器。
SVN倉庫地址 | https://svn.sinaapp.com/YOUR_APP_NAME |
SVN用戶名 | SAE安全郵箱 |
SVN密碼 | SAE安全密碼 |
註解
SVN倉庫地址可以在應用管理面板的“代碼管理”中找到,倉庫地址可以直接使用瀏覽器進行訪問。 SVN用戶名和密碼爲安全郵箱和安全密碼,不是微博賬號和微博密碼! 如已啓用微盾動態密碼,則此處填寫“安全密碼”+“微盾動態密碼”
使用SVN客戶端
TortoiseSVN客戶端
註解
如果使用TortoiseSVN 1.8.x部署代碼發生問題,請嘗試更新至最新版本或者使用1.8以下的版本。
在Windows下推薦使用烏龜(Tortoise)SVN客戶端。 TortoiseSVN 是 Subversion 版本控制系統的一個免費開源客戶端,可以超越時間的管理文件和目錄。文件保存在中央版本庫(即SAE中央SVN倉庫),除了能記住文件和目錄的每次修改以 外,版本庫非常像普通的文件服務器。你可以將文件恢復到過去的版本,並且可以通過檢查歷史知道數據做了哪些修改,誰做的修改。這就是爲什麼許多人將 Subversion 和版本控制系統看作一種“時間機器”。
TortoiseSVN下載: http://tortoisesvn.net/downloads.html
下面詳細介紹使用TortoiseSVN向SAE部署代碼。
第一步,如圖1,創建一個新文件夾作爲本地工作目錄(Working directory),可以使用應用名爲文件夾名。如,爲我的應用devcenter創建本地工作目錄。
第二步,從SAE的SVN倉庫檢出(checkout)一個應用的全部版本代碼,如圖2,右鍵–>點擊“SVN Checkout”
在彈出頁面中填寫倉庫路徑即可,這裏是:https://svn.sinaapp.com/devcenter/,其它默認參數即可,如圖3:
Reversion處,“HEAD revision”是指最新版,也可以指定Revision爲任意一個版本。
點擊“OK”,出現下載界面,如圖4:
如果一切順利,devcenter應用所有版本代碼將會全部出現在剛剛創建的devcenter文件夾下,如圖5:
在本地使用你喜歡的編輯器,編輯任意文件,保存後該文件圖標將會出現紅色感嘆號,如圖6所示:
看,剛剛修改過的index.php變色了。下面需要提交(commit)最近的更新。在index.php文件上擊右鍵,出現菜單
選擇“SVN commit”,如圖7:
然後填寫關於本次更新的日誌(log message),這是必填項,否則commit會失敗。如圖8:
當您看到如圖9所示,表明剛纔的修改已經成功提交,並且前該devcenter項目的SVN版本號加1,變成30.
在SVN工作目錄下,對於文件修改,完成後只需要commit就ok了,但對於新增文件,或者從其它目錄複製進來的文件或文件夾,需要在commit之前 需 要做一步add操作,即將文件或文件夾添加到svn工作目錄中來,否則SVN客戶端不認它。具體操作很簡單,如圖10:
然後再如圖7所示,右鍵commit 即可。
更多Tortoise SVN使用幫助,請參閱: http://www.subversion.org.cn/tsvndoc/
Notepad++集成SVN插件
Notepad++是一款Windows環境下很受歡迎的免費開源的代碼編輯器,有很豐富的第三方插件。
下面介紹Notepad++的SVN插件的安裝及使用。
如圖12,點擊Plugin –> Plugin Manager –> Show Plugin Manager
打開後,在“Available”頁找到“Subversion”,然後點擊“Install”,如圖13所示:
安裝成功後會在Plugins菜單下出現”Subversion”子菜單。
打開之前checkout下來的任一文件,如devcenter/1/index.php,編輯完成後,點擊Plugins –> Subversion –> Commit File(或使用 快捷鍵Ctrl+Alt+A)
出現熟悉的一頁,如圖14所示:
對,這就是烏龜SVN的Commit頁面,輸入Log Message,點擊“OK”即可提交。
使用UltraEdit Studio部署
UltraEdit Studio(注意不是UltraEdit,UltraEdit不能與SVN整合)配置稍微複雜些。
第一步,SVN倉庫賬號設置,如圖15所示:
然後填寫倉庫信息,如圖16所示:
完成後,創建Project,如圖17所示:
填寫project名b.prj後,出現如圖18所示”Project Settings”,點擊“Add Folder”,出現“NewFolder”,將”Group”前的勾去掉,然後點擊“Browse”,在“Browse for Folder”頁找到之前checkout出現的本地工作目錄。
點擊“OK”後出現提示,如圖19所示:
表明UEStudio自動識別出了選擇的代碼目錄是一個SVN工作目錄,並詢問是否整合,點擊“Yes”,出現如圖20所示:
大功告成,”Close”之後即可以編輯代碼,並隨時commit修改。如圖21所示:
使用EditPlus部署
EditPlus依賴於Tortoise SVN(TSVN),必須先安裝。
使用最簡單,見圖22所示:
當編輯SVN工作目錄裏的文件時,File –> TSVN即出現相應可操作的菜單。
SVN命令行工具
例如,您剛剛創建了應用newapp,在本地執行:
svn checkout https://svn.sinaapp.com/newapp
第一次checkout時需要驗證,用戶名/密碼爲您的SAE安全郵箱和安全密碼(非微博登陸賬號密碼,如已啓用微盾動態密碼,則此處填寫“安全密碼”+“微盾動態密碼”)。
上傳代碼。如部署wordpress到版本1。
svn checkout https://svn.sinaapp.com/newapp cd newapp/1 cp -rf /path/to/wordpress/* ./ svn add ./ svn commit -m"add wordpress"
修改代碼。假如需要修改newapp應用版本1根目錄下某個文件,如index.php,完整的操作流程如下:
svn checkout https://svn.sinaapp.com/newapp #如果已經checkout過了,不需要重新checkout。 cd newapp/1 vim index.php #這裏編輯代碼 svn commit -m "edit index.php"
註解
應用配置文件config.yaml不會被部署到用戶的代碼目錄,但會被存儲在服務端SVN倉庫中。因此下次可以被checkout出來,但不會被用戶訪問到。
SAE提供的SVN服務完全支持標準SVN的所有命令,更詳細的使用說明請查閱SVN官方幫助文檔。
SVN for SAE的限制條件
爲了保持與SAE兼容,使用SVN方式部署代碼到SAE有如下限制:
- 文件名或目錄名不允許含有以下字符:”,*,?,<,>,|,另外文件或文件名的開始與結束也不允許有空格。
- 每個應用代碼總大小不超過對應等級的配額
- 頂層目錄下只允許存在10個以內的版本目錄,目錄名必須爲正整數(詳細見: 應用目錄、應用版本目錄、應用版本 )
常見錯誤說明及解決辦法
錯誤提示 | 錯誤原因 | 解決方法 |
---|---|---|
The change log need some words(not null) | 提交時沒有添加log message | 提交時加上log message即可 |
The log message is a pathname (was -F intended?); use ‘–force-log’ to override log message | 與路徑名稱相同 | 修改log message |
invalid directory or file: xxx | 文件不符合SAE的目錄結構規定,詳細見 應用目錄、應用版本目錄、應用版本 | 按照 應用目錄、應用版本目錄、應用版本 的要求組織目錄結構 |
Too many versions, 10 allowed | 版本目錄多於10個,最多不超過10個 | 刪除剛剛創建的版本目錄即可 |
Too many files: XXX (less than 2000 is allowed). | XXX目錄下文件的數量超過2000 | 刪除XXX目錄下的文件,使其總數降至2000以下 |
out of quota, quota: xxx, used: yyy | 該應用下代碼(不包括.svn目錄)總大小超過配額 | 刪除不必要的代碼再嘗試提交 |
類似Repository UUID ‘305daf1b-94be-48ee-a4b9-f4bcd36320de’ doesn’t match expected UUID ‘44e2f7a2-1b69-4710-974a-b6edef0fdc12’ |