精品伊人久久大香线蕉,开心久久婷婷综合中文字幕,杏田冲梨,人妻无码aⅴ不卡中文字幕

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Mercurial - 分布式版本控制系統
 






級別: 初級

運 國蓮 (yunguol@cn.ibm.com), 軟件工程師, IBM
李 振剛 (lizg@cn.ibm.com), 軟件工程師, IBM

2008 年 9 月 04 日

是一個輕量級的分布式版本控制系統,它以方便的控制、極強的擴展性贏得了眾多開放源代碼項目的青睞。本文從版本控制系統中的基本概念、操作和擴展性等方面,有側重的介紹了 Mercurial。此外本文列出了幾個其他常用的分布式版本控制系統,并和 Mercurial 作了簡單的比較。通過閱讀本文,讀者可以了解基礎的Mercurial操作,進而熟悉這個備受青睞的工具。

Mercurial 簡介

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

  • 更輕松的管理。傳統的版本控制系統使用集中式的 repository,一些和 repository相關的管理就只能由管理員一個人進行。由于采用了分布式的模型,Mercurial 中就沒有這樣的困擾,每個用戶管理自己的 repository,管理員只需協調同步這些repository。
  • 更健壯的系統。分布式系統比集中式的單服務器系統更健壯,單服務器系統一旦服務器出現問題整個系統就不能運行了,分布式系統通常不會因為一兩個節點而受到影響。
  • 對網絡的依賴性更低。由于同步可以放在任意時刻進行,Mercurial 甚至可以離線進行管理,只需在有網絡連接時同步。




回頁首


從 repository 開始

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

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

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


圖 1. 工作模式的演示





回頁首


Mercurial 里的元素

Revision

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

Changeset

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

	changeset:   207:58e4906e69e3                                    

冒號前面的數字代表版本號,它用來標識本地 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選項來獲得歷史信息中的一切細節。





回頁首


動手操作起來

以下是一些實際使用 Mercurial 中常用的例子。Mercurial 的原意是元素周期表當中的汞元素,但是 Mercurial 這樣的單詞顯然不太適合日常使用。事實上 Mercurial 的命令取了元素周期表當中汞元素的化學符號:hg,所有的 Mercurial 命令都以 hg 開始。

    $ hg command [options]                                    

其中 command 是 Mercurial 的命令。每個命令的具體的命令行選項可以使用:

    $ hg help command                                    

來獲得。

克隆一個 repository

我們使用 clone 命令克隆一個 repository,它生成一個完整的 repository 復本,這樣我們就有一個本地私有的 repository 來工作。

例如:

     $ hg clone  http://foo.com/hg/project1                                    

如果所有都沒問題,clone 命令輸出:

    destination directory: project1                                    requesting all changes                                    adding changesets                                    adding manifests                                    adding file changes                                    added 127 changesets with 448 changes to 143 files                                    139 files updated, 0 files merged, 0 files removed, 0 files 	unresolved                                    

此時,我們應該在當前目錄下發現一個目錄叫 project1,目錄下的文件是我們剛克隆的 repository 的精確復本。在 Mercurial 中,每一個 repository 是自包含的。當你克隆一個repository 后,新 repository 變成克隆時它的精確復本,但是后續的兩個 repository 當中任一方改變都不會在對方顯示,除非用戶使用 pull 或 push 命令明確地傳遞改變,這個將在后面介紹。

另外,每個用戶可以使用 init 命令將本地的一個目錄初始化為一個 Mercurial 的 repository,只需要在那個目錄下運行:

   $ hg init                                    

如果設置好了同步共享的發布方式,其他用戶就可以來克隆該用戶的 repository 了。

發布你的改動

進入工作目錄,使用我們喜歡的編輯軟件修改,例如我們要修改 main.py 讓它增加打印一行輸出:

def main():                                    print "I'm in the a function."                                    print "Great joy of using Mercurial!"  #新加的一行                                    if __name__ == "__main__":                                    sys.exit(main())                                    

完成之后退出編輯器,任務完成。有了剛才的修改我們就可以創建一個changeset。

在創建 changeset 之前如果想確認一下哪些文件被改動了,可以使用 status 命令。

$ hg status                                    M main.py                                    

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

diff -r a58db6f0e482 main.py                                    --- a/main.py   Thu Nov 29 13:38:38 2007 +0800                                    +++ b/main.py   Thu Nov 29 13:46:10 2007 +0800                                    @@ -1,5 +1,6 @@ def main():                                    def main():                                    print "I'm in the a function."                                    +    print "Great joy of using Mercurial!" #新加的一行                                    if __name__ == "__main__":                                    sys.exit(main())                                    

diff 命令的默認輸出是通用的補丁格式,易于在各種系統之間交換和討論。

創建一個 changeset 后我們就可以用 commit 命令提交了。

$ hg commit                                    

這個命令把我們帶到一個編輯器內,缺省的編輯器是 vi,同時給我們展示了幾行如下的文字:

HG: user: Guolian Yun <yunguol@cn.ibm.com>                                    HG: changed main.py                                    

第一行是空的,接下來的幾行表明哪些文件將進入本 changeset。為了改變 changeset,我們必須描述它的原因,這通常稱為 changeset注釋。讓我們輸入一些:

I’m using Mercurial!                                    HG: user: Guolian Yun <yunguol@cn.ibm.com>                                    HG: changed main.py                                    

接著,保存并退出編輯器,如果一切正常,commit 命令將沒有任何提示地輸出。

讓我們看看status命令現在告訴我們什么?

$ hg status                                    

什么也沒有!我們的改動已經提交到changeset里了,那里沒有修改的文件需要提交的。Repository 中內容和當前工作目錄的內容一致了。

現在可以檢查以下最新的改動是不是包含剛才所添加的 changeset 注釋,使用 tip 命令就可以顯示了:

$ hg tip:                                    changeset:   2:2874393e3d9c                                    tag:         tip                                    user:        Guolian Yun <yunguol@cn.ibm.com>                                    date:        Thu Nov 29 10:10:39 2007 +0800                                    summary:     I'm using Mercurial!                                    

目前新的 changeset 只存在本地 repository 中,如果想和其它 repository 分享改動,我們需要使用 push。

$ hg push project2                                    

project2 為你想要 push 的目標 repository 的名字。

引入他人的改動

想要得到所有在別的 repository中而在本地repository中沒有的改動,可以采用 pull命令。

$ hg pull project3                                    

project3為我們想要得到更新的目標repository的名字。

在 Pull 后,缺省情況下Mercurial不更新工作目錄。這意味著雖然repository現在有changeset,但在工作目錄中的 main.py 文件仍然是 pull 之前老的內容。

如果只想從hg clone的 repository 中更新當前 revision 到最新版,可以直接采用:

$ hg pull -u                                    

Repository 之間的同步

上文當中的 push 和 pull 的操作,是處于不同位置的 repository 之間的同步。之前給出的兩個例子是本地目錄 repository 之間的同步。Mercurial 還支持以下形式的 repository 之間的同步:

file://local/filesystem/path                                    http://[user@]host[:port]/[path]                                    https://[user@]host[:port]/[path]                                    ssh://[user@]host[:port]/[path]                                    

其中 file 協議和本地目錄相同。在 http 和 https 協議上使用push命令,需要在遠端的服務器上啟用相關的屬性。ssh協議是眾多系統中支持的shell。

標準的 Mercurial 發行包中還附帶一個 Python CGI 腳本 hgweb.cgi, 可以用來參考搭建一個多用戶可以集中式的同步改動的界面,如下圖所示:


圖 2. 界面





回頁首


擴展 Mercurial

Mercurial 系統中提供一種擴展機制來添加新的命令。通過擴展添加的命令可以在現有的Mercurial 系統的基礎上添加新的功能,這些命令跟隨 hg 后被調用時就像原生的命令一樣。本文介紹兩個常用的Mercurial擴展:Patchbomb和Mq。

Patchbomb

Patchbomb是一個在Mercurial系統中利用發送郵件的方式來交換changeset的擴展。Patchbomb添加了一個新的email命令。通過調用 hg email 命令,changeset 提交時的信息的第一行將作為郵件的主題,信件的正文包括完整的 changese t提交信息,以 patch 的形式發布出來的 changeset 完整補丁。如果一次發送的是多個changeset,那么Patchbomb會提示輸入本次 changeset 集的總提示信息,這部分信息將作為第一封信,信件主題以[PATCH 0 of N]開頭,changeset 則會以[PATCH i of N]將的主題開頭發出,其中i是 changeset在本地 repository 當中的順序。多changeset 系列郵件中,每封信會在郵件頭中包含合適的回復信息,這樣在郵件客戶端可以清晰的顯示出系列 changeset 之間的層次關系。


圖 3. 層次關系

Patchbomb 支持使用本地系統中的 sendmail 程序來發送郵件,同時支持使用 SMTP 郵件服務器。用戶如果長期固定為某個項目工作,還可以將郵件的收件地址和發信地址提供給Patchbomb,免去每次手動輸入的麻煩。這一切都可以在 Mercurial 統一的 .hgrc 當中設置,以下是一個完整的例子。

[extensions]                                    hgext.patchbomb =                                    [email]                                    method = smtp # 還可以在這里指定/usr/sbin/sendmail                                    from = Zhengang Li <lizg@cn.ibm.com>                                    to = groupmail@foo.com                                    [smtp]                                    host = smtp.foo.com                                    

Patchbomb 作者為Bryan O’Sullivan,該擴展現在隨同 Mercurial 系統一起發布,用戶不需額外下載安裝,只需如上例中一樣啟用即可。

Mq

Mq 擴展的全名是Mercurial Queues,顧名思義該擴展將用戶本地的多個 changeset 排列到隊列中。原先分布式版本控制系統中,changeset 一旦提交并不能修改。有了 Mq 擴展之后,用戶可以將本地的任意數量的 changeset 存放至一個本地的隊列當中,對這些 changeset 用戶除了可以使用傳統的 changeset 上的任何命令之外,還可以修改changeset,包括提交信息和版本補丁的改動。

啟用 Mq 擴展的辦法同其他擴展一樣,在 .hgrc 當中添加如下信息:

[extensions]                                    hgext.mq=                                    

Mq的命令是一系列以字母q打頭的命令,qinit, qnew, qrefresh, qdiff, qpop和qpush等。Qinit 用來初始化用來存放補丁隊列的目錄,qnew創建一個新的補丁changeset,qrefresh 將改動刷新到當前的補丁當中去,qdiff 將當前的補丁打印到屏幕,qpop qpush 用來移動當前存放在隊列頂部的補丁。完整的 q 系列命令可以從 hg help給出的列表中獲得。

Mq中所有的 changeset 補丁存放在項目頂層目錄的.hg/patches下面,用戶可以手動修改這些補丁當中的提交信息。Changeset 補丁的順序存放在.hg/patches/series文件當中,同樣的,用戶可以修改這些補丁的順序。

Mq的作者是Chris Mason,該擴展現在隨同 Mercurial 系統一起發布,用戶不需額外下載安裝。

如果現有的擴展不能滿足用戶的要求,編寫自己的擴展也不困難。Mercurial 使用 Python編寫,編寫一個新的擴展相當于在 Mercurial 系統的 hgext 包當中編寫一個新的模塊。具體的擴展實現還有些約定的規則,用戶可以參考 Mercurial 所提供的文檔。





回頁首


其他分布式版本控制系統

分布式版本控制系統領域還有一些其他的系統,如GNU arch,monotone,Bazaar,git,darcs。

各類系統在各在一定的領域內長處,如GNU arch在GNU Savannah主機上應用,Bazaar 主要用于 Ubuntu Linux 系統的開發當中,git 源于Linux kernel 的開發,現在在多處和內核相關的項目中使用。他們大多數提供友好的Web界面和多種版本同步協議的支持。Git 和Gnu arch 由 C 和 shell 腳本語言編寫實現,monotone 由C++語言實現,darcs 由 Haskell語言實現,Bazaar 和本文介紹的 Mercurial 由 Python 語言實現。從開放和擴展性方面來說,類似 Python 這樣的腳本語言的更易于用戶編寫自己的擴展。

在眾多的分布式版本控制系統中,Mercurial 是最年輕的,它的第一個版本發布于2005年4月。Mercurial 吸收了眾多前輩的特性,被眾多的項目采用。




本站僅提供存儲服務,所有內容均由用戶發布,如發現有害或侵權內容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
mac上使用hg命令
Solidot | Python選擇Mercurial Hg版本控制系統
為什么選擇GIT--GIT與其他SCM工具的比較
分布式版本控制(一)
如何從Windows命令行中訪問SSH發布的Hg倉庫?
你所需要知道的一些git 的使用命令:克隆
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯系客服!

聯系客服

主站蜘蛛池模板: 收藏| 昭平县| 丹寨县| 土默特右旗| 大厂| 铁岭县| 罗平县| 柳江县| 额尔古纳市| 阳信县| 碌曲县| 阜阳市| 游戏| 四子王旗| 鄢陵县| 嘉峪关市| 大名县| 闽侯县| 西宁市| 香港 | 祥云县| 安平县| 台前县| 金溪县| 陵水| 扎赉特旗| 台山市| 锦屏县| 山阴县| 泰州市| 孝感市| 通海县| 古丈县| 璧山县| 夏河县| 榕江县| 普格县| 普兰县| 富平县| 克拉玛依市| 巴林左旗|