SVN簡單操作

一、 SVN簡介

       SVN(subversion)是近年來崛起的版本管理工具,是CVS的接班人。目前,絕大多數開源軟件都使用SVN作爲代碼版本管理軟件。

1.1 SVN服務器

SVN服務器,支持linux和windows,更多是安裝在Linux下。

SVN服務器有2種運行方式:獨立服務器和藉助apache。2種方式各有利弊。

SVN存儲版本數據也有2種方式:BDB和FSFS。因爲BDB方式在服務器中斷時,有可能鎖住數據,所以還是FSFS方式更安全一點。

1.2 SVN客戶端

Subversion的客戶端有兩類,一類是websvn等基於web的,一種是以TortoiseSVN爲代表的客戶端軟件。前者需要web服務器的支持,後者需要用戶在本地安裝客戶端。

1.3 SVN插件

AnkhSVN是一款在VS中管理Subversion的插件,您可以在VS中輕鬆的提交、更新、添加文件,而不用在命令行或資源管理器中提交。

二、 安裝與配置

2.1 軟件準備

       在準備軟件前首先要弄明白電腦裝的是32位還是64位,然後根據不同來選軟件

VisualSVN Server:Subversion服務器版。

TortoiseSVN:Subversion客戶端。

AnkhSvn:VS上使用SVN的插件。

2.2 軟件安裝

        然後將以上的服務器,客戶端和插件分別進行安裝這裏就省略不寫了

三、 SVN使用

       這裏主講客戶端的使用

1.CheckoutRepository

首先要Checkout服務器端的Repository,

所謂的Checkout就是指獲得服務器端指定的Repository存儲的所有文件。

這個Checkout和VisualSource Safe的Checkout意義完全不一樣,

VSS的Checkout指的是鎖定某個文件,如果你以前使用過VSS,

在學習Subversion時這個問題一定要注意。

Checkout的具體方式是:

在客戶端新建一個空目錄,比如:F:\Project1

在該目錄上單擊右鍵,在彈出式菜單中選中SVNCheckout...,

之後在“URL of Repository”文本框中填入你想要連接的Repository的地址,

這個URL地址可以用瀏覽方式加入。

對於在本教程第二節建立的Repository,

URL應該是“svn://xxx/project1”

(xxx可以是服務器端主機名,也可以是服務器端的ip地址)。

然後點OK,會彈出一個認證對話框,

輸入在教程第三節設置的用戶名和密碼。

點OK後就完成了對Repository的Checkout。

比如:在服務器端Repository中有一個a.txt文件,

那麼Checkout之後F:\Project1目錄下也會出現一個a.txt文件。

在本例中由於服務器端的Repository還未添加任何文件,

所以在客戶端的F:\Project1下沒有文件被Checkout。

執行Checkout除了會在F:\Project1產生Repository存儲的文件及目錄外,

還會產生了一個“.svn”的隱含目錄,該目錄是由subversion管理的,

不要刪除或者手工改動其中的文件和目錄。

現在F:\Project1中的文件和目錄就叫做Repository的“WorkingCopy”簡寫“WC”

(這個簡寫...汗)。

以後對Repository中文件和目錄的修改,添加,刪除的操作,

都是通過對這個“Working Copy”的操作實現的。

Checkout執行完後,

會發現F:\Project1目錄的圖標的左下角附着了一個小的狀態圖標

(當F:\Project1目錄中的文件改變時,這個狀態圖標也會隨之變化),

它表示F:\Project1是一個Repository的“WorkingCopy”,

F:\Project1內的所有文件和目錄也會有類似的狀態圖標。

 

2.添加文件

將要添加的文件或者目錄拷貝到F:\Project1下,

然後在該文件或目錄上單擊右鍵,TortoiseSVN->Add,點OK。

如果添加了不止一個文件或目錄,

則鼠標不要在F:\Project1中點中任何文件,

然後單擊右鍵,TortoiseSVN->Add,

就可以添加多個文件或目錄。

這時文件的狀態圖標會發生變化。

Add命令只是告訴本地的“Working Copy”將該文件納入版本管理,

並沒有將這個改變提交到服務器端,

如果想要別人也看見你對Repository的修改,你需要

在F:\Project1下單擊右鍵,SVNCommit...,

將你所做的修改提交到Repository。

文件的狀態圖標也會更新。

不管你在“Working Copy”內添加、修改、刪除文件後,

要想其他人也看見你的修改,

都必須用Commit命令將所做修改遞交到服務器端的Repository。

3.修改文件

用文本編輯器或IDE對文件修改後,

文件的狀態圖標會變化,

然後單擊右鍵,SVN Commit...

提交修改,只有當執行Commit提交修改後,

你所作的修改纔會反映到服務器端的Repository中。

 

4.刪除文件

刪除文件時,選中要刪除的文件或目錄,

單擊右鍵,TortoiseSVN->Delete,提交修改。

注意千萬不要用“Delete”鍵來刪除文件,否則將無法提交你的修改。

這一點對目錄的刪除來說尤爲重要。

 

5.放棄修改

當你添加、修改、刪除文件後,決定放棄修改,

你可以單擊右鍵,TortoiseSVN->Revert,

本地的“Working Copy”中的文件和目錄會恢復到你修改前的狀態。

 

6.獲取Repository的最新版本

當一個團隊合作開發項目時,

每一個人都在不斷的對Repository進行更新,

你需要不斷的更新自己的“Working Copy”,

以獲取項目最新的文件。

當第一次獲得最新Repository的文件時,

我們用Checkout命令,前面已經介紹了,

以後再獲取最新文件時就不用Checkout了。

而改用Update命令。

接着前面的例子,這時F:\Project1已經成爲一個“WorkingCopy”了

(通過執行Checkout命令),現在其他人已經對Repository進行了修改,

我想將別人的修改反映到我的“Working Copy”中,

具體的方法是:在F:\Project1目錄上單擊右鍵,

SVN Update。這時F:\Project1中的文件就是最新的版本了。

注意,如果當你的“Working Copy”中有被修改的文件,

或者有被刪除的文件,並且還未提交這些修改時,

這些文件在執行Update過程中是不會被更新的。

比如你修改了F:\Project1下a.txt文件,

還未提交修改,那麼,

當你對F:\Project1進行Update時,

a.txt文件是不會更新爲Repository上的a.txt文件的。

所以如果想放棄當前的所有修改,

並將F:\Project1下所有文件及目錄更新到最新版本,

應該先對F:\Project1執行Revert命令再執行Update命令。

 

7.subversion的版本控制模型

當你用subversion進行版本控制時,

Subversion會記錄你對Repository進行的每一次修改(包括添加,修改,刪除等等),

每修改一次Repository都會產生一個新的Revision(修訂版本號),

不同的Revision代表了不同時刻Repository的狀態,

因此我們可以用這個Revision回朔任意時刻Repository的狀態,

就像時間機器一樣,也就是說某一Revision

就是Repository在某一時刻的一個“快照”。

注意:Revision不是針對某一個文件或者目錄,

而是針對整個Repository而言的。

每修改一次Repository,Revision 都會增加1。

Subversion的版本控制模型是一種叫做Copy-Modify-Merge

(拷貝-修改-合併)的模型。

考慮這種情況:

張三和李四是公司同一個部門的同事,

他們共同維護一個文本文件a.txt,

並且對該文件進行版本控制,

因此他們把這個文件放到一個Repository上共同維護該文件。

週一上午9點,張三和李四同時想對a.txt文件進行修改,

於是他們同時從Repository上取得該文件的最新版本(Revision10),

然後進行修改。過了三分鐘,張三首先完成了修改,

他在該文件的第五行修改了一個單詞的拼寫(將Typo改爲Type),

於是張三對修改後的文件執行Commit命令,

將修改提交到服務器端的Repository中。

這時Repository的Revision變爲11。

六分鐘過後,李四也完成了他的修改,

他修改了該文件第十行上的一個單詞拼寫(將He改爲She),

於是他也對修改後的文件執行Commit命令,

這時Subversion 在提交修改時會發現,

李四修改的文件是Revision10的a.txt文件,

而不是最新的Revision 11的a.txt文件。

於是,Subversion 提示李四在提交修改前,

應該先將Working Copy更新到最新版本,

李四執行Update命令將WorkingCopy更新到Revision 11,

這時Subversion會提示已經完成合並,

李四的a.txt文件的第五行的“Typo”已經變爲了“Type”,

第十行還是“She”,就是說Subversion已經將張三的修改“合併”到李四的a.txt文件中了。

之後,李四再執行Commit命令,就能將他對第十行的修改(將He改爲She)

提交到服務器端的Repository中了(生成Revision12)。

但是這種合併在某些情況下會變得複雜一些,

比如:李四對a.txt文件的修改並不是第十行,

而是與張三同樣修改第五行的單詞,

李四將“Typo”改爲“Typr”,並且提交修改,

這時Subversion會提示李四在提交修改前,

應該先將Working Copy更新到最新版本,

李四執行Update命令將WorkingCopy更新到Revision 11,

這時Subversion將Revision11的a.txt文件與

李四修改的a.txt文件進行合併時發現李四修改的同樣是第五行,

於是Subversion就無法判斷是李四的修改(“Tpyr”)

正確還是張三的修改(“Type”)正確,

因爲他們都是在Revision10的a.txt基礎上作的修改。

這種情況叫做Conflict(衝突),

a.txt文件的圖標會變成一個黃色三角。

這時,只能依靠李四自己去判斷到底第三行應該修改爲“Typr”還是“Type”。

當李四確定修改之後,在a.txt文件上單擊右鍵,TortoiseSVN->Resolved

告訴Subversion已經解決了Conflict。

這時再執行Commit命令就能提交修改(生成Revision12)。

Subversion 這種控制方式保證了你對文件所作的修改都是基於文件的最新版本。

 

8.“.svn”目錄

在客戶端Working Copy的每一層目錄中都會有一個“.svn”目錄,

該目錄是Subversion進行管理用的目錄。

不要手動修改其中的文件。

該目錄存儲了Working Copy的一個副本

(實際存儲副本的地方是F:\project1\.svn\text-base目錄),

比如:F:\Project1是一個WorkingCopy,

該目錄下有兩個文件a.txt和b.txt還有一個子目錄ccc,

子目錄ccc中還有一個d.txt文件。

“.svn”目錄中存儲的是你最近一次執行完Update或者Commit命令之後當前目錄中文件的副本,

比如:F:\project1\.svn\text-base中存儲的a.txt和b.txt

是最近一次執行完Update或者Commit命令之後F:\project1下的a.txt和b.txt的拷貝。

也就是說你所作的修改都是基於“.svn”目錄存儲的那些文件。

這種機制可以讓我們在不連接網絡的情況下,

將Working Copy中的文件恢復到修改之前的狀態。

Subversion的Revert命令就是利用了這種機制來實現的。

比如你修改了F:\project1\a.txt文件,

這時你又改變了主意想放棄對該文件的修改,

你可以單擊右鍵,TortoiseSVN->Revert,

修改過的F:\project1\a.txt文件

就會被F:\project1\.svn\text-base中a.txt文件的副本所替代,

使得a.txt恢復到修改前的狀態。

Working Copy中每一個子目錄下都會有一個“.svn”目錄,

並不是只有最上層目錄纔有“.svn”目錄。

所以,F:\project1\ccc下也有一個“.svn”目錄,

該目錄存儲的是F:\project1\ccc\d.txt的副本

(d.txt的副本位於F:\project1\ccc\.svn\text-base)。

也就是說每個“.svn”目錄只存儲同級目錄中的“文件”副本,

而不存儲“目錄”副本。“.svn”目錄存有許多重要的內容,

所以前面說在刪除文件或目錄時,

必須用TortoiseSVN->Delete,

而不能用“Delete”鍵來刪除文件或目錄,尤其是對於目錄的刪除。

 

9.混合版本

Subversion的Working Copy被設計成一種能夠包含不同版本的文件共存的形式。

比如F:\Project1是一個WorkingCopy,

該目錄下有兩個文件a.txt和b.txt。

執行Update命令,將WorkingCopy更新到最新版本(Revision 24)。

這時,a.txt和b.txt的Revision都是24

(其實對於單個文件來說並不存在Revision,

Revision是對於整個Repository而言的,

這裏所指的是Repository的Revision24所存儲的a.txt和b.txt,

但爲了方便而採用這種描述方式,請注意,下同)。

之後,你的同事修改了a.txt,並且提交了修改,

這時Repository的Revision就變成25了。

注意,這時你沒有再次執行Update,

因此你的Working Copy的Revision還是24。

這時你修改了b.txt文件,並提交修改。

因爲Revision25並沒有對b.txt文件進行修改,

因此你對b.txt文件的修改是基於b.txt文件最新的版本,

所以不會出現Conflict。

當你提交b.txt的修改後,產生Revision26。

這時你會發現你的Working Copy中的a.txt文件並不是Revision25中的a.txt文件,

它還是Revision24的a.txt文件,而你的b.txt文件是Revision26的b.txt文件。

也就是說當你Commit時,你的WorkingCopy中只有你提交的那些文件是最新版本,

而其他沒有修改的文件並不會更新爲最新版本。

這樣就造成了你的Working Copy由不同的Revision文件所組成

(Revision24的a.txt文件和Revision26的b.txt文件)。

前面說過在提交修改前必須保證你是在文件的最新版本基礎上修改,

如果在這種混合版本的情況下,

怎樣才能知道當前Working Copy中的文件是否爲最新版本?

在前面所說的“.svn”目錄中有一個文件名爲“entries”的文件,

該文件記錄了當前Working Copy中的每一個文件的Revision,

因此當你Commit時,Subversion會從該文件中取得你提交文件的Revision,

再與Repository的最新Revision一比較就可以知道你修改的文件是否基於該文件的最新版本。

 

10.文件的鎖定

前面說過Subversion的版本控制模型是一種叫做Copy-Modify-Merge

(拷貝-修改-合併)的模型。

該模型在對文本文件進行版本控制時工作的很好,

但是有些需要進行版本控制的文件並不是文本文件,

比如說圖像文件,這種模型在這種情況下就不能正常工作了,

因爲文本文件可以合併,而二進制文件則無法合併。

所以Subversion從1.2開始支持一種叫Lock-Modify-Unlock

(鎖定-修改-解鎖)的版本控制模型。

在Windows下最常用的版本控制軟件VisualSource Safe(VSS)就是採用這種模型。

這種模型要求在對一個文件修改前首先要鎖定這個文件,

然後才能修改,這時,別人將無法對該文件進行修改,

當修改完後再釋放鎖,使其他人可以對該文件進行鎖定,然後修改。

鎖定文件的方法是:TortoiseSVN->GetLock...再點OK按鈕,

這時就完成了對文件的鎖定。

這時,如果其他人想對文件進行鎖定時,

Subversion會對他提示該文件已經被別人鎖定。

當你修改完文件後,然後單擊右鍵,SVN Commit...,

將修改提交,默認情況下,提交的時候就會對該文件解鎖,

如果你想仍然鎖定該文件,請在commit時彈出的對話框中選中keeplock複選框。

 

11.文件的附加屬性

在Subversion中,每個文件可以擁有一種叫做附加屬性的東西。

附加屬性描述了該文件所擁有的一些特性。

Subversion已經預定義了一些附加屬性

(這裏只是指Subversion已經定義了一些附加屬性的“名稱”,

並不是指已經將這些屬性附加在文件上了,

比如默認情況下文本文件一開始不含任何屬性,

直到人爲的對該文件添加附加屬性),

並且你可以對文件添加自定義的屬性。

Subversion對待附加屬性就像對待文件內容一樣,

當修改了一個文件的附加屬性(添加,改變,刪除附加屬性),

即使沒有對文件的內容進行修改,

同樣可以Commit該文件,就像更改了文件內容那樣,

Repository也會生成新的Revision,

所以從某種意義上來說,

Subversion不區別對待文件的附加屬性的修改和文件的內容的修改,

文件的附加屬性可以看成是一種特殊的文件內容。

Subversion預定義了若干個附加屬性,

這裏只討論“svn:needs-lock”屬性,

因爲它與我們上面的文件鎖定會產生的一個問題有關。

其他的屬性可以參考Subversion自帶的幫助文檔。

考慮這種情況,

張三和李四同時想對一個圖片文件a.jpg作修改,

張三在修改時先將該文件鎖定,然後進行修改,

同時李四也開始對該文件進行修改,

但李四忘記了對非文本文件進行修改時應該先鎖定該文件。

張三首先對該文件修改完畢,於是張三向服務器提交了他的修改。

之後,李四也完成了修改,當他提交修改時,

Subversion提示李四的文件版本不是最新的,

在Commit之前應先更新a.jpg到最新版本,

由於圖片文件無法合併,

這就意味着張三和李四之間必定有一個人的修改會作廢。

應用“svn:needs-lock”屬性可以避免這個問題。

當一個文件擁有“svn:needs-lock”屬性時,

該文件在沒有鎖定時,文件的圖標是灰色的,

表示該文件是一個只讀文件(該文件的Windows只讀屬性的複選框爲選中),

這個灰色的圖標就會提醒想對該文件進行修改的人,

在修改該文件之前應該首先鎖定該文件。

鎖定該文件之後,文件的只讀屬性就會去掉了,

一旦釋放掉鎖,文件的圖標又會變成灰色,

文件也會變成只讀的了。

李四在這種情況下就會避免在沒有鎖定文件時對文件進行修改。

對非文本文件添加“svn:needs-lock”

屬性應該在將該文件第一次添加到Repository時就設置,

當然,一個文件可以在任意時刻添加附加屬性,

這樣做是爲了減少李四所遇到的那個問題發生的機率。

具體的方法是:

首先將a.jpg文件拷貝到WorkingCopy中,

然後在該文件上單擊右鍵,

TortoiseSVN->Add,告訴Subversion要將該文件納入版本控制,

接着在該文件上單擊右鍵並選中屬性,

在彈出的屬性對話框中選中Subversion頁。

在下拉框中選中“svn:needs-lock”,

並在下面的文本框中填入“*”

(其實這裏填什麼都無所謂,只要文件有“svn:needs-lock”附加屬性就行),

之後點Set按鈕,“svn:needs-lock”附加屬性就設置好了。

然後執行Commit命令提交修改。

這時當其他人執行Update時,

a.jpg就會添加到他們的Working Copy中,

並且文件的附加屬性也會隨文件一起被得到。

可以看到a.jpg此時的圖標就是灰色的,

文件的Windows屬性也是隻讀的。

 

12.回到以前的版本

由於Subversion會記錄你對Repository的每一次修改,

因此能夠很容易的獲得Repository以前某一時刻的狀態。

比如:現在Repository的最新Revision是56,

這時我想看看Repository在Revision24時的狀態,

可以在本地的Working Copy中單擊右鍵,

TortoiseSVN->Update to Revision...,

然後輸入你想要回復到的Revision號,點OK按鈕。

回到以前的版本還有一種情況是我想將Repository的

最新Revision的狀態與以前某一個Revision的狀態一模一樣,

上面那種方法就不適合,

上面的那種方法只是將本地的Working Copy回覆到以前的狀態,

而服務器端的Repository並沒有回到以前的狀態。

將Repository的最新Revison的狀態回覆到以前某個Revision的狀態具體的方法是:

 

先執行Update命令將WorkingCopy更新到最新的Revision,

然後在Working Copy中單擊右鍵,

TortoiseSVN->Show Log,

彈出的Log Messages窗口中會顯示該Repository的所有Revision,

選中最新的Revision,之後按住Shift鍵,

再單擊你想回復到的Revision+1的那個Revision

(比如Repository的最新Revision是30,

你想將Repository的狀態回覆到Revision16,

那麼就選中Revision30,再按住Shift鍵,

選中Revision17,

就是說選中Revision17到Revision30之間的所有Revision)。

然後在選中的Revision上單擊右鍵,

選中“Revert changes from theserevision”。

再點Yes按鈕,就可以將WorkingCopy的狀態回覆到目標Revision。

注意,此時只是Working Copy回覆到目標Revision,

之後應該用Commit提交修改,

這樣Repository最新狀態就與目標Revision的狀態一樣了。

這兩種回覆到以前版本的方式截然不同,

第一種方式是將整個Working Copy回覆到某個Revision,

也就是說這種方式Working Copy中的“.svn”目錄所存的文件副本也與目標Revision的一模一樣,

如果這時你沒有修改文件,你將不能執行Commit命令。

而第二種方式客戶端Working Copy中的

“.svn”目錄所存的副本始終是最新的Revision的文件副本

(這裏我們基於一個假設:在Update之後沒有其他人對Repository做修改)。

這種方式就像是我們自己手工將Working Copy的文件狀態修改爲目標Revision,

在修改之後提交修改一樣。

 

13.查看修改

有時我們對Working Copy的許多文件進行了修改,

這些文件位於不同的子目錄,我們就可以在Working Copy的最上層目錄單擊右鍵,

TortoiseSVN->Check For Modifications,

彈出的對話框就會顯示你所做的所有修改明細。

還有一種情況是我們的Working Copy已經很久沒有執行Update命令,

我們想看看Working Copy中有哪些文件已經發生修改了,

這時就可以在Working Copy的最上層目錄單擊右鍵,

TortoiseSVN->Check For Modifications,

在彈出的對話框點擊Check Repository按鈕後,

就會顯示服務器端已經修改了的文件。

該方法還有一個用途就是查看文件的鎖定,

當你想鎖定一個文件時,你想先看看這個文件有沒有被別人鎖定,

點擊Check Repository按鈕會顯示服務器端Repository所有被鎖定的文件,

如果你想鎖定的文件不在這裏面,那就說明該文件目前沒有人鎖定。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章