Windows下用subversion進(jìn)行版本控制
這篇教程是寫給從未接觸過(guò)Subversion的人看的,高手就不要
浪費(fèi)時(shí)間了。由于Subversion自帶的文檔太長(zhǎng),而且講得太全面了,可能剛?cè)腴T者沒(méi)有耐心一點(diǎn)點(diǎn)看完(比如我剛接觸Subversion的時(shí)候
^_^),所以想寫一篇比較基礎(chǔ),但是版本控制過(guò)程中遇到的各個(gè)方面(這里是指我自己遇到過(guò)的,Subversion還有許多基礎(chǔ)的方面我沒(méi)有遇到,用軟
件工程的話講就是沒(méi)有需求^_^,這些方面我就沒(méi)有寫)都能涉及到的教程,讓更多的人能夠了解subversion和使用subversion這個(gè)優(yōu)秀的
版本控制工具(好像subversion在國(guó)內(nèi)用的人很少啊)。文中如有不對(duì)的地方,還請(qǐng)高手指正。特別感謝subversion.org.cn的論壇斑
竹回答我關(guān)于lock的問(wèn)題,特別感謝subversion的作者提供了這么一個(gè)優(yōu)秀的版本控制工具。
一.安裝subversion
首先安裝subversion1.2.3和圖形化客戶端TortoiseSVN-1.2.4.4479(該版本的TortoiseSVN針對(duì)
subversion1.2.3)。subversion在服務(wù)器端和客戶端都需要安裝,TortoiseSVN只要在客戶端安裝就行。
二.建立Repository(保存文檔各個(gè)版本的數(shù)據(jù)庫(kù))
在服務(wù)器端建立一個(gè)空目錄,比如“C:\SVNProjects\Project1”。建立Repository的具體方式是:在subversion安
裝目錄下的\bin子目錄下有一個(gè)svnadmin.exe文件,在DOS窗口下進(jìn)入該\bin目錄,并執(zhí)行“svnadmin create
--fs-type bdb
C:\SVNProjects\Project1”。之后你會(huì)發(fā)現(xiàn)原本是空目錄的“C:\SVNProjects\Project1”下多出了幾個(gè)目錄和
幾個(gè)文件。這些目錄和文件就是用來(lái)存儲(chǔ)文檔各個(gè)版本的數(shù)據(jù)庫(kù)。
***除了用命令行方式建立Repository外,還可以用TortoiseSVN建立,不過(guò)這要求在服務(wù)器端也安裝TortoiseSVN。建立
Repository的具體方式是:在“C:\SVNProjects\Project1”目錄上右擊鼠標(biāo),TortoiseSVN->
Create Repository here....,然后彈出一個(gè)對(duì)話框選擇Berkeley Database(BDB),然后點(diǎn)OK按鈕。
三.配置Repository
建立Repository后,還應(yīng)該對(duì)Repository進(jìn)行配置,主要的目的是控制訪問(wèn)權(quán)限和添加Repository的用戶。“C:\
SVNProjects\Project1\conf\svnserve.conf”文件就是該Repository的配置文件。它是一個(gè)典型的INI文
件,雖然該文件并不是以INI作為擴(kuò)展名。用文本編輯器打開(kāi)它后,可以看見(jiàn)一些文本,該文件以“#”開(kāi)始的行都是注釋行。將“#[general]”行的
“#”刪掉,“#anon-access = none”“#auth-access = write”“#password-db =
passwd”行也刪掉“#”,注意,只是刪掉“#”字符,不要把整行都刪了。“anon-access =
none”是指不允許匿名訪問(wèn)Repository,不管是讀操作還是寫操作。“auth-access =
write”表示認(rèn)證的訪問(wèn)允許寫操作,當(dāng)然讀操作就更允許了。“password-db =
passwd”表示用戶名及用戶密碼存在一個(gè)叫passwd的文件里,這個(gè)文件也在“C:\SVNProjects\Project1\conf”目錄
下,用文本編輯器打開(kāi)后,將“# [users]”的“#”字符刪掉,然后在文件的最后添加一個(gè)新行,在該行寫上用戶名和密碼,格式為“xxxx =
yyyy”其中“xxxx”表示用戶名,“yyyy”表示密碼,一行只能設(shè)定一個(gè)用戶,要設(shè)定多個(gè)用戶,請(qǐng)?jiān)倨鹦滦小?br />
四.啟動(dòng)subversion服務(wù)器
Subversion提供了三種服務(wù)器模式,這里介紹其中的一種,它是subversion自帶的一種輕量級(jí)的服務(wù)器,該服務(wù)器啟動(dòng)后,在服務(wù)器端的
3690端口監(jiān)聽(tīng)客戶端的連接請(qǐng)求(這是默認(rèn)情況下,如果你有其他程序占用了3690端口,可以用“--listen-port”參數(shù)指定服務(wù)器監(jiān)聽(tīng)端
口)。服務(wù)器的具體啟動(dòng)方式是:在subversion安裝目錄下的\bin子目錄下有一個(gè)svnserve.exe文件,該文件運(yùn)行時(shí)可帶參數(shù),常用的
參數(shù)有兩個(gè)一個(gè)是“-d”,該參數(shù)表明服務(wù)器作為一個(gè)精靈進(jìn)程一直運(yùn)行,直到手動(dòng)結(jié)束該程序。另一個(gè)參數(shù)就是“-r”,該參數(shù)指定服務(wù)器進(jìn)程尋找
Repository的根路徑。在DOS窗口下進(jìn)入\bin目錄,并執(zhí)行:
“svnserve.exe -d -r C:\SVNProjects”。服務(wù)器這時(shí)就啟動(dòng)了。“-r
C:\SVNProjects”參數(shù)的作用是:當(dāng)在客戶端用“svn://xxx/project1”(xxx可以是服務(wù)器端主機(jī)名,也可以是服務(wù)器端的
ip地址)訪問(wèn)服務(wù)器的Repository時(shí),服務(wù)器會(huì)知道你要訪問(wèn)的Repository路徑是“C:\SVNProjects\
Project1”。如果當(dāng)我有兩個(gè)完全不相干的項(xiàng)目要進(jìn)行版本控制時(shí),可以再建立一個(gè)空目錄
“C:\SVNProjects\Project2”,并在其中再建立一個(gè)Repository,此時(shí)客戶端就可以用“svn:
//xxx/project2”訪問(wèn)“C:\SVNProjects\Project2”下的Repository。至此,服務(wù)器端就配置完畢了。
五.客戶端的使用
1.Checkout Repository
首先要Checkout服務(wù)器端的Repository,所謂的Checkout就是指獲得服務(wù)器端指定的Repository存儲(chǔ)的所有文件。這個(gè)
Checkout和Visual Source
Safe的Checkout意義完全不一樣,VSS的Checkout指的是鎖定某個(gè)文件,如果你以前使用過(guò)VSS,在學(xué)習(xí)Subversion時(shí)這個(gè)問(wèn)
題一定要注意。Checkout的具體方式是:在客戶端新建一個(gè)空目錄,比如:F:\Project1
在該目錄上單擊右鍵,在彈出式菜單中選中SVN Checkout...,之后在“URL of
Repository”文本框中填入你想要連接的Repository的地址,對(duì)于在本教程第二節(jié)建立的Repository,URL應(yīng)該是“svn:
//xxx/project1” (xxx可以是服務(wù)器端主機(jī)名,也可以是服務(wù)器端的ip地址)。
然后點(diǎn)OK,會(huì)彈出一個(gè)認(rèn)證對(duì)話框,輸入在教程第三節(jié)設(shè)置的用戶名和密碼。點(diǎn)OK后就完成了對(duì)Repository的Checkout。比如:在服務(wù)器端
Repository中有一個(gè)a.txt文件,那么Checkout之后F:\Project1目錄下也會(huì)出現(xiàn)一個(gè)a.txt文件。在本例中由于服務(wù)器端
的Repository還未添加任何文件,所以在客戶端的F:\Project1下沒(méi)有文件被Checkout。執(zhí)行Checkout除了會(huì)在F:\
Project1產(chǎn)生Repository存儲(chǔ)的文件及目錄外,還會(huì)產(chǎn)生了一個(gè)“.svn”的隱含目錄,該目錄是由subversion管理的,不要?jiǎng)h除
或者手工改動(dòng)其中的文件和目錄。現(xiàn)在F:\Project1中的文件和目錄就叫做Repository的“Working
Copy”簡(jiǎn)寫“WC”(這個(gè)簡(jiǎn)寫...汗)。以后對(duì)Repository中文件和目錄的修改,添加,刪除的操作,都是通過(guò)對(duì)這個(gè)“Working
Copy”的操作實(shí)現(xiàn)的。Checkout執(zhí)行完后,會(huì)發(fā)現(xiàn)F:\Project1目錄的圖標(biāo)的左下角附著了一個(gè)小的狀態(tài)圖標(biāo)(當(dāng)F:\Project1
目錄中的文件改變時(shí),這個(gè)狀態(tài)圖標(biāo)也會(huì)隨之變化),它表示F:\Project1是一個(gè)Repository的“Working
Copy”,F(xiàn):\Project1內(nèi)的所有文件和目錄也會(huì)有類似的狀態(tài)圖標(biāo)。
2.添加文件
將要添加的文件或者目錄拷貝到F:\Project1下,然后在該文件或目錄上單擊右鍵,TortoiseSVN->Add,點(diǎn)OK。如果添加了不
止一個(gè)文件或目錄,則鼠標(biāo)不要在F:\Project1中點(diǎn)中任何文件,然后單擊右鍵,TortoiseSVN->Add,就可以添加多個(gè)文件或目
錄。這時(shí)文件的狀態(tài)圖標(biāo)會(huì)發(fā)生變化。Add命令只是告訴本地的“Working
Copy”將該文件納入版本管理,并沒(méi)有將這個(gè)改變提交到服務(wù)器端,如果想要?jiǎng)e人也看見(jiàn)你對(duì)Repository的修改,你需要
在F:\Project1下單擊右鍵,SVN
Commit...,將你所做的修改提交到Repository。文件的狀態(tài)圖標(biāo)也會(huì)更新。不管你在“Working
Copy”內(nèi)添加、修改、刪除文件后,要想其他人也看見(jiàn)你的修改,都必須用Commit命令將所做修改遞交到服務(wù)器端的Repository。
3.修改文件
用文本編輯器或IDE對(duì)文件修改后,文件的狀態(tài)圖標(biāo)會(huì)變化,然后單擊右鍵,SVN Commit...
提交修改,只有當(dāng)執(zhí)行Commit提交修改后,你所作的修改才會(huì)反映到服務(wù)器端的Repository中。
4.刪除文件
刪除文件時(shí),選中要?jiǎng)h除的文件或目錄,單擊右鍵,TortoiseSVN->Delete,提交修改。注意千萬(wàn)不要用“Delete”鍵來(lái)刪除文件,否則將無(wú)法提交你的修改。這一點(diǎn)對(duì)目錄的刪除來(lái)說(shuō)尤為重要。
5.放棄修改
當(dāng)你添加、修改、刪除文件后,決定放棄修改,你可以單擊右鍵,TortoiseSVN->Revert,本地的“Working Copy”中的文件和目錄會(huì)恢復(fù)到你修改前的狀態(tài)。
6.獲取Repository的最新版本
當(dāng)一個(gè)團(tuán)隊(duì)合作開(kāi)發(fā)項(xiàng)目時(shí),每一個(gè)人都在不斷的對(duì)Repository進(jìn)行更新,你需要不斷的更新自己的“Working
Copy”,以獲取項(xiàng)目最新的文件。當(dāng)?shù)谝淮潍@得最新Repository的文件時(shí),我們用Checkout命令,前面已經(jīng)介紹了,以后再獲取最新文件時(shí)
就不用Checkout了。而改用Update命令。接著前面的例子,這時(shí)F:\Project1已經(jīng)成為一個(gè)“Working
Copy”了(通過(guò)執(zhí)行Checkout命令),現(xiàn)在其他人已經(jīng)對(duì)Repository進(jìn)行了修改,我想將別人的修改反映到我的“Working
Copy”中,具體的方法是:在F:\Project1目錄上單擊右鍵,SVN
Update。這時(shí)F:\Project1中的文件就是最新的版本了。注意,如果當(dāng)你的“Working
Copy”中有被修改的文件,或者有被刪除的文件,并且還未提交這些修改時(shí),這些文件在執(zhí)行Update過(guò)程中是不會(huì)被更新的。比如你修改了F:\
Project1下a.txt文件,還未提交修改,那么,當(dāng)你對(duì)F:\Project1進(jìn)行Update時(shí),a.txt文件是不會(huì)更新為
Repository上的a.txt文件的。所以如果想放棄當(dāng)前的所有修改,并將F:\Project1下所有文件及目錄更新到最新版本應(yīng)該先對(duì)F:\
Project1執(zhí)行Revert命令再執(zhí)行Update命令。
7.subversion的版本控制模型
當(dāng)你用subversion進(jìn)行版本控制時(shí),Subversion會(huì)記錄你對(duì)Repository進(jìn)行的每一次修改(包括添加,修改,刪除等等),每修改
一次Repository都會(huì)產(chǎn)生一個(gè)新的Revision(修訂版本號(hào)),不同的Revision代表了不同時(shí)刻Repository的狀態(tài),因此我們
可以用這個(gè)Revision回朔任意時(shí)刻Repository的狀態(tài),就像時(shí)間機(jī)器一樣,也就是說(shuō)某一Revision 就是Repository
在某一時(shí)刻的一個(gè)“快照”。注意:Revision
不是針對(duì)某一個(gè)文件或者目錄,而是針對(duì)整個(gè)Repository而言的。每修改一次Repository,Revision 都會(huì)增加1。
Subversion的版本控制模型是一種叫做Copy-Modify-Merge(拷貝-修改-合并)的模型。考慮這種情況:張三和李四是公司同一個(gè)部
門的同事,他們共同維護(hù)一個(gè)文本文件a.txt,并且對(duì)該文件進(jìn)行版本控制,因此他們把這個(gè)文件放到一個(gè)Repository上共同維護(hù)該文件。周一上午
9點(diǎn),張三和李四同時(shí)想對(duì)a.txt文件進(jìn)行修改,于是他們同時(shí)從Repository上取得該文件的最新版本(Revision
10),然后進(jìn)行修改。過(guò)了三分鐘,張三首先完成了修改,他在該文件的第五行修改了一個(gè)單詞的拼寫(將Typo改為Type),于是張三對(duì)修改后的文件執(zhí)
行Commit 命令,將修改提交到服務(wù)器端的Repository 中。這時(shí)Repository 的Revision
變?yōu)?1。六分鐘過(guò)后,李四也完成了他的修改,他修改了該文件第十行上的一個(gè)單詞拼寫(將He改為She),于是他也對(duì)修改后的文件執(zhí)行Commit
命令,這時(shí)Subversion 在提交修改時(shí)會(huì)發(fā)現(xiàn),李四修改的文件是Revision 10的a.txt文件,而不是最新的Revision
11的a.txt文件。于是,Subversion 提示李四在提交修改前,應(yīng)該先將Working
Copy更新到最新版本,李四執(zhí)行Update命令將Working Copy更新到Revision
11,這時(shí)Subversion會(huì)提示已經(jīng)完成合并,李四的a.txt文件的第五行的“Typo”已經(jīng)變?yōu)榱?#8220;Type”,第十行還是“She”,就是說(shuō)
Subversion
已經(jīng)將張三的修改“合并”到李四的a.txt文件中了。之后,李四再執(zhí)行Commit命令,就能將他對(duì)第十行的修改(將He改為She)提交到服務(wù)器端的
Repository中了(生成Revision
12)。但是這種合并在某些情況下會(huì)變得復(fù)雜一些,比如:李四對(duì)a.txt文件的修改并不是第十行,而是與張三同樣修改第五行的單詞,李四將“Typo”
改為“Typr”,并且提交修改,這時(shí)Subversion會(huì)提示李四在提交修改前,應(yīng)該先將Working
Copy更新到最新版本,李四執(zhí)行Update命令將Working Copy更新到Revision
11,這時(shí)Subversion將Revision11的a.txt文件與李四修改的a.txt文件進(jìn)行合并時(shí)發(fā)現(xiàn)李四修改的同樣是第五行,于是
Subversion就無(wú)法判斷是李四的修改(“Tpyr”)正確還是張三的修改(“Type”)正確,因?yàn)樗麄兌际窃赗evision10的a.txt
基礎(chǔ)上作的修改。這種情況叫做Conflict(沖突),a.txt文件的圖標(biāo)會(huì)變成一個(gè)黃色三角。這時(shí),只能依靠李四自己去判斷到底第三行應(yīng)該修改為
“Typr”還是“Type”。當(dāng)李四確定修改之后,在a.txt文件上單擊右鍵,TortoiseSVN->Resolved
告訴Subversion已經(jīng)解決了Conflict。這時(shí)再執(zhí)行Commit命令就能提交修改(生成Revision 12)。Subversion 這種控制方式保證了你對(duì)文件所作的修改都是基于文件的最新版本。
8.“.svn”目錄
在客戶端Working
Copy的每一層目錄中都會(huì)有一個(gè)“.svn”目錄,該目錄是Subversion進(jìn)行管理用的目錄。不要手動(dòng)修改其中的文件。該目錄存儲(chǔ)了
Working
Copy的一個(gè)副本(實(shí)際存儲(chǔ)副本的地方是F:\project1\.svn\text-base目錄),比如:F:\Project1是一個(gè)
Working
Copy,該目錄下有兩個(gè)文件a.txt和b.txt還有一個(gè)子目錄ccc,子目錄ccc中還有一個(gè)d.txt文件。“.svn”目錄中存儲(chǔ)的是你最近一
次執(zhí)行完Update或者Commit命令之后當(dāng)前目錄中文件的副本,比如:F:\project1\.svn\text-base中存儲(chǔ)的a.txt和
b.txt是最近一次執(zhí)行完Update或者Commit命令之后F:\project1下的a.txt和b.txt的拷貝。也就是說(shuō)你所作的修改都是基
于“.svn”目錄存儲(chǔ)的那些文件。這種機(jī)制可以讓我們?cè)诓贿B接網(wǎng)絡(luò)的情況下,將Working
Copy中的文件恢復(fù)到修改之前的狀態(tài)。Subversion的Revert命令就是利用了這種機(jī)制來(lái)實(shí)現(xiàn)的。比如你修改了F:\project1\
a.txt文件,這時(shí)你又改變了主意想放棄對(duì)該文件的修改,你可以單擊右鍵,TortoiseSVN->Revert,修改過(guò)的F:\
project1\a.txt文件就會(huì)被F:\project1\.svn\text-base中a.txt文件的副本所替代,使得a.txt恢復(fù)到修改
前的狀態(tài)。
Working
Copy中每一個(gè)子目錄下都會(huì)有一個(gè)“.svn”目錄,并不是只有最上層目錄才有“.svn”目錄。所以,F(xiàn):\project1\ccc下也有一個(gè)
“.svn”目錄,該目錄存儲(chǔ)的是F:\project1\ccc\d.txt的副本(d.txt的副本位于F:\project1\ccc\.svn\
text-base)。也就是說(shuō)每個(gè)“.svn”目錄只存儲(chǔ)同級(jí)目錄中的“文件”副本,而不存儲(chǔ)“目錄”副本。“.svn”目錄存有許多重要的內(nèi)容,所以
前面說(shuō)在刪除文件或目錄時(shí),必須用TortoiseSVN->Delete,而不能用“Delete”鍵來(lái)刪除文件或目錄,尤其是對(duì)于目錄的刪除。
9.混合版本
Subversion的Working Copy被設(shè)計(jì)成一種能夠包含不同版本的文件共存的形式。比如F:\Project1是一個(gè)Working
Copy,該目錄下有兩個(gè)文件a.txt和b.txt。執(zhí)行Update命令,將Working Copy更新到最新版本(Revision
24)。這時(shí),a.txt和b.txt的Revision都是24(其實(shí)對(duì)于單個(gè)文件來(lái)說(shuō)并不存在Revision,Revision是對(duì)于整個(gè)
Repository而言的,這里所指的是Repository的Revision24所存儲(chǔ)的a.txt和b.txt,但為了方便而采用這種描述方式,
請(qǐng)注意,下同)。之后,你的同事修改了a.txt,并且提交了修改,這時(shí)Repository的Revision就變成25了。注意,這時(shí)你沒(méi)有再次執(zhí)行
Update,因此你的Working
Copy的Revision還是24。這時(shí)你修改了b.txt文件,并提交修改。因?yàn)镽evision25并沒(méi)有對(duì)b.txt文件進(jìn)行修改,因此你對(duì)
b.txt文件的修改是基于b.txt文件最新的版本,所以不會(huì)出現(xiàn)Conflict。當(dāng)你提交b.txt的修改后,產(chǎn)生Revision26。這時(shí)你會(huì)
發(fā)現(xiàn)你的Working
Copy中的a.txt文件并不是Revision25中的a.txt文件,它還是Revision24的a.txt文件,而你的b.txt文件是
Revision26的b.txt文件。也就是說(shuō)當(dāng)你Commit時(shí),你的Working
Copy中只有你提交的那些文件是最新版本,而其他沒(méi)有修改的文件并不會(huì)更新為最新版本。這樣就造成了你的Working
Copy由不同的Revision文件所組成(Revision24的a.txt文件和Revision26的b.txt文件)。前面說(shuō)過(guò)在提交修改前必
須保證你是在文件的最新版本基礎(chǔ)上修改,如果在這種混合版本的情況下,怎樣才能知道當(dāng)前Working
Copy中的文件是否為最新版本?在前面所說(shuō)的“.svn”目錄中有一個(gè)文件名為“entries”的文件,該文件記錄了當(dāng)前Working
Copy中的每一個(gè)文件的Revision,因此當(dāng)你Commit時(shí),Subversion會(huì)從該文件中取得你提交文件的Revision,再與
Repository的最新Revision一比較就可以知道你修改的文件是否基于該文件的最新版本。
10.文件的鎖定
前面說(shuō)過(guò)Subversion的版本控制模型是一種叫做Copy-Modify-Merge(拷貝-修改-合并)的模型。該模型在對(duì)文本文件進(jìn)行版本控制
時(shí)工作的很好,但是有些需要進(jìn)行版本控制的文件并不是文本文件,比如說(shuō)圖像文件,這種模型在這種情況下就不能正常工作了,因?yàn)槲谋疚募梢院喜ⅲM(jìn)制
文件則無(wú)法合并。所以Subversion從1.2開(kāi)始支持一種叫Lock-Modify-Unlock(鎖定-修改-解鎖)的版本控制模型。在
Windows下最常用的版本控制軟件Visual Source
Safe(VSS)就是采用這種模型。這種模型要求在對(duì)一個(gè)文件修改前首先要鎖定這個(gè)文件,然后才能修改,這時(shí),別人將無(wú)法對(duì)該文件進(jìn)行修改,當(dāng)修改完后
再釋放鎖,使其他人可以對(duì)該文件進(jìn)行鎖定,然后修改。鎖定文件的方法是:TortoiseSVN->Get
Lock...再點(diǎn)OK按鈕,這時(shí)就完成了對(duì)文件的鎖定。這時(shí),如果其他人想對(duì)文件進(jìn)行鎖定時(shí),Subversion會(huì)對(duì)他提示該文件已經(jīng)被別人鎖定。當(dāng)
你修改完文件后,然后單擊右鍵,SVN
Commit...,將修改提交,默認(rèn)情況下,提交的時(shí)候就會(huì)對(duì)該文件解鎖,如果你想仍然鎖定該文件,請(qǐng)?jiān)赾ommit時(shí)彈出的對(duì)話框中選中keep
lock復(fù)選框。
11.文件的附加屬性
在Subversion中,每個(gè)文件可以擁有一種叫做附加屬性的東西。附加屬性描述了該文件所擁有的一些特性。Subversion已經(jīng)預(yù)定義了一些附加
屬性(這里只是指Subversion已經(jīng)定義了一些附加屬性的“名稱”,并不是指已經(jīng)將這些屬性附加在文件上了,比如默認(rèn)情況下文本文件一開(kāi)始不含任何
屬性,直到人為的對(duì)該文件添加附加屬性),并且你可以對(duì)文件添加自定義的屬性。Subversion對(duì)待附加屬性就像對(duì)待文件內(nèi)容一樣,當(dāng)修改了一個(gè)文件
的附加屬性(添加,改變,刪除附加屬性),即使沒(méi)有對(duì)文件的內(nèi)容進(jìn)行修改,同樣可以Commit該文件,就像更改了文件內(nèi)容那樣,Repository也
會(huì)生成新的Revision,所以從某種意義上來(lái)說(shuō),Subversion不區(qū)別對(duì)待文件的附加屬性的修改和文件的內(nèi)容的修改,文件的附加屬性可以看成是
一種特殊的文件內(nèi)容。Subversion預(yù)定義了若干個(gè)附加屬性,這里只討論“svn:needs-lock”屬性,因?yàn)樗c我們上面的文件鎖定會(huì)產(chǎn)生
的一個(gè)問(wèn)題有關(guān)。其他的屬性可以參考Subversion自帶的幫助文檔。考慮這種情況,張三和李四同時(shí)想對(duì)一個(gè)圖片文件a.jpg作修改,張三在修改時(shí)
先將該文件鎖定,然后進(jìn)行修改,同時(shí)李四也開(kāi)始對(duì)該文件進(jìn)行修改,但李四忘記了對(duì)非文本文件進(jìn)行修改時(shí)應(yīng)該先鎖定該文件。張三首先對(duì)該文件修改完畢,于是
張三向服務(wù)器提交了他的修改。之后,李四也完成了修改,當(dāng)他提交修改時(shí),Subversion提示李四的文件版本不是最新的,在Commit之前應(yīng)先更新
a.jpg到最新版本,由于圖片文件無(wú)法合并,這就意味著張三和李四之間必定有一個(gè)人的修改會(huì)作廢。應(yīng)用“svn:needs-lock”屬性可以避免這
個(gè)問(wèn)題。當(dāng)一個(gè)文件擁有“svn:needs-lock”屬性時(shí),該文件在沒(méi)有鎖定時(shí),文件的圖標(biāo)是灰色的,表示該文件是一個(gè)只讀文件(該文件的
Windows只讀屬性的復(fù)選框?yàn)檫x中),這個(gè)灰色的圖標(biāo)就會(huì)提醒想對(duì)該文件進(jìn)行修改的人,在修改該文件之前應(yīng)該首先鎖定該文件。鎖定該文件之后,文件的
只讀屬性就會(huì)去掉了,一旦釋放掉鎖,文件的圖標(biāo)又會(huì)變成灰色,文件也會(huì)變成只讀的了。李四在這種情況下就會(huì)避免在沒(méi)有鎖定文件時(shí)對(duì)文件進(jìn)行修改。對(duì)非文本
文件添加“svn:needs-lock”屬性應(yīng)該在將該文件第一次添加到Repository時(shí)就設(shè)置,當(dāng)然,一個(gè)文件可以在任意時(shí)刻添加附加屬性,這
樣做是為了減少李四所遇到的那個(gè)問(wèn)題發(fā)生的幾率。具體的方法是:首先將a.jpg文件拷貝到Working
Copy中,然后在該文件上單擊右鍵,TortoiseSVN->Add,告訴Subversion要將該文件納入版本控制,接著在該文件上單擊右
鍵并選中屬性,在彈出的屬性對(duì)話框中選中Subversion
頁(yè)。在下拉框中選中“svn:needs-lock”,并在下面的文本框中填入“*”(其實(shí)這里填什么都無(wú)所謂,只要文件有“svn:needs-
lock”附加屬性就行),之后點(diǎn)Set按鈕,“svn:needs-lock”附加屬性就設(shè)置好了。然后執(zhí)行Commit命令提交修改。這時(shí)當(dāng)其他人執(zhí)
行Update時(shí),a.jpg就會(huì)添加到他們的Working
Copy中,并且文件的附加屬性也會(huì)隨文件一起被得到。可以看到a.jpg此時(shí)的圖標(biāo)就是灰色的,文件的Windows屬性也是只讀的。
12.回到以前的版本
由于Subversion會(huì)記錄你對(duì)Repository的每一次修改,因此能夠很容易的獲得Repository以前某一時(shí)刻的狀態(tài)。比如:現(xiàn)在
Repository的最新Revision是56,這時(shí)我想看看Repository在Revision24時(shí)的狀態(tài),可以在本地的Working
Copy中單擊右鍵,TortoiseSVN->Update to
Revision...,然后輸入你想要回復(fù)到的Revision號(hào),點(diǎn)OK按鈕。
回到以前的版本還有一種情況是我想將Repository的最新Revision的狀態(tài)與以前某一個(gè)Revision的狀態(tài)一模一樣,上面那種方法就不適
合,上面的那種方法只是將本地的Working
Copy回復(fù)到以前的狀態(tài),而服務(wù)器端的Repository并沒(méi)有回到以前的狀態(tài)。將Repository的最新Revison的狀態(tài)回復(fù)到以前某個(gè)
Revision的狀態(tài)具體的方法是:先執(zhí)行Update命令將Working Copy更新到最新的Revision,然后在Working
Copy中單擊右鍵,TortoiseSVN->Show Log,彈出的Log
Messages窗口中會(huì)顯示該Repository的所有Revision,選中最新的Revision,之后按住Shift鍵,再單擊你想回復(fù)到的
Revision+1的那個(gè)Revision(比如Repository的最新Revision是30,你想將Repository的狀態(tài)回復(fù)到
Revision16,那么就選中Revision30,再按住Shift鍵,選中Revision17,就是說(shuō)選中Revision17到
Revision30之間的所有Revision)。然后在選中的Revision上單擊右鍵,選中“Revert changes from
these revision”。再點(diǎn)Yes按鈕,就可以將Working Copy的狀態(tài)回復(fù)到目標(biāo)Revision。注意,此時(shí)
只是Working Copy回復(fù)到目標(biāo)Revision,之后應(yīng)該用Commit提交修改,這樣Repository最新?tīng)顟B(tài)就與目標(biāo)Revision的狀態(tài)一樣了。
這兩種回復(fù)到以前版本的方式截然不同,第一種方式是將整個(gè)Working Copy回復(fù)到某個(gè)Revision,也就是說(shuō)這種方式Working
Copy中的“.svn”目錄所存的文件副本也與目標(biāo)Revision的一模一樣,如果這時(shí)你沒(méi)有修改文件,你將不能執(zhí)行Commit命令。而第二種方式
客戶端Working
Copy中的“.svn”目錄所存的副本始終是最新的Revision的文件副本(這里我們基于一個(gè)假設(shè):在Update之后沒(méi)有其他人對(duì)
Repository做修改)。這種方式就像是我們自己手工將Working Copy的文件狀態(tài)修改為目標(biāo)Revision,在修改之后提交修改一樣。
13.查看修改
有時(shí)我們對(duì)Working Copy的許多文件進(jìn)行了修改,這些文件位于不同的子目錄,我們就可以在Working
Copy的最上層目錄單擊右鍵,TortoiseSVN->Check For
Modifications,彈出的對(duì)話框就會(huì)顯示你所做的所有修改明細(xì)。
還有一種情況是我們的Working Copy已經(jīng)很久沒(méi)有執(zhí)行Update命令,我們想看看Working
Copy中有哪些文件已經(jīng)發(fā)生修改了,這時(shí)就可以在Working Copy的最上層目錄單擊右鍵,TortoiseSVN->Check
For Modifications,在彈出的對(duì)話框點(diǎn)擊Check
Repository按鈕后,就會(huì)顯示服務(wù)器端已經(jīng)修改了的文件。該方法還有一個(gè)用途就是查看文件的鎖定,當(dāng)你想鎖定一個(gè)文件時(shí),你想先看看這個(gè)文件有沒(méi)
有被別人鎖定,點(diǎn)擊Check
Repository按鈕會(huì)顯示服務(wù)器端Repository所有被鎖定的文件,如果你想鎖定的文件不在這里面,那就說(shuō)明該文件目前沒(méi)有人鎖定