2009-03-13 作者:Aaron Wong 來源:Aaron Wong的blog
0 前言
Subversion是一個免費(fèi)的開源的版本管理系統(tǒng),它是作為CVS(Concurrent Versions System)的取代品出現(xiàn)的。本文簡單介紹了Subversion在Fedora上的安裝過程及其基本概念和使用方法。您可以到O'Reilly出版的開源書籍
Version Control with Subversion的主頁在線閱讀(中、英文版本都有),以獲取更多信息。
1 在Fedora上安裝Subversion
[aaronwong@localhost ~]$ sudo yum -y install subversion
[aaronwong@localhost ~]$ rpm -ql subversion
//上面的命令可查詢subversion軟件包在系統(tǒng)上所安裝的文件列表
[aaronwong@localhost ~]$ sudo yum -y install mod_dav_svn
//mod_dav_svn不是必須安裝的,它是Apache HTTP Server的一個插件,你本地倉庫(repository)的文件必須通過它才能在網(wǎng)絡(luò)上與別人共享。
//subversion的組件列表點(diǎn)此查看。
[aaronwong@localhost ~]$ svn --version
svn,版本 1.4.3 (r23084)
編譯于 Mar 23 2007,09:29:55
版權(quán)所有 (C) 2000-2007 CollabNet。
Subversion 是開放源代碼軟件,請參閱 http://subversion.tigris.org/
此產(chǎn)品包含由 CollabNet (http://www.Collab.Net/)開發(fā)的軟件。
可使用以下的倉庫存取 (RA) 模塊:
* ra_dav : 通過WebDAV(DeltaV)協(xié)議訪問倉庫的模塊。
- 處理“http”方案
- 處理“https”方案
* ra_svn : 使用svn網(wǎng)絡(luò)協(xié)議訪問倉庫的模塊。
- 處理“svn”方案
* ra_local : 訪問本地磁盤的倉庫模塊。
- 處理“file”方案
2 使用Subversion管理本地project
作為程序開發(fā)人員,我們沒有必要了解Subversion的所有特性的方方面面,我們的目的是使用它來對我們的project進(jìn)行方便的簡單的版本管理,因此,強(qiáng)烈推薦閱讀
Subversion Quick-Start Guid和
Basic Usage。
以下是筆者參照上述Guide進(jìn)行一個簡單的本地project的版本管理的示例。假定工程名為hello。
(1)建立本地工程hello的subversion倉庫
Subversion把工程的各個版本的數(shù)據(jù)集中放在一個倉庫(repository)中。假定我們要建立一個本地工程,叫做hello,為了使用subversion對它進(jìn)行版本管理,首先要為該工程建立一個倉庫。
[aaronwong@localhost ~]$ svnadmin create .subversion/repos/hello
//subversion安裝后會生成一個~/.subversion目錄,這里,我們將工程hello的數(shù)據(jù)倉庫建立在~/.subversion/repos/hello目錄。
[aaronwong@localhost ~]$ ls -p .subversion/repos/hello/
conf/ dav/ db/ format hooks/ locks/ README.txt
(2)按照subversion的要求組建本地工程hello的工作目錄
假定工程hello的頂層目錄為~/projects/hello(這里~代表/home/aaronwong/),則應(yīng)如下組建工程的工作目錄:
~/projects/hello/branches
~/projects/hello/tags
~/projects/hello/trunk/
hello.c
//trunk目錄是實(shí)際上的工程頂層目錄,工程中的所有文件和文件夾都在該目錄下組織。
[aaronwong@localhost ~]$ cd projects/hello/
[aaronwong@localhost hello]$ ls -p
branches/ tags/ trunk/
[aaronwong@localhost hello]$ cat trunk/hello.c
//This is a original version.
#include <stdio.h>
int main()
{
printf("Hello world!\n");
}
(3)將本地工程hello導(dǎo)入本地的Subversion的工程倉庫
由于是首次導(dǎo)入,因此要加信息-m "initial import"。
[aaronwong@localhost trunk]$ svn import ~/projects/hello/ file:///home/aaronwong/.subversion/repos/hello/ -m "initial improt"
新增 /home/aaronwong/projects/hello/trunk
新增 /home/aaronwong/projects/hello/trunk/hello.c
新增 /home/aaronwong/projects/hello/branches
新增 /home/aaronwong/projects/hello/tags
提交后的版本為 1。
注意,完成導(dǎo)入后,原目錄~/projects/hello并不轉(zhuǎn)換為“工作副本(working copy)”,而且該項目已經(jīng)轉(zhuǎn)由該倉庫接管,即該倉庫中已經(jīng)包含了首次導(dǎo)入的工程的所有信息,與源目錄~/project/hello再無任何關(guān)系,我們完全可以刪除這一目錄而不必?fù)?dān)心丟失工程項目數(shù)據(jù)。注意,如果源目錄并不是一個“工作副本”,那么就無法用svn進(jìn)行管理,在其中所作的任何變動都無法提交到倉庫。
要用subversion對工程進(jìn)行版本管理,那么工程項目的開發(fā)必須在一個“工作副本”中進(jìn)行,即首先要從倉庫獲取一個“工作副本”。
(4)工程開發(fā)過程中的版本管理與控制
使用subversion對工程進(jìn)行版本管理的一般流程如下:
a)建立工程的數(shù)據(jù)倉庫,并導(dǎo)入工程的最初版本(前面已經(jīng)完成);
b)從倉庫獲取一個“工作副本”(svn checkout,可以獲取最新版本也可以獲取以前的某個版本),在這個“工作副本”中進(jìn)行工程開發(fā),修改完畢將變動提交到倉庫。
下面簡單介紹b)步驟。
由于工程hello已經(jīng)導(dǎo)入到倉庫,因此原目錄可以刪除。我們刪除原目錄,并從倉庫獲取工程hello的一個“工作副本”(working copy);當(dāng)然,如果你當(dāng)心這樣做會造成數(shù)據(jù)丟失,完全可以重新建立一個目錄,將“工作副本”保存到那里。
[aaronwong@localhost projects]$ rm -rf hello/
[aaronwong@localhost projects]$ svn checkout file:///home/aaronwong/.subversion/repos/hello/trunk hello
A hello/hello.c
取出版本 1。
//注意,我們用紅色標(biāo)出了"trunk",如果不指定這一目錄,則會取出除工程源文件外的其他不必要的目錄如branches和tags。
[aaronwong@localhost projects]$ ls -a hello/
. .. hello.c .svn
//可以看到“工作副本”下有一個.svn隱藏目錄,其中就包含了subversion用來進(jìn)行版本管理的信息。
下面可以對工程hello的內(nèi)容進(jìn)行編輯和修改。注意,如果要在工程中增加或刪除某一文件或目錄(包括復(fù)制和移動),必須使用svn add/delete/mkdir/copy/move等相關(guān)命令進(jìn)行標(biāo)記。
[aaronwong@localhost hello]$ pwd
/home/aaronwong/projects/hello
[aaronwong@localhost hello]$ vim hello.c
[aaronwong@localhost hello]$ cat hello.c
//This is the second version.
#include <stdio.h>
int main()
{
printf("Hello world!\n");
return;
}
[aaronwong@localhost hello]$ mkdir doc
[aaronwong@localhost hello]$ vim doc/readme.txt
[aaronwong@localhost hello]$ svn add doc
A doc
A doc/readme.txt
//說明:如果svn add的對象是一個目錄,則該目錄及其子目錄和其下的文件都會被添加到工程。
對工程編輯完畢,你可以檢查一下該次編輯對工程(實(shí)際上是對你的"工作副本")做了哪些改動。
[aaronwong@localhost hello]$ svn status
M hello.c
A doc
A doc/readme.txt
[aaronwong@localhost hello]$ svn diff
Index: hello.c
===================================================================
--- hello.c (版本 1)
+++ hello.c (工作副本)
@@ -1,10 +1,10 @@
-//This is a original version.
+//This is the second version.
#include <stdio.h>
int main()
{
printf("Hello world!\n");
-
+ return;
}
Index: doc/readme.txt
===================================================================
--- doc/readme.txt (版本 0)
+++ doc/readme.txt (版本 0)
@@ -0,0 +1,2 @@
+This is an example for subversion tutorial.
+
//可以看到,svn diff提供了更詳細(xì)的改動信息,并且很容易的將該命令的輸出重定向?yàn)橐粋€patch補(bǔ)丁。
檢查確認(rèn)無誤后,便可提交此次更改,同時要附加此次更改的說明注釋信息。
[aaronwong@localhost hello]$ svn commit -m "documents added."
新增 doc
新增 doc/readme.txt
正在發(fā)送 hello.c
傳輸文件數(shù)據(jù)..
提交后的版本為 2。
現(xiàn)在工程倉庫中已經(jīng)保存了上面所提交的版本2的工程的所有信息,因此,上面的“工作副本”也可以被刪除:當(dāng)然,如果下次你還要繼續(xù)使用這個“工作副本”進(jìn)行工作,則可以保留這個副本,不過需要注意的是,如果你是在一個開發(fā)團(tuán)隊中,開發(fā)團(tuán)隊的任一成員都可能在你不知情的情況下更新了工程版本,因此,在團(tuán)隊開發(fā)中,進(jìn)入已有的“工作副本”進(jìn)行編輯前,應(yīng)該先使用"svn update"命令將當(dāng)前“工作副本”更新到倉庫中的最新版本。
3 使用svn獲取開源項目源代碼
這實(shí)際上是獲取一個“工作副本”的過程。例如我需要下載ffmpeg的最新源代碼,就可以使用svn checkout命令來完成:
[aaronwong@localhost ~]$ svn checkout svn://svn.mplayerhq.hu/ffmpeg/trunk ffmpeg
A ffmpeg/configure
A ffmpeg/Doxyfile
A ffmpeg/ffmpeg.c
A ffmpeg/vhook
A ffmpeg/vhook/imlib2.c
A ffmpeg/vhook/drawtext.c
A ffmpeg/vhook/fish.c
A ffmpeg/vhook/null.c
......