分佈式版本控制系統Mercurial(一):Mercurial基本功能介紹

版本控制系統(Version Control System / Revision Control System,或者叫做源碼控制系統Source Control System,以下簡稱VCS),是軟件開發人員最常用的工具之一,由於VCS是如此常用,所以花一些時間去了解它是有必要的。

 

  • 分佈式版本控制系統(Distributed Version Control System,DVCS),是相對於集中式版本控制系統(Centralized Version Control System,CVCS)而言的,比如,使用人數最多的SVN、VSS就是典型的CVCS。如果你曾經用過SVN或VSS,就可以很容易理解什麼叫做“Centralized” 。CVCS,是指只有一份數據倉庫存放在一臺服務器上,所有客戶端都連接到這臺服務器以讀寫數據倉庫的工作模型。而DVCS模型則不然,每一臺終端都有一份完整的數據倉庫,所有終端之間都是平等的,並不存在唯一的一臺“服務器”。所有的終端之間,可以自由地交換數據。

DVCS可以很容易地模擬CVCS的工作方式,只要指定任意一臺終端作爲服務器,規定所有人都將更改推送到這臺服務器,並且所有人也都從這臺服務器獲取更新即可。而與CVCS相比,DVCS則有以下優點:

a) 更加安全的代碼管理。
在SVN中,每次提交都意味着正式的代碼被更改,別人可以立即看到此次提交,並且可能直接影響到正在運行的系統(可能會有人立即將此更新拷貝到服務器),這導致一系列的問題。首先一個問題是,有人可能會無意中提交錯誤的、不可靠的代碼。其次,這導致程序員不敢輕易簽入更改,當程序進行一項耗時很久,大量修改的工作時,所有的修改都是沒有經過VCS保護的,這是非常危險的,也不符合使用VCS的初衷。


而在DVCS中則不同,因爲首先提交到自己本地倉庫中,所以程序員可以儘量地向數據倉庫提交更改,而不用擔心這會影響到其他人或系統,這可以將程序員在開發過程中所產生的各個版本代碼完善地保護起來,在週期較長的開發中,這一特點尤其顯得重要。

 

雖然在SVN中有分支功能可以達到類似的目的,但是分支合併操作起來較爲繁瑣,而且非常容易發生衝突,結果就是很多應當使用分支的場合其實並沒有使用分支。

b) 擺脫網絡的束縛,隨時進行完整的工作。
在SVN中,由於中央倉庫只有一個,所以任何需要與倉庫溝通的動作(例如查詢歷史版本,提交更改等等)必須首先聯網,而在有些時候,這一束縛就顯得不方便,而在DVCS中,則隨時可以與數據倉庫進行無縫的溝通,程序員可以向其中不停提交新的更改,或查詢某個文件的歷史版本,都可以在完全斷網的情況下進行。

c) 更加智能的代碼合併。
當兩個人對同一份代碼進行工作時,兩個人的修改可能會產生衝突。然而,SVN當新的更改被提交時,SVN只能查看最終的版本,這導致SVN對某些差異很大的文件無法自動合併,而人工合併是很費時費力的。在Mercurial中,當兩個不同的版本需要進行合併時,DVCS可以使用這個文件所有的修改歷史來一步一步地還原整個修改的過程,這樣一來,Mercurial的合併能力就遠遠地超過了SVN,所以在Mercurial中,極少會出現人工合併的問題。

d) 更快的反應速度. 由於各種日常操作都是在開發人員的本機進行的, 所以與任何的CVCS相比, DVCS的操作反應速度都將快很多倍.

另外,對於個人項目來說,尤其適合使用DVCS,因爲DVCS天然地擅長管理本地的數據倉庫,不像CVCS那樣必須架設一個服務端,一個客戶端。

 

因此總的來說,分佈式結構的Mercurial具有SVN的所有優點,而又比SVN更加合理有效。

 

目前的DVCS最主要有Mercurial和Git兩款軟件,其中Git的原作者是Linus大神,用C語言編寫,運行性能優於Mercurial(Mercurial是用Python寫的,天生註定性能不可能比Git更快),但是Linus以及最初的開發團隊並不打算開發Windows版本的Git,所以Git本身並不支持Windows,後來有了一個msysgit項目將Git移植到了windows平臺,並且有了開發了一個TortoiseGit客戶端,使得Git在windows下也變得容易使用了,但是在我使用的過程中,連續發生多次嚴重的故障,我懷疑其在windows下還不夠成熟,因此採用與操作系統兼容完美的Mercurial。 Mercurial這個單詞是水銀的意思,所以Mercurial的命令名採用了水銀的化學元素符號hg,這也是爲什麼它的圖形終端叫做TortoiseHg,而不是TortoiseMercurial之類的。

 

這裏(http://hgbook.red-bean.com/read/)有一份完整的Mercurial文檔,詳細描述了Mercurial的各種細節,不過鑑於其是英文的,我簡單再羅列一下Mercurial的基本用法。

 

首先,下載並安裝一個TortoiseHg with Mercurial(http://tortoisehg.bitbucket.org/), TortoiseHg是一個圖形化的客戶端,集成於Windows explorer,與TortoiseSVN是極爲類似的。這個安裝包同時集成了Mercurial的主程序,所以只要裝這一個就夠了。(Mercurial並不需要一個服務器端)

 

安裝完成以後,打開Windows explorer, 在任意位置右擊, 即可看到如下所示的TortoiseHg菜單:

image

 

這裏需要先設置一下用戶信息,因爲Mercurial提交的時候需要知道用戶名以便記錄歷史,所以必須首先配置用戶名. 在上圖菜單中點擊Global Settings, 在彈出選項窗中的Commit子頁中:

image

其中用戶名的格式一般爲"姓名<郵箱>" . 寫完以後保存即可.

 

Clone命令用於從其它位置複製一個數據倉庫,而Create repository here當然就是在當前文件夾創建倉庫了,這裏我們先創建一個倉庫。

或者也可以不使用TortoiseHg的圖形界面,直接用Mercurial命令創建。

Windows7有一個隱藏的右鍵菜單, 當住shift不放點右鍵時, 會發現右鍵菜單多了幾項,其中就有一個是open command here, 這會打開一個cmd命令窗,路徑就是當前文件夾,直接輸入命令hg init, 即可完成數據倉庫的創建。

(以前我也不喜歡用命令,但是使用Mercurial以後,我發現其實用命令並不麻煩,很多時候比TortoiseHg來得還要舒服一些)

image

 

創建數據倉庫以後,再次右擊, 會發現首先在一級右鍵菜單上增加了Hg Commit選項,而子項中則出現了一大排可用命令。這些暫時不用去理它。

隨便新建一個文本文件,點擊hg commit,輸入一點註釋(Mercurial強制要求每次commit必須寫註釋),點擊提交即可。

image

注意左側的文件列表, 必須先打上勾。因爲是向Mercurial新增文件,所以必須先執行add命令, 然後才能commit,體現在這個圖形界面上,就是先勾上左邊,再點commit。

如果使用命令,則分別輸入:

hg add

hg commit –m “some comment here”

第一行hg add會將所有新增的文件標記爲需要Mercurial進行追蹤管理,第二句則是向數據倉庫提交修改。

 

這裏需要注意的是Update命令。Mercurial的Update與SVN在實際效果上差異巨大。Update是用於使工作目錄與本地數據倉庫之間保持一致。所以,如果你是單人項目,總是在工作目錄提交修改的話,它們肯定是完全一致的,Update命令將永遠不必執行。(這大約也是爲什麼TortoiseHg把Update命令作爲二級命令而不像Commit那樣是一級菜單命令) 那麼什麼時候需要Update?先看一下push和pull。

 

假定我們剛纔創建的倉庫位於D:\repo1, 現在執行命令hg clone d:\repo1 d:\repo2, 或者在tortoisehg上點擊clone執行相應操作(圖形界面不再一一截圖,很簡單的操作),這樣就創建了一個新的倉庫repo2, 它與repo1是完全相同的。現在向repo1提交另外一些修改,顯而易見的,repo2仍然停留在clone時的狀態,repo1的最新修改repo2並不知道。 如果現在希望repo2也能更新到repo1的最新狀態, 則有兩種操作方式:

1. Push。 Push顧名思義,是推送的意思,就是從repo1中推送數據到repo2, repo2 不需要做任何動作。在repo1目錄下執行命令hg push d:\repo2。 或者點擊tortoisehg的Syncronize, 在同步窗口中點擊push命令:

image

(這種操作我實在覺得還是命令方便一些。。。)

其中,push命令後面的路徑並不是必須的。每個數據倉庫可以有一個默認的遠程倉庫,如果在repo1中設置了默認遠程倉庫爲repo2, 則只需要執行hg push 就可以了。當執行clone命令時,會自動把來源倉庫設爲默認遠程倉庫,所以在repo2中可以直接執行hg push或hg pull, 會自動到repo1中同步數據。

因爲repo1並不知道repo2的存在, 所以如果需要手動設置默認遠程倉庫,如下這樣操作:

點擊右鍵—>TortoiseHg—>Repository settings,

image

點擊Edit file, 如圖所示, 修改default爲需要指定的路徑即可.

修改完成以後,即可直接執行hg push 而不用寫成hg push d:\repo2了.

2. Pull. Pull是拉取的意思, 即被更新的倉庫主動從遠程倉庫拉取數據. 在本例中, 到repo2的目錄下執行hg pull即可. 因爲repo2是從repo1  clone來的, 所以repo2已經自動把repo1設置默認遠程倉庫, 不需要再寫hg pull d:\repo1了.

 

所以,無論是從repo1端push, 還是從repo2端pull, 都可以達到更新repo2數據倉庫的目的.

 

然而需要注意的是, 無論是push還是pull, 都只更新數據倉庫, 而不更新工作目錄.

 

記住這一點非常重要, 否則可能經常會迷惑爲什麼與預期不符. push或pull之後, repo2的數據倉庫與工作目錄已經不符, 這時就需要在repo2目錄下執行hg update命令, 即可將工作目錄更新到與數據倉庫一致.

 

當像SVN那樣使用遠程服務器作爲主機時, 每次Pull後可以肯定是要執行update的, 這樣兩次操作顯然帶來不便, 在TortoiseHg中, 已經集成了這樣的命令, 首先右鍵—>TortoiseHg—>Syncronize, 打開同步窗口,

image

點擊Post Pull, 在彈出的小窗口中選擇Update, 這樣每次pull之後就會立即執行update了.

或者在項目的根目錄下寫一個批處理文件, 包括以下兩行即可:

hg pull

hg update

以後每次需要獲取更新時, 雙擊一下這個批處理即可, 我覺得還是命令方便……

 

以上簡單羅列了Mercurial的基本用法, 對於查詢歷史修改等操作, TortoiseHg的菜單已經非常簡單, 與SVN也沒有什麼差別, 自行點擊看一下即可.

 

關於在兩臺電腦之間傳遞數據,Mercurial自帶了一個簡單的Serve命令,例如在d:\repo1目錄下執行命令hg server, 會立即啓動一個默認在8000端口監聽的服務進程,這個命令會返回一個url地址,另一臺電腦可以用hg clone <url> local-path 的形式複製本機的repo1倉庫,但是這個serve命令顯然只是一個非常簡單的臨時途徑,如果要配置一臺作爲服務器的中央倉庫,當然就不能僅僅使用serve命令了,而是應該使用IIS或其它web server,下一篇就介紹如何在IIS上架設一個Mercurial的Web Server,請參閱 分佈式版本控制系統Mercurial(二):web server的架設

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