Home » Misc » Mercurial (Hg) 简易指南
  • 13
  • 06月

Mercurial (Hg) 简易指南

Mercurial 是一种轻量级分布式版本控制系统,采用 Python 语言实现, 易于学习和使用,扩展性强。其是基于 GNU General Public License (GPL) 授权的开源项目。

1   基本概念

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 选项来获得历史信息中的一切细节。

英文说明: Revisions, changesets, heads, and tip

Mercurial groups related changes to multiple files into single atomic changesets, which are revisions of the whole project. These each get a sequential revision number. Because Mercurial allows distributed parallel development, these revision numbers may disagree between users. So Mercurial also assigns each revision a global changeset ID. Changeset IDs are 40-digit hexadecimal numbers, but they can be abbreviated to any unambiguous prefix, like "e38487".

example-repository

Branches and merges in the revision history can occur at any point. Each unmerged branch creates a new head of the revision history. Here, revisions 5 and 6 are heads. Mercurial considers revision 6 to be the tip of the repository, the head with the highest revision number. Revision 4 is a merge changeset, as it has two parent changesets (revisions 2 and 3).

2   基本操作

2.1   安装

Linux
Linux 系统一般会带有命令行版本的 Mercurial, 当然, 也可以安装 TortoiseHg. 另外, 早期的 Mercurial 版本和 TortoiseHg 版本可能会存在一定的差异, 比如Mercurial 2.7.x 版本, 对应使用 TortoiseHg 2.9.x 版本.
Windows
Windows 下直接安装 TortoiseHg 即可, 这是一个功能相当强大的图形客户端.

2.2   配置

第一步, 设置用户名

方法1, 通过 TortoiseHg 工作台来设置, 点击 File 菜单, 选择 Settings 命令, 在弹出的对话框中点击 Commit 标签, 在 Username 这栏填写类似这样的用户名 xxx <xxx@xxx.com>, 然后点击 OK 按钮保存.

方法2, 直接编辑 ~/.hgrc 并添加或更新以下内容:

[ui]
username = xxx <xxx@xxx.com>
verbose = True

第二步, 启用记住密码功能

Windows 下, 打开 TortoiseHg 工作台, 进入 Settings 对话框, 点击 Extensions 标签, 勾选 mercurial_keyring 插件, 点击 OK 按钮保存.

Linux 下, 需要先安装 mercurial_keyring 软件包 (可通过 pip 或者 easy_install 安装), 然后再在 TortoiseHg 中启用插件, 或者编辑 ~/.hgrc 启用:

[extensions]
mercurial_keyring =

注解

本人使用 Slackware 14.1 系统, 桌面环境为 KDE4, 若要使用这个插件, 需要开启 KDE 钱包.

第三步, KDiff3 工具(可选)

Windows 下, TortoiseHg 默认已经安装并启用, 无须设置.

Linux 下, 需要先安装 KDiff3 软件, 然后再启用:

[extensions]
hgext.extdiff =

[extdiff]
cmd.kdiff3 =

[merge-tools]
kdiff3.args = $base $local $other -o $output

2.3   添加仓库

hg init example

2.4   添加并追踪文件(add)

hg add hello.txt

若某个文件添加之后, 想撤消, 可以使用 forget 命令:

hg forgot hello.txt

2.5   遗忘(forget)

对指定文件进行标记, 以便在下一次提交时不再被追踪. 被标记的文件只会在当前分支删 除, 而不是从整个项目历史. 标记后的文件不会从当前工作目录中删除.

hg forgot hello.txt

2.6   查看状态(status)

查看当前工作目录文件的变更状态:

hg status

2.7   提交变更集(commit)

hg commit

警告

一定要填写良好的提交信息.

提交时可以提交所有的变更, 也可以只提交某个或某几个文件的变更.

2.8   查看差异(diff)

查看当前工作目录和最后一次版本的差异:

hg diff

2.9   复制和移动(copy, move)

hg copy hello.txt hello2.txt
hg mv hello.txt hello1.txt

技巧

mv, move, rename 是相同的命令, 若要更改文件名, 可以使用 mv 命令.

2.10   删除(remove)

对仓库中指定文件进行标记, 以便在下一次提交时被删除. 被标记的文件只会在当前分支删除. 标记后的文件会从当前工作目录中删除.

hg remove hello.txt

若要撤消删除操作, 使用 hg revert 命令.

若要撤销已添加的文件, 使用 hg forget 命令.

remove 对不同状态的文件的反应:

opt/state A C M !
none W RD W R
-f R RD RD R
-A W W W R
-Af R R R R

注解

  • 文件状态: Added [A], Clean [C], Modified [M] and Missing [!]
  • 动作: Warn, Remove (from branch), Delete (from disk)

2.12   版本切换(update)

hg update
hg update tip
hg update -r 3

2.13   撤消修改(revert)

将文件到恢复到检出(未提交)的状态.

注解

revert 命令会恢复文件内容到未提交的状态, 但添加(add), 删除(remove), 复制(copy), 重命名(rename)的文件除外.

撤销当前工作目录中某个文件的修改:

hg revert hello.txt

注解

一般会生成一个 .orig 后缀的备份文件.

撤消当前工作目录中所有的修改:

hg revert --all

撤消某个历史版本中某个文件的修改:

hg revert -r 3 hello.txt

2.14   撤消变更集(backout)

如果对历史版本中某个版本所做的修改不满意, 可以把整个版本撤消:

hg backout -r 3

等价于:

hg revert -r 3 --all

3   进阶操作

3.1   克隆(clone)

hg clone example example2
hg clone http://bitbucket.org/xxxx xxxx

3.2   拉取(pull)

拉取之前先检查有哪些变更集可以拉取:

hg incoming

再考虑要不要拉取:

hg pull

拉取时也可以指定只拉取哪些分支, 哪些版本.

3.3   推送(push)

推送之前先检查有哪些变更集可以推送:

hg incoming

再考虑要不要推送:

hg push

推送时也可以指定只推送哪些分支, 哪些版本.

3.4   合并(merge)

若拉取之后, 有 2 个以上的 head, 可以考虑进行合并:

hg merge

注解

合并操作是不能回滚 (Rollback) 的.

3.5   解决冲突

合并过程中会自动解决冲突, 若某些冲突无法自动解决, 则需要手工解决.

3.6   回滚(rollback)

若对最后一次提交的变更集不满意, 可以执行回滚操作:

hg rollback

注解

只有一级回滚, 回滚操作不能被还原. 它会恢复最后一次事务那个时间的目录状态, 损失从那时起的所有目录状态. 而且合并操作是不能回滚的.

可以回滚的操作:

  • commit
  • import
  • pull
  • push (需要在这个仓库的目的仓库进行回滚操作)
  • unbundle

3.7   更正提交信息

若仅仅只是提交信息遗忘或者填写错误, 则完全没有必要进行回滚:

hg commit --amend

这个命令可以修改最后一次提交的提交信息.

3.8   书签(bookmark)

书签与 Git 的本地分支类似, 是指向某个版本的指针.

查看书签:

hg bookmarks

添加一个 feature-a 的书签:

hg bookmark feature-a

书签改名:

hg bookmark --rename feature-a feature-hello

删除书签:

hg bookmark --delete feature-a

注解

更多书签相关的操作可以参考: http://mercurial.aragost.com/kick-start/en/bookmarks/

3.9   分支(branch)

Mercurial 中的分支是不能删除的, 只能关闭, 不像 Git 的本地分支那样, 可以随时删除, Mercurial 中和它类似的功能是书签 (Bookmark).

查看分支:

hg branches

增加一个分支:

hg branch stable
hg commit -m "Started stable branch."
hg tag 1.0

注解

不同分支之间只能合并, 分支切换可以使用 hg update 命令.

一般情况下, default 是日常开发分支, stable 分支只做重要的版本发布. 某些情况下, 某个 Bug 可能在 default 分支修正了, 但 stable 分支又不能马上与 default 分支合并, 这时就需要把修正这个 Bug 的版本复制到 stable 分支:

hg update stable
hg graft tip  # 或者 hg graft -r 12
hg tag 1.0.1
hg update default
hg merge stable

注解

更多分支相关的操作可以参考: http://mercurial.aragost.com/kick-start/en/tasks/

3.10   标签(tag)

标签用于发布版本.

查看标签:

hg tags

在当前版本打标签:

hg tag 1.0

为某个指定版本打标签:

hg tag 1.1 -r 30

3.13   服务器(serve)

最简单的架设一个服务器的命令:

hg serve

4   使用 Hgweb 架设服务器

参考: http://mercurial.selenic.com/wiki/PublishingRepositories

系统环境:

  • Apache 2.2 - 2.4
  • Mod_wsgi 3.5
  • Python 2.7.x
  • Mercurial 3.2 - 3.4
  • Virtualenv

Hgweb 从 Mercurial 代码仓库中获取.

相关路径:

  • Hgweb 目录: /var/www/hgweb
  • 虚拟环境路径: /var/www/hgweb/env
  • 仓库路径: /var/www/hgweb/repos

文件 /var/www/hgweb/hgweb.wsgi:

# An example WSGI for use with mod_wsgi, edit as necessary
# See http://mercurial.selenic.com/wiki/modwsgi for more information

# Path to repo or hgweb config to serve (see 'hg help hgweb')
config = "/var/www/hgweb/hgweb.conf"

# Uncomment and adjust if Mercurial is not installed system-wide
# (consult "installed modules" path from 'hg debuginstall'):
# import sys; sys.path.insert(0, "/var/www/hgweb")

# Uncomment to send python tracebacks to the browser if an error occurs:
#import cgitb; cgitb.enable()

activate_this = '/var/www/hgweb/env/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))

# enable demandloading to reduce startup time
from mercurial import demandimport; demandimport.enable()

from mercurial.hgweb import hgweb
application = hgweb(config)

配置文件 /var/www/hgweb/hgweb.conf:

[paths]
# mysite = /var/www/hgweb/repos/mysite
/ = /var/www/hgweb/repos/*

[web]
baseurl = /hg
encoding = "UTF-8"
allow_archive = bz2 gz zip
descend = True
collapse = True
allow_push = *
push_ssl = False

创建仓库路径:

cd /var/www/hgweb/
mkdir repos
chown -R daemon:daemon repos
cd repos
hg init mysite
chown -R daemon:daemon mysite

注解

本例中, 需要设置拥有者为 daemon:daemon, 而不是 apache:apache. 若 httpd 为 centos 6 仓库中安装的, 则拥有者设置为 apache:apache.

Httpd 配置:

WSGIScriptReloading On
WSGIDaemonProcess hgweb threads=5 display-name=%{GROUP}
WSGIScriptAlias /hg /var/www/hgweb/hgweb.wsgi
WSGIProcessGroup hgweb

<Location /hg>
    AuthType Basic
    AuthName "Mercurial repositories"
    AuthUserFile /var/www/hgweb/hgweb_users
    <LimitExcept GET>
        Require valid-user
        # Require user digwtx
    </LimitExcept>
    # Require valid-user
</Location>

注解

若要做成私有仓库, 则把 LimitExcept 段注释掉; 把下面那行 # Require valid-user 前面的 # 去掉.

用户认证文件的操作:

htpasswd -c /var/www/hgweb/hgweb_users digwtx  # 创建文件和用户
htpasswd /var/www/hgweb/hgweb_users digwtx01  # 追加用户, 或修改密码
Tags:   hgmercurial .