分佈式版本控制系統

分佈式版本控制系統

——Mercurial

一、 分佈式版本控制系統介紹

(1)CVCSDVCS   

Centralized Version Control Systems集中式版本控制系統

Distributed Version Control Systems 分佈式版本控制系統

分佈式版本控制 (DVCS) 是一種不需要中心服務器的管理文件版本的方法,但是它也可以使用中心服務器。更改可以被合併到 DVCS 的任何其他用戶的系統中,因此可以實現非常靈活的工作流。DVCS 的兩個主要優點是:它比集中的版本控制更靈活,因爲它除了支持傳統的(集中式)工作流,還支持其他各種工作流;它比集中式服務器快得多,因爲大多數操作在客戶機本地進行,而不需要網絡操作。

在 DVCS 和集中式版本控制系統之間有三個關鍵差異。第一個差異是,DVCS 通過本地提交支持離線工作,這是由 DVCS 的操作方式決定的。這與集中式版本控制完全不同,集中式版本控制要求通過到中心服務器的連接執行所有操作。這種靈活性讓開發人員在飛機上也能夠像在辦公室中一樣輕鬆地工作,可以一次又一次地進行提交。 

第二個差異是 DVCS 比集中式系統更靈活,因爲 DVCS 支持許多不同類型的工作流,從傳統的集中式工作流到純粹的特殊工作流,再到特殊工作流和集中式工作流的組合。這種靈活性允許通過電子郵件、對等網絡和開發團隊喜歡的任何方式進行開發。 

第三個差異是 DVCS 比集中式版本控制系統快得多,因爲大多數操作在客戶機上進行,速度非常快。另外,在需要進行推(push )操作(與另一個節點通信)時,速度也更快,因爲兩個客戶機機器上都有完整的元數據。速度差異相當顯著,根據使用本地存儲庫還是網絡存儲庫,DVCS 比 Subversion 快大約 3-10 倍。

(2)分佈式版本控制工作流

Partner 工作流。按照 Partner 工作流,一個開發人員啓動一個項目,然後進行分支。然後,在不同開發人員工作的分支之間來回合併更改。

通過本地提交使用集中式服務器。在這種工作流中,開發人員的工作方式與使用集中式 Subversion 存儲庫時非常相似,但是他們進行本地提交,然後把最終更改推到集中式服務器。這種工作流有許多變體,包括與 Partner 工作流結合使用。重要的是,可以採用許多種工作方式,通過使用 DVCS,可以靈活地選擇最適合自己的工作方式。

二、 Mercurial - 分佈式版本控制系統

(1) Mercurial 簡介

Mercurial 是一種輕量級分佈式版本控制系統,採用 Python 語言實現,易於學習和使用,擴展性強。其是基於 GNU General Public License (GPL) 授權的開源項目。相對於傳統的集中式 Subversion版本控制,具有如下優點:

更輕鬆的管理。傳統的版本控制系統使用集中式的 repository,一些和 repository相關的管理就只能由管理員一個人進行。由於採用了分佈式的模型,Mercurial 中就沒有這樣的困擾,每個用戶管理自己的 repository,管理員只需協調同步這些repository。 

更健壯的系統。分佈式系統比集中式的單服務器系統更健壯,單服務器系統一旦服務器出現問題整個系統就不能運行了,分佈式系統通常不會因爲一兩個節點而受到影響。 

對網絡的依賴性更低。由於同步可以放在任意時刻進行,Mercurial 甚至可以離線進行管理,只需在有網絡連接時同步。

(2) repository倉庫

版本控制系統中的 repository 就像一個倉庫一樣,用來存儲被管理的數據文件,包含數據文件的不同版本。傳統的版本控制系統中,這樣的repository 是集中式的。除了這樣一個集中式的 repository 之外,每個用戶會有一份自己的工作版本拷貝。用戶通過命令同步自己的拷貝和集中式的repository

分佈式版本控制系統中的 repository 則採用的是對等網絡式的方式。傳統集中式的管理中,只有一份 repository,其他的只是工作拷貝,不包含額外的版本。分佈式的管理當中,每個用戶所持有的都是一個真實的 repository,當中存儲有不同的版本信息和維護一個 repository 的必要的輔助元數據。這樣一個對等工作模式當中,用戶通過交換下文即將提到的 changeset 來完成同步。

這樣做的一些優點在於,工作的並行度將大大的提高。每個用戶都可以帶着這樣的repository,從這裏他可以把當前的工作拷貝切換到 repository 裏面存儲的任何一個版本。這個版本可以是之前正在工作的版本,現在需要合併進一些別人的意見,也可以是用戶私有的一個版本,當前正在做很多前瞻性的工作,還沒有能同步給其他用戶使用。也同樣是因爲這樣的模式,每個用戶可以任意把自己的 repository 當中的一個版本交換給其他用戶,而不需要對自己手頭正在工作的版本進行回退。下圖是這樣一個靈活的工作模式的演示。

(3) Mercurial 裏的元素

Revision

在使用 Mercurial 的系統中每個改動隔離在各自的 repository 裏,既避免把不相關的代碼混雜起來, 又便於一個接一個的測試每一部分工作,用戶做的每個改動稱爲一個 revision。一般會有一個所有用戶都可以訪問得到的 repository 保存了項目的“主要”版本,工作repository 是用戶自己做事情的地方,實現新的特性,修改漏洞,重構,實驗等,當完成改變後,你可以 push 到共用的 repository中,即完成了一個 revision

Changeset

一個或多個文件的改變集合在一起形成一個邏輯單元,稱爲 changeset。每一個 changeset由兩部分內容描述,版本號和 changeset 標識,例如:

冒號前面的數字代表版本號,它用來標識本地 changeset。這個版本號只有在用戶的本地repository 中才有意義。冒號後面的那個很長的十六進制串是 changeset標識它是確定changeset的全局唯一標識符在所有包含這個 changese 的 repository 中都相同。多個用戶之間討論changeset,一般使用這個 changeset 標識,而不是上面說的版本號,因爲完全有可能每個用戶的 repository 中同樣的 changeset 版本號不同。

Head

Head 表示 repository 中每個分支最新的 revision,通常在合併幾個分支時會用到這個概念。

Tip

Tip 是最新的一個 changeset 的版本號的一個別名。在命令中任何使用版本號的地方都可以使用 tip 來代替最新的 changeset的版本號。Tip在各個repository中是不同的,同時一個repository 中只有一個 tip

Log

Log 命令按時間順序從近到遠的記錄着在 repository 中發生的每一次事件。可以通過指定-v診斷輸出選項來獲得更多更詳細的歷史信息,或者指定—debug選項來獲得歷史信息中的一切細節。

三、 MercurialWindowsLinux下的安裝和使用

(1) MercurialWindows下的安裝和使用

① 下載TortoiseHg-0.7.6-hg-1.2.1.exe可執行程序,直接安裝即可,也可以從源代碼編譯安裝,具體參看

http://www.selenic.com/mercurial/wiki/index.cgi/WindowsInstall

② 項目負責人創建一個原始版本並做設置

      

③ 創建本地repository

④創建本地repository後的倉庫中的文件(原倉庫中爲空文件夾)

⑤向本地repository添加文件

⑥添加文件後向本地repository提交

提交後本地repository中文件入下所示:

⑦創建一個精確的克隆版本,放到一個其他組員可以訪問到的地方,供其他組員分享使用

 

⑧其他組員訪問公共站點進行更新

pullpush的使用,在DVCS host中添加一空的zip文件,在DVCS client1中添加一個空的html文件及bmp文件

和本地自己的repository庫合併

我們從DCVS host repository pull更新得到blank.zip。下面說明push的使用方法

要注意以上兩個參數的設置

⑩其他功能

(2) MercurialLinux下安裝使用(VMware CentOS5.3,VMware採用hostonly方式和宿主機通信

① 下載mercurial-1.2.1.tar.gz源碼 下載地址:http://mercurial.selenic.com/release/

② tar zxvf mercurial-1.2.1.tar.gz 說明陰影部分爲bash shell root用戶所用命令

# cd mercurial-1.2.1

# python setup.py install --force --home=$HOME

設置PYTHONPATH

#vi ~/.bash_profile

在該文件中添加export PYTHONPATH=$PATH:$HOME/root/lib/python 注意橙色部分爲你自己安裝時的路徑

#source ~/.bash_profile

安裝好後

# hg 

Mercurial Distributed SCM

basic commands:

 add        add the specified files on the next commit

 annotate   show changeset information per file line

 clone      make a copy of an existing repository

 commit     commit the specified files or all outstanding changes

 diff       diff repository (or selected files)

 export     dump the header and diffs for one or more changesets

 init       create a new repository in the given directory

 log        show revision history of entire repository or files

 (...)

③ 克隆倉庫

# hg clone http://192.168.0.1:8000 my-hello

requesting all changes

adding changesets

adding manifests

adding file changes

added 5 changesets with 8 changes to 7 files

updating working directory

7 files updated, 0 files merged, 0 files removed, 0 files unresolved

在當前目錄下會有一個my-hello目錄

#cd my-hello

#ls

blank.rar  blank.zip  hello.c  hello.h  helloWorld.txt  readme.txt

出現的就是我們在WindowsDCVS host文件夾中的內容

④ 變更文件

hg clone http://192.168.0.1:8000 my-hello-new-output

ls

anaconda-ks.cfg  Desktop             lab       my-hello-new-output

bin              install.log         lib

C++              install.log.syslog  my-hello

# cd my-hello-new-output

#vi hello.c

 #include <stdio.h>

int main()

{

  printf("Hello,Mercurial!");

  printf("sure am glad I'm using Mercurial!");  /*此行爲添加的*/

  return 0;

}

hg status

M hello.c  /*以 開頭的行意思就是hello.c文件修改過了*/

使用 diff 命令我們可以檢查文件實際的改變:

# hg diff

diff -r 8f09d6982f89 hello.c

--- a/hello.c   Thu Jul 02 20:08:11 2009 +0800

+++ b/hello.c   Thu Jul 02 21:08:21 2009 +0800

@@ -2,5 +2,6 @@

 int main()

 {

   printf("Hello,Mercurial!");

+  printf("sure am glad I'm using Mercurial!");

   return 0;

 }

萬一我們希望放棄我們的變更並重新開始,我們可以用revert命令來恢復到我們沒有更改的狀態。

# hg revert

⑤ 接下來我們要提交我們創建的變更集

# hg commit

HG: Enter commit message.  Lines beginning with 'HG:' are removed.

HG: --

HG: user: [email protected]

HG: branch 'default'

HG: changed hello.c

爲了提交變更集,我們必須描述它的原因,我們加入註釋

我們現在可以爲我們的新工作檢查變更的歷史

# hg log

changeset:   5:0660ed208d40

tag:         tip

user:        [email protected]

date:        Thu Jul 02 21:15:33 2009 +0800

summary:     Express great joy at existence of Mercurial

⑥ 與別的倉庫分享改變

   我們在my-hello-new-output 倉庫中創建了一個變更集。現在我們希望在其它地方擴展那個變化。

   #cd my-hello-share

#hg -q tip

4:8f09d6982f89

#cd ../my-hello-new-output/

#hg -q tip

5:0660ed208d40

the Tip 在各個倉庫中是不同的。讓我們回到 my-hello-share 並在那裏擴展我們的新變更集。要達到這個目的,我們用 pull 命令,這個命令所有在別的倉庫中有而在本倉庫中沒有的 ChangeSet 從別的倉庫 Pull 到本倉庫。

#cd ../my-hello-share

# hg pull ../my-hello-new-output

pulling from ../my-hello-new-output

searching for changes

adding changesets

adding manifests

adding file changes

added 1 changesets with 1 changes to 1 files

(run 'hg update' to get a working copy)

最近一行輸出是重要的。在 Pull 後,缺省情況下 Mercurial 不更新工作目錄。這意味着雖然 Repository 現在有變更集, 但在工作目錄中的 hello.c 文件仍然是Pull 之前老的內容。

我們可以用以下Mercurial的提醒來 Update 這個文件 (也包括所有其它 Pull 時改變的文件)。

#hg update

1 files updated, 0 files merged, 0 files removed, 0 files unresolved

#hg -q tip

5:0660ed208d40

現在my-hello-sharemy-hello-new-output有相同的內容和版本歷史記錄  

⑦ 通過網絡分享改變

   # hg incoming http://192.168.0.1:8000

comparing with http://192.168.0.1:8000

searching for changes

changeset:   7:46bc915ccd2b

parent:      2:1ca713fd149c

user:        leeiee

date:        Thu Jul 02 19:11:08 2009 +0800

summary:     a file include  bmp and html

changeset:   8:ba5a08ead13e

parent:      7:46bc915ccd2b

parent:      3:45394e4035a4

user:        leeiee

date:        Thu Jul 02 19:32:54 2009 +0800

summary:     merge

#hg pull http://192.168.0.1:8000

pulling from http://192.168.0.1:8000

searching for changes

adding changesets

adding manifests

adding file changes

added 7 changesets with 3 changes to 5 files (+1 heads)

(run 'hg heads' to see heads, 'hg merge' to merge)

發佈了55 篇原創文章 · 獲贊 5 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章