作者:東風化宇 來源:http://www.flyne.org/article/851
一、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:svnreporepoDemo1。后面就使用該目錄作為SVN倉庫。
2)創建倉庫:svnadmin create E:svnreporepoDemo1。創建倉庫后的目錄結構如下:
3)啟動SVN服務:svnserve -d -r E:svnreporepoDemo1,如下圖:
這樣就啟動了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的使用
TortoiseSVN是現在最流行的SVN客戶端工具,使用圖形化界面和SVN倉庫交互(作為命令行方式的替代)。關于TortoiseSVN的安裝省略。
安裝完成后,在任意位置右擊都能看到TortoiseSVN選項。
1、基本操作
1)創建倉庫
創建目錄:E:svnreporepoDemo2,進入該目錄下,右擊 — 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.2confhttpd.conf釋放掉注釋和增加紅色邊框的兩行(有順序要求)
3)從SVN安裝目錄的bin目錄下,拷貝mod_authz_svn.so和mod_dav_svn.so到C:Apache2.2modules目錄中
4)用Apache服務器的htpasswd創建密碼文件
5)拷貝project1_password到E:repositorysvnproject1conf目錄下
6)拷貝以下內容到Apacheconfhttpd.conf最后
7)訪問http://localhost/svn/flyne/trunk即可訪問SVN倉庫。