用強大且靈活的Mercurial管理源代碼
對于軟件開發項目,管理源代碼的重要性只略低于編寫代碼的重要性。UNIX 和Linux系統提供許多種版本控制系統 (VCS) 包,每個包采用略有不同的方法解決這個問題。本文主要討論 Mercurial 源代碼管理系統(常常簡稱為 hg)。Mercurial 提供一個強大、現代且輕量的源代碼控制解決方案,讓開發人員可以輕松地更改和調試軟件項目,同時維護一個穩定的中心源代碼存儲庫,所有項目成員都可以依賴這個存儲庫。
UNIX 和 Linux 系統上的源代碼管理
識別和跟蹤多位開發人員所做的更改并把它們合并在最新的單一代碼庫中,這樣就能夠實現協作性的多開發人員項目。VCS 軟件也稱為修訂控制系統 (RCS) 或源代碼管理 (SCM) 系統,它們讓多個用戶可以提交對相同文件或項目的更改,而且保證一個開發人員的更改不會意外地覆蓋另一個開發人員的修改。
Linux® 和 UNIX® 系統上有許多 VCS 軟件,從 RCS 和 Concurrent Versions System (CVS) 等老式系統直到 Arch、Bazaar、Git、Subversion 和 Mercurial 等現代系統。與 Git 一樣,Mercurial 最初是作為替代商業源代碼管理系統 BitKeeper 的開放源碼系統出現的,BitKeeper 過去用于維護和管理 Linux 內核的源代碼。在此之后,Mercurial 發展成為流行的 VCS 系統,許多開放源碼和商業項目都使用它。使用 Mercurial 的項目包括 Mozilla、IcedTea 和 MoinMoin wiki。
VCS 系統一般把每個可以進行更改和跟蹤的源代碼集合稱為存儲庫。開發人員如何與存儲庫交互是傳統 VCS 系統(比如 CVS 和 Subversion,稱為集中式 VCS 系統)與更靈活的 VCS 系統(比如 Mercurial 和 Git,稱為分布式 VCS 系統)之間的關鍵差異。開發人員使用客戶機/服務器模型與集中式 VCS 系統交互,對本地源代碼拷貝的更改只能推回到中心存儲庫中。開發人員使用對等模型與分布式 VCS 系統交互,中心存儲庫的任何拷貝本身都是一個存儲庫,可以向它們提交更改,其他任何拷貝可以共享其中的更改。分布式 VCS 系統實際上沒有中心主存儲庫的概念,但是差不多總是通過策略定義一個主存儲庫,所以有一個存儲庫負責構建、測試和維護軟件的主版本。
為什么要使用 Mercurial?
Mercurial 是一個小型但強大的分布式 VCS 系統,它很容易掌握,同時仍然提供 VCS 高級用戶可能需要(或希望)使用的高級命令。由于 Mercurial 的分布式性質,很容易在本地操作項目、通過本地提交跟蹤并管理自己的更改以及在需要時把這些更改推到遠程存儲庫。
在現代的分布式 VCS 系統中,最接近于 Mercurial 的 VCS 系統是 Git。Mercurial 和 Git 之間的一些差異如下:
●多種內置的撤消操作:Mercurial 的 revert、backout 和 rollback 命令可以簡便地返回到特定文件的以前版本或以前的已提交更改集。Git 只提供一個內置的 revert 命令,而且語法非常復雜。
●內置的 web 服務器:Mercurial 提供一個簡單的集成的 web 服務器,很容易快速地駐留存儲庫,讓其他用戶可以從中獲取更改。推操作需要忽略安全性或支持 Secure Sockets Layer (SSL) 的更復雜的設置。
●在復制/移動操作期間保存歷史:Mercurial 的 copy 和 move 命令都保存完整的歷史信息,而 Git 在這兩種情況下不保存歷史。
●分支:Mercurial 自動地共享所有分支,而 Git 要求每個存儲庫設置自己的分支(在本地創建它們或者把它們映射到遠程存儲庫中的特定分支)。
●全局和本地標簽:Mercurial 支持在存儲庫之間共享的全局標簽,可以在沒有分支的情況下方便地共享代碼開發中特定點的相關信息。
●Windows 平臺上的原生支持:Mercurial 是用 Python 編寫的,而 Microsoft® Windows® 系統支持 Python。因此,可以以 Windows 可執行程序的形式使用 Mercurial(見 參考資料)。Windows 上的 Git 比較復雜,可以選用 msysGit、在 Cygwin 下使用標準的 Git 或者使用基于 web 的托管系統或存儲庫。
●自動的存儲庫收縮:Git 要求您顯式地對存儲庫進行收縮和垃圾收集,而 Mercurial 自動地執行功能相當的操作。但是,對于相同的代碼庫,Mercurial 存儲庫往往比 Git 存儲庫大。
Mercurial 和 Git 的支持者還希望討論這兩個 VCS 系統的命令集的學習難度、優點和易用性。由于篇幅的限制,這里不討論這些方面,但是在網上搜索這個主題會找到許多有意思的資料。
創建并使用 Mercurial 存儲庫
Mercurial 提供兩種為項目源代碼創建本地存儲庫的基本方法:顯式地創建存儲庫或者克隆現有的遠程存儲庫:
要想創建本地存儲庫,應該使用 hg init [REPO-NAME] 命令。如果在執行此命令時提供存儲庫名稱,就會在指定的位置為此存儲庫創建目錄。如果不提供存儲庫名稱,就會把當前的工作目錄轉換為存儲庫。在為現有的代碼庫創建 Mercurial 存儲庫時,后一種做法很方便。
要想克隆現有的存儲庫,應該使用 hg clone REPO-NAME [LOCALNAME] 命令。Mercurial 支持使用 Hypertext Transfer Protocol (HTTP) 和 Secure Shell (SSH) 協議訪問遠程存儲庫。清單 1 給出一個 hg 命令示例和通過 SSH 克隆存儲庫時產生的輸出。
清單 1. 通過 SSH 克隆 Mercurial 存儲庫
$ hg clone ssh://codeserver//home/wvh/src/pop3check wvh@codeserver's password: destination directory: pop3check requesting all changes adding changesets adding manifests adding file changes added 1 changesets with 12 changes to 12 files updating to branch default 12 files updated, 0 files merged, 0 files removed, 0 files unresolved remote: 1 changesets found
注意:要想使用 HTTP 協議訪問 Mercurial 存儲庫,那么必須在此存儲庫中啟動 Mercurial 的內部 web 服務器 (hg serve -d),或者使用 Mercurial 的 hgweb.cgi 腳本把 Mercurial 與現有的 web 服務器(比如 Apache)集成起來。在通過 HTTP 克隆存儲庫時,常常要指定本地存儲庫的名稱。
創建或克隆存儲庫并讓此存儲庫成為工作目錄之后,就可以開始使用其中包含的代碼、添加新文件等等。#p#
在 Mercurial 中獲取幫助
Mercurial 的主要命令是 hg,它支持與其他 VCS 系統相似的一套子命令。執行不帶參數的 hg 命令就可以看到最常用的命令的列表,輸出與 清單 2 相似。
清單 2. Mercurial 提供的基本命令
Mercurial Distributed SCM basic commands: add add the specified files on the next commit annotate show changeset information by line for each file 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 forget forget the specified files on the next commit init create a new repository in the given directory log show revision history of entire repository or files merge merge working directory with another revision pull pull changes from the specified source push push changes to the specified destination remove remove the specified files on the next commit serve export the repository via HTTP status show changed files in the working directory summary summarize working directory state update update working directory use "hg help" for the full list of commands or "hg -v" for details
這個簡短的列表只顯示基本的 Mercurial 命令。執行 hg help 命令可以獲得完整的列表。
提示:執行 hg help COMMAND 命令,把 COMMAND 替換為任何有效的 Mercurial 命令,就可以獲得任何 Mercurial 命令的詳細幫助。
檢查存儲庫狀態
簽入 (check in)更改是任何 VCS 系統中最常見的操作。可以使用 hg status 命令查看對存儲庫中的文件所有未完成的更改。例如,在創建新文件或修改現有文件之后會看到與 清單 3 相似的輸出。
清單 3. Mercurial 的狀態輸出
$ hg status M Makefile ? hgrc.example
在這里,Makefile 文件是已經修改過的現有文件(由行開頭的字母 M 表示),而 hgrc.example 文件是還沒有跟蹤的新文件(由行開頭的問號 ? 表示)。
在存儲庫中添加文件
要想把 hgrc.example 文件添加到存儲庫跟蹤的文件列表中,應該使用 hg add 命令。作為參數顯式地指定一個或多個文件名,就會把這些文件添加到存儲庫跟蹤的文件列表中。如果不指定任何文件,就會把所有新文件添加到存儲庫中,見 清單 4。
清單 4. 在存儲庫中添加文件
$ hg add adding hgrc.example
提示:要想自動地添加所有新文件并且把已經刪除的所有文件標為永久刪除,可以使用 Mercurial 的 hg addremove 命令。
檢查存儲庫的狀態,會看到已經添加了新文件(由行開頭的字母 A 表示),見 清單 5。
清單 5. 更改之后的存儲庫狀態
$ hg status M Makefile A hgrc.example
提交更改
簽入更改是任何 VCS 系統中最常見的操作。更改代碼并測試之后,就可以把這些更改提交到本地存儲庫了。
在第一次提交更改之前
如果這是您的第一個 Mercurial 項目,那么必須提供一些基本信息,讓 Mercurial 能夠識別提交這些更改的用戶。如果不這么做,在嘗試提交更改時會看到包含 abort: no username supplied... 的消息,更改不會提交。
添加用戶信息的方法是在自己的主目錄中創建文件 .hgrc。這個文件是您的個人 Mercurial 配置文件。至少需要在此文件中添加 清單 6所示的基本用戶信息。
清單 6. 用戶的 .hgrc 文件中必需的信息
[ui] username = Firstname Lastname
把 Firstname 和 Lastname 替換為您的名字和姓氏;把 user@domain.tld 替換為您的電子郵件地址;保存修改后的文件。
在 Linux 和 UNIX 系統上的 /etc/mercurial/hgrc 文件以及 Microsoft Windows 系統上 Mercurial 安裝目錄中的 Mercurial.ini 文件中,可以設置應用于所有用戶的默認 Mercurial 配置值(不應該包含針對特定用戶的信息)。
標準的提交過程
創建或檢查 ~/.hgrc 文件之后,可以使用 hg commit 命令提交更改,可以指定希望提交的文件;如果不提供參數,就會提交所有未提交的更改,見以下示例:
$ hg commit Makefile hgrc.example committed changeset 1:3d7faeb12722
如示例輸出所示,Mercurial 把與一次提交相關聯的所有更改稱為更改集。
當提交更改時,Mercurial 啟動默認編輯器,讓您能夠添加提交消息。要想避免啟動默認編輯器,可以在命令行上使用 -m "Message.." 選項指定提交消息。要想使用另一種編輯器,可以在 ~/.hgrc 文件的 [ui] 部分中添加一個 editor 條目,在 editor 關鍵字后面加上希望使用的編輯器的名稱和相關聯的命令行選項。例如,我通過添加條目使用非窗口模式的 emacs 作為默認編輯器,我的 ~/.hgrc 文件如 清單 7 所示。
清單 7. 用戶的 .hgrc 文件中的進一步定制
[ui] username = William von Hagen editor = emacs -nw
提示:要想讓 Mercurial 提供盡可能多的活動信息,可以在 Mercurial 配置文件的 [ui] 部分中添加 verbose = True 條目。
把更改推到遠程存儲庫
如果使用一個遠程存儲庫的克隆,在把更改提交到本地存儲庫之后,可能希望把這些更改推到遠程存儲庫。這要使用 Mercurial 的 hg push 命令,見 清單 8。
清單 8. 通過 SSH 推更改
$ hg push wvh@codeserver's password: pushing to ssh://codeserver//home/wvh/src/pop3check searching for changes 1 changesets found remote: adding changesets remote: adding manifests remote: adding file changes remote: added 1 changesets with 2 changes to 2 files
從遠程存儲庫獲取更改
如果您使用一個遠程存儲庫的克隆,而其他用戶也使用這個存儲庫,您可能希望獲取他們已經完成并推到此存儲庫的更改。這要使用 Mercurial 的 hg pull 命令,見 清單 9。
清單 9. 通過 SSH 獲取更改
$ hg pull wvh@codeserver's password: pulling from ssh://codeserver//home/wvh/src/pop3check searching for changes adding changesets adding manifests adding file changes added 1 changesets with 0 changes to 0 files (run 'hg update' to get a working copy) remote: 1 changesets found
正如這個命令的輸出所示,這個命令只獲取遠程更改的相關信息 — 必須運行 hg update 命令顯示本地存儲庫中的相關更改。這個命令檢查更新存儲庫的方式,見 清單 10。
清單 10. 更新自己的存儲庫以顯示更改
$ hg update 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
在 Mercurial 中撤消更改
Mercurial 提供下面的內置命令,它們可以輕松地撤消已提交的更改:
hg backout CHANGESET:撤消特定的更改集并創建撤消此更改集的更改集。除非在執行此命令時指定 --merge 選項,否則必須把這個更改集合并到自己的當前修訂中,以便推到遠程存儲庫。
hg revert:如果指定一個或多個文件的名稱,就返回到它們的以前版本;如果指定 --all 命令行選項,就返回到所有文件的以前版本。
hg rollback:撤消最后一個 Mercurial 事務,通常是 commit、對遠程存儲庫的 pull 或 push。只能撤消一個事務。
結束語
Mercurial 和其他分布式源代碼管理系統是未來的潮流。Mercurial 是開放源碼軟件,有針對 Linux、UNIX、Microsoft Windows 和 Mac OS® X 預先編譯的 Mercurial 版本。本文主要討論了如何使用 Mercurial 執行一些常見的 VCS 任務,說明了使用 Mercurial 是多么容易。Mercurial 還提供許多更高級的命令和配置選項,幫助您管理源代碼和定制與 Mercurial 的交互。
【編輯推薦】