Subversion 簡介三千年版本控制 ![]() |
![]() |
![]() |
級別: 中級
Elliotte Harold
(elharo@metalab.unc.edu), 副教授, Polytechnic University 2006 年 7 月 06 日 Elliotte Rusty Harold 介紹了 Subversion —— 一種開放源碼、多用戶版本控制系統(tǒng),支持非 ASCII 文本和二進制數(shù)據(jù)。通過 Elliotte 的介紹,您可看到如何在 Eclipse 中配置 Subversion 支持(通過 Subclipse 插件)、檢出一個項目、與您的存儲庫同步,隨后執(zhí)行一些常用的操作,如合并、修補、比較和刪除。 版本控制之于程序員,就好比安全網(wǎng)之于高空秋千表演者。知道安全網(wǎng)就在那里,萬一自己摔落它能夠提供保護,高空秋千表演者才能放心大膽地在空中飛躍。同樣,版本控制使您有能力去冒以往想都不敢想的風險。如果哪兒出了錯,您總是可以使自己的代碼回復(fù)到一個已知的、工作正常的版本。您可以在不觸及主干的分支中進行試驗,而不會影響到其他小組成員。在已經(jīng)發(fā)布的產(chǎn)品的較老版本中發(fā)現(xiàn) bug 時,您可以輕松檢出特定版本,以確認、修訂,并生成該 bug 的修補程序。如果沒有版本控制,您必須極為慎之又慎,緩慢地推進,總而言之,生產(chǎn)力會更低。 Subversion 是一種開放源碼的全新版本控制系統(tǒng),支持可在本地訪問或通過網(wǎng)絡(luò)訪問的數(shù)據(jù)庫和文件系統(tǒng)存儲庫。不但提供了常見的比較、修補、標記、提交、回復(fù)和分支功能性,Subversion 還增加了追蹤移動和刪除的能力。此外,它支持非 ASCII 文本和二進制數(shù)據(jù),所有這一切都使 Subversion 不僅對傳統(tǒng)的編程任務(wù)非常有用,同時也適于 Web 開發(fā)、圖書創(chuàng)作和其他在傳統(tǒng)方式下未采納版本控制功能的領(lǐng)域。 本文介紹了使用 Subversion 追蹤項目的基礎(chǔ)知識,以使您在編寫代碼時能夠承受更多的風險、享受更多的樂趣。 當我還是一名剛剛畢業(yè)的學生時,我第一次在國家太陽觀察站(National SSolar Observatory)接觸到了如今版本控制系統(tǒng)的鼻祖 —— SCCS。今天,已經(jīng)出現(xiàn)了數(shù)不勝數(shù)的版本控制系統(tǒng),而 SCCS 也早已被更強大的產(chǎn)品所取代,如 Visual SourceSafe、BitKeeper、Perforce 和開源 CVS(參見 參考資料 部分)。 在開放源碼程序員間,CVS 已成為一種事實上的 標準。Codehaus、Sourceforge、Savannah 和 Java? 社區(qū)的 java.net 等站點中駐留的免費 CVS 使得為開源項目建設(shè)存儲庫更為簡單。以 CVS 為中心,已發(fā)展起一個大型的附件市場,包括 TortoiseCVS、ViewCVS 和 Fisheye 等工具。 與其他版本控制系統(tǒng)相比,CVS 最令人稱道的地方就是其非鎖定 存儲庫,這使多個開發(fā)人員能夠同時檢出同一個文件。CVS 在提交時解決沖突問題,這就避免了沖突成為發(fā)展的瓶頸。CVS 第二個出色的特性就是它是一種網(wǎng)絡(luò)存儲庫。處于許多不同系統(tǒng)上的程序員可以通過公共的 Internet 訪問相同的存儲庫。 CVS 在過去的十年中,為社區(qū)提供了優(yōu)質(zhì)的服務(wù),但它陳舊的劣勢開始體現(xiàn)出來。首先,它實際上僅能處理 ASCII 文件。Unicode 文件會令 CVS 嚴重混亂。此外,CVS 存儲庫更改起來極為困難。CVS 沒有任何關(guān)于 “移動” 操作的概念。它只能注意到,一個文件在一處被刪除了,而在一個新位置創(chuàng)建了另外一個文件。由于它不會連接兩個操作,因此也很容易使文件歷史軌跡丟失。設(shè)置 CVS 存儲庫時,您必須非常謹慎地為每個文件選擇準確的位置,因為在設(shè)置之后,您幾乎就要一直使用這個位置了。 CVS 已經(jīng)不再適合現(xiàn)代開發(fā),這一點越來越明顯。特別是 CVS 只能滿足老式 C 程序員的 ASCII 需求,而對 Web 開發(fā)人員和其他非傳統(tǒng)用戶來說,CVS 實際上根本不起作用。在您開始考慮存儲整個 Web 站點時,在 CVS 中,將文件從一個目錄移動到另外一個目錄是關(guān)鍵考慮事項。因此,在幾年前,許多核心 CVS 開發(fā)人員認為,已經(jīng)到了利用他們多年來使用 CVS 時學到的經(jīng)驗和教訓、從頭開始創(chuàng)建新一代開放源碼存儲庫的時機。在 2004 年年初,他們的努力結(jié)出了豐碩的果實,那就是 Subversion 1.0。 程序員(特別是那些依賴版本控制的程序員)是一個非常謹慎的群體,Subversion 著實用了很長一段時間,才得到他們的廣泛接受。很少有程序員愿意沖在易于流血的最前沿,即便是他們已經(jīng)因為 CVS 受了傷。甚至是在 Subersion 變得可靠之后,仍然用了好幾年的時間,所有第三方編輯器、IDE 和文檔規(guī)范才相繼跟進。而 Subversion 依然在不斷改進,BBEdit 和 Eclipse 等第三方工具現(xiàn)在已經(jīng)有了足夠好的 Subversion 支持。逐漸地,新項目也紛紛選擇 Subversion 滿足其版本控制需求,而老項目正在向 Subversion 移植。最近,Apache Software Foundation 已移植到 Subversion。已實現(xiàn)移植的項目包括 Xerces XML 解析器、Apache HTTP Server 和 Spamassassin。
您可通過命令行使用 Subversion,但若將其與您的 IDE 集成更為便捷。IntelliJ IDEA 5.0 及后續(xù)版本均包含對 Subversion 的內(nèi)置支持。NetBeans 還不支持 Subversion,但相關(guān)工作已經(jīng)在開展,未來版本中將提供支持。對于 Eclipse,您需要安裝 Subclipse 插件。本文使用 Eclipse 作為 IDE。 Subclipse 的安裝與其他 Eclipse 插件類似:
程序包目前未經(jīng)過數(shù)字簽名,但只要您是按照第三步的 URL 下載的,就是安全的。
安裝程序包后,您必須重新啟動 Eclipse,隨后才能使用 Subversion。完成之后,您就可以與如今使用 CVS 大體相同的方式使用 Subversion 了,只有為數(shù)不多的區(qū)別。 設(shè)置一個新的 Subversion 存儲庫,特別是網(wǎng)絡(luò)存儲庫相對來說較為復(fù)雜。但若您正在連接一個現(xiàn)有項目,第一次檢出文件就相當輕松。在 File 菜單中選擇 New/Other...。這些步驟將為您打開如 圖 1 所示的對話框: 圖 1. 通過 Subversion 啟動一個新項目 ![]() 接下來,打開 SVN 文件夾,選擇 Select Checkout Projects from SVN,并單擊 Next 以顯示如圖 2 所示的對話框: 圖 2. Select/Create Location ![]() 第一次從存儲庫檢出時,您需要選擇 Create a new repository location 并單擊 Next。這將為您打開如圖 3 所示的對話框: 圖 3. 為存儲庫鍵入 URL ![]() 您在這里提供存儲庫的 URL。這只是一個普通的 http URL,如 http://svn.apache.org/repos/asf/xerces/java/。這一次單擊 Next 時,Eclipse 連接到存儲庫,并查找可檢出的文件夾。通常有三個文件夾:branches、tags 和 trunk,如圖 4 所示。Branches 文件夾用于試驗。Tags 通常標識較老的、已發(fā)布的軟件版本。而大多數(shù)時候,您都希望在主分支上工作(CVS 稱之為 HEAD),因此選擇 trunk 并單擊 Next。 圖 4. 選擇要檢出的修訂版 ![]() 您現(xiàn)在有兩個選擇:Check out as a Project configured using the New Project Wizard 或 Check out as a project in the workspace,如圖 5 所示。您可按自己的需要任意選擇,您可能希望為項目命名,因為默認名稱為 “trunk”。最后,單擊 Finish。 圖 5. 檢出項目的兩種方法 ![]() Eclipse 現(xiàn)在從您選擇的分支、主干或標記中下載所有源文件。如果您選擇的是 Check out as a project in the workspace,則必須完成 Eclipse 的 New Project 向?qū)В栽O(shè)置編譯器級別、項目布局和其他選項。如果您未使用 New Project 向?qū)В瑒t需要手動設(shè)置構(gòu)建路徑和其他選項,就像您在自己的文件系統(tǒng)的一個目錄中創(chuàng)建了一個項目那樣。確實,您所做的與那極為相似。所有文件都是本地存儲的。對于構(gòu)建、運行和調(diào)試這樣的普通操作,Eclipse 不關(guān)心文件是否已為版本控制檢出。
此時,最好進行一次快速、明智的檢查,確保您已正確地設(shè)置了構(gòu)建路徑。如果沒有明顯的問題,并且能夠運行單元測試,那么即可放心地繼續(xù)下去了。 如果存在問題,檢查項目屬性,以確保正確地設(shè)置了源路徑和類路徑。使之差一非常常見,無論是多一還是少一。因此,最終 Eclipse 會認為您的類的名稱類似于
要檢查錯誤,選擇 Project | Properties,然后找到 Java Build Path。您可在 source 選項卡中修訂任何向?qū)ё鲥e的地方。您可能還要添加另外一個項目需要的 JAR 歸檔,Eclpse 在檢出時不會注意到此歸檔。您還可在 library 選項卡的 Java Build Path 中添加此歸檔。 請做好心理準備,您可能要在這里花上一點時間。Eclipse 很少會在第一次就讓一切正確無誤,每個項目組織其文件和庫的方式又總會有所不同。 接下來您就可以照常編輯文件了。作出您希望的任何更改。運行單元測試。優(yōu)化代碼。更正注釋中的拼寫錯誤。完成部分工作后,使用上下文菜單并選擇 Team/Commit...。您將看到圖 6 所示的對話框,要求您輸入提交注釋: 圖 6. Subclipse 的提交對話框 ![]() 同樣,若其他人更改了您希望應(yīng)用于您的副本的存儲庫,只要在 Package Explorer 中選中文件,并從上下文菜單中選擇 Team/Update 即可。這會以主副本替換您的副本。
如果您已進行了更改,其他開發(fā)人員也進行了更改,那么您就必須手動合并文件。對于絕大多數(shù)簡單更改,Subversion 可推斷出需要進行怎樣的處理,無需人工干預(yù)。但對于較大、較為復(fù)雜、存在沖突的更改,您可能需要參與進來,手動合并更改。 Subclipse 在這里可提供一些幫助,但實際上我發(fā)現(xiàn),在一個獨立的窗口或選項卡中直接實現(xiàn)一個臨時文件副本,通過存儲庫更新本地副本以覆蓋我的更改,然后通過臨時副本重新輸入更改,這樣做往往更容易。若存儲庫中的更改與我做出的更改相比較少,我就會從存儲庫實現(xiàn)臨時副本,并通過它進行提交,而不是更新。隨后我會重新應(yīng)用那些更改。這聽上去非常復(fù)雜,但事實通常并非如此,它的發(fā)生幾率幾乎與您希望的一樣低。即便是您出了錯,忘記重新應(yīng)用更改或是錯誤地應(yīng)用了更改,總是可以找到所有更改的完整歷史(包括您覆蓋的那些更改)供您參考。實際上您從未徹底丟失任何東西。 如果您不確定已更改了哪些文件,同步視圖可以為您顯示這些文件。您還可打開標簽修飾(label decoration)來查看上次提交/更新后哪些文件發(fā)生過更改。選擇 Help | Preferences,然后再選擇 General/Appearance/Label Decorations。然后選中 SVN 復(fù)選框。(實際上該復(fù)選框在默認情況下就是選中的。)
如果您不具備正在使用的存儲庫的提交權(quán)限,就需要制作一個修補程序,然后將其發(fā)送給維護人員。只要選中您希望比較的文件,然后從上下文菜單中選擇 Team/Create Patch... 即可。您可以隨自己的方便將修補程序保存到文件或剪貼板中。隨后可通過電子郵件將其發(fā)送給維護人員,或者在 bug 報告中附上該修補程序。修補程序本身采用的格式與 CVS 所使用的 diff 格式相同。 應(yīng)用他人發(fā)送給您的修補程序就沒那么復(fù)雜了,只要選中您想修補的文件或項目。從上下文菜單中選擇 Team/Apply Patch... ,然后平臺上慣用的 open file 對話框選擇修補程序文件即可。
如果您已作出了一些更改,并且希望看看您的副本與存儲庫中的版本有怎樣的差別,只需在上下文菜單中選擇 Compare/Latest From Repository 即可。這實際上與 CVS 中比較功能的工作方式完全相同。圖 7 顯示了比較功能的工作情況: 圖 7. 在 Subclipse 中比較兩個文件 ![]()
刪除文件也很輕松。只要在 Eclipse 的程序包管理器中刪除文件,然后提交父文件夾即可。刪除目錄要略微復(fù)雜一點。您可以選擇一個目錄并刪除它。目錄中的所有文件將會立即被刪除。但在您刪除后,目錄本身及其所有子目錄又會立即出現(xiàn)在原來的位置。要真正地刪除一個文件夾,您需要選中 “已刪除” 的文件夾并提交它。同一規(guī)則也適用于將一個文件從一個位置移動到另外一個位置的情況。
在您刪除了一個文件或一個文件夾之后,依然可以通過存儲庫使其還原,即便是已經(jīng)提交了刪除。一旦您將任何內(nèi)容放進存儲庫,那么就永遠不會真正、永久地失去它,這有時候會產(chǎn)生問題。例如,假設(shè)您發(fā)現(xiàn)有人意外的檢入了其整個主目錄,包括其 Quicken 數(shù)據(jù)文件和所有來自其愛人的情書歸檔。您很希望能夠徹底消除 這些被誤提交的文件,這樣就不會有其他人得到這些文件。盡管這是一個非同尋常的操作(無論如何,版本控制系統(tǒng)的目的就在于永遠地保留每一個文件的每個修訂版),但有時也是必要的。令人沮喪的是,Subversion 漏掉了這個重要的特性。 由于沒有徹底消除的命令,所以我在為外部可見的存儲庫使用 Subversion 時非常不安。CVS 也沒有這樣的命令,但在 CVS 中,您完全有可能在不毀掉存儲庫的情況下手動刪除錯誤提交的文件。
對于內(nèi)部存儲庫,Subversion 提供了遠超過 CVS 的改進。如果添加了某種類型的徹底消除功能,它也應(yīng)同樣適于外部存儲庫。盡管像 Eclipse 這樣的工具對 Subversion 的第三方支持還不像 CVS 支持那樣普遍,但形勢正在迅速地發(fā)生變化。Subversion 會成為新項目的默認源代碼存儲庫。尚無源代碼控制的現(xiàn)有項目應(yīng)盡快檢入 Subversion。而已有 CVS 存儲庫的現(xiàn)有項目可能仍在觀望,希望等到他們所依賴的全部工具均全面支持 Subversion 后再進行切換。但這些項目最終也會移植到 Subversion。Subversion 中的改進如此顯著,令人難以忽略。未來必將屬于 Subversion。
學習
獲得產(chǎn)品和技術(shù)
討論
|