Mercurial - 版本控制概览

作者:Joey Bernard

不久前,Linux Journal 上发表了一篇文章,暗示 Git 是源代码版本控制系统的终极方案(“Git—完美版本控制”,作者 Henry Van Styn,2011 年 8 月)。我想挑战这个假设,并向世界宣告,真正完美的版本控制系统就在这里,它的名字是 Mercurial。

如果您没有注意到,那么上一段话我是在开玩笑。我认为版本控制系统就像编辑器。它们各不相同,适合不同的人及其工作习惯。没有一个完美的系统可以统治一切。Git 可能适合某些人,而 RCS 可能更适合其他人。本文介绍了添加到选择范围中的另一个选项。Mercurial 提供了类似于 Git 的一些功能,以及类似于 CVS 或 Subversion 的一些功能。希望在阅读本文后,您将有足够的信息来做出关于什么最适合您的理性选择。

Mercurial 的主要站点包含大量面向最终用户和开发人员的文档。有几个教程可用,它们甚至包括一系列工作流程,涵盖最终用户如何在其开发项目中使用 Mercurial。使用这些工作流程,您可以看到如何将 Mercurial 用作单人开发人员或开发人员团队的一员,或者如何使用像 CVS 这样的中央仓库。这些工作流程是您创建自己的工作流程的绝佳起点。

首先,让我们看看 Mercurial 的组成。Mercurial 仓库由一个工作目录和一个存储库组成。存储库包含仓库的历史记录。每个工作目录都与其自身的存储库副本配对。这意味着 Mercurial 具有分布式系统,非常像 Git。当您提交一系列文件更改时,将创建一个变更集,封装这些更改。每个变更集都获得一个顺序编号,称为修订号。但是,请记住,每个工作目录都获得其自身的存储库副本,因此这些修订号实际上可能不匹配。因此,每个修订版本也获得一个 40 位十六进制全局唯一 ID。

图 1. 在这里您可以看到 Mercurial 仓库被标记以便于查找。

图 2. 右键单击文件并调出属性会为您提供大量 Mercurial 信息。

那么,当两个用户进行并行开发时会发生什么?假设他们从相同的仓库开始,用户一进行的任何已提交的更改都会创建一个新分支,用户二进行的任何已提交的更改也会创建一个新分支。然后,用户一从用户二的仓库中拉取任何更改。这会在用户一的仓库中创建两个分支:一个分支用于用户一的更改,另一个分支用于用户二的更改。然后,用户一需要合并这两个分支,以便合并自上次仓库同步以来的所有更改。用户二需要做同样的事情(拉取和合并)才能同步仓库。更改也可以推送到另一个仓库。

Mercurial 的优势之一是它对扩展的使用。该项目提供了几个扩展,您始终可以继续编写自己的扩展。扩展是用 Python 编写的,所以磨练您的脚本编写技能。您可以通过将它们添加到配置文件的 [extensions] 部分来启用这些扩展。

那么,您实际上如何使用 Mercurial 呢?您可能需要在 .hgrc 文件中设置一些基本配置选项。Mercurial 需要用户名来记录提交。您可以使用以下配置选项在配置文件中设置此选项


[ui]
username = John Doe <john.doe@company.com>

首先要做的是创建您的本地仓库。如果您正在处理来自其他人的副本,您将进行克隆。克隆命令的格式为


hg clone [OPTIONS...] SOURCE [DEST]

source 选项可以采用几种不同的形式。如果您要克隆的仓库在同一台机器上,您可以简单地提供源仓库的文件系统路径。Mercurial 包含一个 Web 服务器,可用于通过 HTTP 提供对仓库的访问。如果您要克隆这样的仓库,该命令将很简单


hg clone http://[user[:pass]@]somemachine.com[:port]/[path][#revision]

您也可以通过 HTTPS 执行此操作。在我的工作中,我们将仓库的备份副本保存在只能通过 SSH 访问的机器上。这很好,因为 Mercurial 非常乐意通过 SSH 进行克隆。您可以使用以下命令执行此操作


hg clone ssh://user@host[:port]/[path][#revision]

您需要在远程计算机上具有有效的登录名,当然。路径是相对于您的主目录的,因此如果您想使用完整路径,您需要以两个正斜杠开头


hg clone ssh://user@host//full/path/to/repo

创建一个新仓库甚至更容易。您所需要做的就是创建一个目录来存放所有要放入仓库的文件。然后,您可以 cd 到该目录并执行以下命令


hg init

此命令创建一个名为 .hg 的子目录,其中包含新仓库的所有存储文件。

更改仓库内容是通过 addremove 命令完成的。还有一个 rename 命令,您可以使用它来更改仓库中文件的名称。您也可以使用该命令在仓库中移动文件。假设您想将文件移动到子目录 dir1。您将执行此操作


hg rename file1.c dir1

您可以使用 status 命令获取文件的当前状态。这将告诉您文件是否已被修改、添加、删除等等。diff 命令显示文件从当前版本到上次提交版本的差异。如果您决定放弃所有这些更改,可以使用 revert 命令将文件重置为上次提交的版本。一旦您对您的编辑感到满意,您可以使用 commit 命令提交任何更改。

在整个仓库的级别上,有很多命令可用。当您完成大量编辑并将所有更改提交到仓库的本地副本后,您可以使用 push 命令将更改发送到另一个仓库。push 命令的目标可以具有上面克隆命令示例中显示的任何形式。如果感兴趣的更改是由远程仓库中的另一个用户进行的,您可以使用 pull 命令来获取它们并将它们放入您的本地仓库。

您可能想在合并这些更改之前检查会发生什么。在推送更改之前,您可以使用 outgoing 命令查看如果实际发出 push 命令会发送哪些变更集。对于拉取,您可以使用 incoming 命令查看如果发出 pull 命令会引入哪些变更集。完成此操作后,这些更改将位于单独的分支中。然后您需要将此分支合并回主分支才能合并更改。

但是,如果您真的没有任何类型的直接网络访问权限怎么办?您可以使用 bundle 命令生成一个包含变更集的压缩文件。然后可以通过电子邮件或 SneakerNet 将其传输到远程仓库。一旦它在那里,您可以使用 unbundle 命令将变更集导入到远程仓库。同样,您可以使用带有 --bundle filename 选项的 incomingoutgoing 命令来检查变更集,并在实际运行真实命令之前查看它们将执行的操作。

正如我之前提到的,Mercurial 包括一个 Web 服务器,可以通过 HTTP 提供对您的仓库的访问。不适合提供对仓库的公共全天候访问,因为它不提供任何类型的用户身份验证。在这些情况下,您将使用真正的 Web 服务器(如 Apache)来提供仓库服务。但是,如果您只是想临时快速启动服务器,或者您只是在本地网络上提供内部访问,并且不需要太担心安全性,这为您提供了非常快速的访问。您只需运行


hg serve [OPTIONS...]

一些更常见的选项包括 -d--daemon。这会将 Mercurial Web 服务器放入后台。

您可能想使用选项 -p--port 设置它正在侦听的端口。默认端口是 8000。您可以从这样的 Web 服务器推送和拉取。如果您想通过 HTTPS 而不是 HTTP 提供服务,您可以使用选项 --certificate 来设置要使用的 SSL 证书文件。

有几个客户端可用于处理 Mercurial 仓库。对于 GNOME 用户,有一个方便的客户端叫做 tortoise。这个客户端真正出色的部分是它与 Nautilus 完美集成。这意味着您可以与您的仓库交互、提交更改、克隆它、与远程仓库同步等等。您还可以在 Nautilus 中获得信息图标,让您立即看到哪些文件已过期、已更改或它们的任何状态。所有工具只需右键单击即可使用。还有一些很棒的独立客户端可用,所以四处看看,看看您喜欢什么。

希望这个介绍能给您一些关于您可以使用 Mercurial 完成什么的想法。现在您没有任何借口不将您的源代码置于版本控制之下了。

加载 Disqus 评论