hg tip - 中文版

原作者:
Steve Losh
David Harrigan
Johnny Graber
Ryan Wilcox
Yuya Nishihara
Zachary Voase
翻译:
项目主页:

hg tip

hg tip 中文版

目录

初阶贴士

设置用户名

作者:Steve Losh
日期:2009-09-28

在你使用Mercurial之前,你需要设置你的用户名以便别人知道你是谁。

每当你提交东西时,Mercurial 都会将你的名字随着每次变更记录下来。开始使用 Mercurial 的第一步便是,告诉它你是谁!

为了指定你的用户名,你需要 修改~/.hgrc文件 成类似下面这样:

[ui]
username = Steve Losh <steve@stevelosh.com>

快速显示变更集信息

作者:Steve Losh
日期:2009-09-29

想要了解一个变更集的 所有 细节?那就添加 hg show 这个命令别名吧。

Mercurial 有许多命令用来了解有关一个变更集的信息,但是假如你发现你常常回溯之前的个别变更内容的话,你可以 添加以下的别名到你的~/.hgrc文件之中:

[alias]
show = log --color=always -pr

如果你正使用的 Mercurial 版本低于1.3,你需要先开启 别名扩展(aliasextension) ,或是最好更新你的Mercurial。

现在你可以使用 hg show REV 来了解某个特定版本的变更内容细节,就像下面这样:

$ hg show tip
changeset:   34:386adf7273a8
tag:         tip
user:        Steve Losh <steve@stevelosh.com>
date:        Mon Sep 28 22:16:10 2009 -0400
summary:     Switch the feed link in the navigation to use FB too.

diff --git a/layout/skeleton/_base.html b/layout/skeleton/_base.html
--- a/layout/skeleton/_base.html
+++ b/layout/skeleton/_base.html
@@ -53,7 +53,7 @@
                 <a href="/tips/beginner/">beginner</a> /
                 <a href="/tips/advanced/">advanced</a> &mdash;
                 <a href="/submit/">submit</a> &mdash;
-                <a href="{{ site.url }}/tips/atom.xml">feed</a> &mdash;
+                <a href="http://feeds.feedburner.com/hgtip/">feed</a> &mdash;
                 <a href="http://twitter.com/hgtip/">twitter</a> &mdash;
                 <a href="/about/">about</a>
             </p>

配置 Mercurial

作者:Steve Losh
日期:2009-09-30

学习将 Mercurial 配置成你所喜欢的样子。

几个看起来普通又过时的文本文件控制着 Mercurial 的运作,让我们来瞧瞧它们到底长个什么样和怎样干活的。

配置文件格式

Mercurial 的配置文件分为很多段,每段各有一些字段。比如说:

[ui]
username = Steve Losh <steve@stevelosh.com>
editor = vim

[alias]
killitwithfire = revert --no-backup --all

这个示例文件分为两段: [ui][alias][ui] 段有两个字段而 [alias] 有一个字段。等号的左边是字段名,右边则是字段值。

你可以使用任意你喜欢的文本编辑器来编辑配置文件。

配置文件级别

你每次运行 Mercurial 的时候它都会去查找一些位于不同位置的配置文件,并且应用它所找到的 所有 文件的设置。“特定的”配置文件设置会覆盖“全局的”配置文件设置。而接下来我们将会说明“特定的”与“全局的”的意义。

“安装级的”与“系统级的”配置文件

这是你能够找到的最“全局的”配置文件,这些文件里的每个设置都会应用于每一个用户以及任意目录。

你可能几乎不会用到它们,除非你是个多用户系统的管理员。这里,我们先无视它们。但如果你想要了解更多的话,可以去看看 使用手册 [hgrc-man]。

“用户级的”配置文件

在一个系统上,每个用户都用有它们各自的 Mercurial 配置文件。这些文件是比安装级的和系统级的文件来说更“特定的”配置文件,并且也是你大部分时间都会用到的配置文件。

在 UNIX, Linux, OS X 系统上你的个人配置文件位于 $HOME/.hgrc (又称 ~/.hgrc)。

而在 Windows 上它可以是下面的任一文件(你可以选择一个你喜欢的位置并创建它):

%HOME%\Mercurial.ini
%HOME%\.hgrc
%USERPROFILE%\Mercurial.ini
%USERPROFILE%\.hgrc

这个文件中的设置将会覆盖安装级和系统级的配置文件中段和名字皆相同的设置。

作为一名用户,你可以将所有用户特定的设置放到这里。例如:

[ui]
username = Your Name <your@email.com>
editor = your_favorite_editor_command

[extensions]
... 任意你喜欢使用的扩展 ...

[alias]
... 任意你觉得方便的别名 ...
“代码库级的”配置文件

这是最“特定的”配置文件,并且它们内部的设置只适用于它们属于的代码库中的运行的命令。

代码库级的配置文件通常位于: [代码库路径]/.hg/hgrc 。注意,这里的 hgrc 前面并 没有点 !

为什么你会想要给一个单独的代码库配置设置呢?一个通常的解释是,当向一个特殊的代码库做提交时你可能会想使用一个不同的邮件地址。

可能你的用户级的配置文件包含像下面这样的内容:

[ui]
username = Your Name <you@personal.com>

但是对于一个特定的库你可能想要用你的工作邮箱,所以你可以将下面的内容放到那个代码库的 [代码库路径]/.hg/hgrc 文件之中:

[ui]
username = Your Name <you@work.com>

现在当你向这个代码库进行提交时将会使用到你的工作邮箱地址,因为代码库级的配置文件比用户级的配置文件更特化并会覆盖它。

Mercurial 配置安全

当你越来越深入使用 Mercurial 之后,可能会碰到像这么一条错误信息:

Not trusting file /home/alice/repo/.hg/hgrc from untrusted user alice, group users

这条信息出现时,Mercurial 是试图告诉你一个使用中的 hgrc 文件被其拥有者进行了恶意修改。

想了解更多有关这个状况你可以到 Mercurial 维基上的 Trust 页面看看。

更多信息

本贴士仅仅向你展示了在哪找到配置文件以及怎样修改它们。 你可以从 hgrc 使用手册 了解到更多的相关信息。

使用 Graphlog

作者:Steve Losh
日期:2009-10-03

hg log 用起来一直感觉不错,可是如果碰上了分支的话那它可就令人抓狂了。这时候 Graphlog 能够帮到你。

hg log 是你最先学会的 Mercurial 命令之一,它能让你查看到一个代码库的所有提交的记录。这是一个它使用的输出示例:

$ hg log
changeset:   2:7b393734ccf7
tag:         tip
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:42:13 2009 -0400
summary:     Do some more work.

changeset:   1:26ac605206b4
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:42:08 2009 -0400
summary:     Do some work.

changeset:   0:ef4afb3d9699
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:42:00 2009 -0400
summary:     Initial commit.

$

还不错啊!如果你的变更呈一条直线没有分支的话那它还能工作良好,可一但出现分支的话那它便变得有些难以理解了。让我们来看看更多提交后的输出:

$ hg log
changeset:   8:b58f37a6f0af
tag:         tip
parent:      3:fee36cf81486
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:48:55 2009 -0400
summary:     Oh god the server is on fire fix it now.

changeset:   7:8f54b4d0d885
parent:      5:ce29b9e5288f
parent:      6:1dff6084cda4
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:48:20 2009 -0400
summary:     Go back to the old wording.

changeset:   6:1dff6084cda4
parent:      4:3c52ba0b77af
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:47:23 2009 -0400
summary:     Actually, the wording was fine.

changeset:   5:ce29b9e5288f
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:46:21 2009 -0400
summary:     Add some content.

changeset:   4:3c52ba0b77af
parent:      2:7b393734ccf7
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:46:04 2009 -0400
summary:     Change some wording around.

changeset:   3:fee36cf81486
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:45:50 2009 -0400
summary:     Fix a horrific bug.

changeset:   2:7b393734ccf7
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:42:13 2009 -0400
summary:     Do some more work.

changeset:   1:26ac605206b4
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:42:08 2009 -0400
summary:     Do some work.

changeset:   0:ef4afb3d9699
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:42:00 2009 -0400
summary:     Initial commit.

$

现在便不是那么容易的完整的看出后面几次变更的动作。这里至少有一次合并的存在 (因为变更集 7 拥有两个父节点) 所以一定存在一个分支。难道你仅瞄一眼就能看出其中奥妙,或是试图把它搞清楚直至你抓狂?

为了使记录更容易理解,你可以通过 编辑你的~/.hgrc文件 包含以下内容来开启 graphlog 扩展

[extensions]
graphlog =

现在你可以使用 hg glog 来查看一个包含了 ASII 字符画的记录,就像这样:

$ hg glog
@  changeset:   8:b58f37a6f0af
|  tag:         tip
|  parent:      3:fee36cf81486
|  user:        Steve Losh <steve@stevelosh.com>
|  date:        Fri Oct 02 23:48:55 2009 -0400
|  summary:     Oh god the server is on fire fix it now.
|
| o    changeset:   7:8f54b4d0d885
| |\   parent:      5:ce29b9e5288f
| | |  parent:      6:1dff6084cda4
| | |  user:        Steve Losh <steve@stevelosh.com>
| | |  date:        Fri Oct 02 23:48:20 2009 -0400
| | |  summary:     Go back to the old wording.
| | |
| | o  changeset:   6:1dff6084cda4
| | |  parent:      4:3c52ba0b77af
| | |  user:        Steve Losh <steve@stevelosh.com>
| | |  date:        Fri Oct 02 23:47:23 2009 -0400
| | |  summary:     Actually, the wording was fine.
| | |
| o |  changeset:   5:ce29b9e5288f
| |/   user:        Steve Losh <steve@stevelosh.com>
| |    date:        Fri Oct 02 23:46:21 2009 -0400
| |    summary:     Add some content.
| |
| o  changeset:   4:3c52ba0b77af
| |  parent:      2:7b393734ccf7
| |  user:        Steve Losh <steve@stevelosh.com>
| |  date:        Fri Oct 02 23:46:04 2009 -0400
| |  summary:     Change some wording around.
| |
o |  changeset:   3:fee36cf81486
|/   user:        Steve Losh <steve@stevelosh.com>
|    date:        Fri Oct 02 23:45:50 2009 -0400
|    summary:     Fix a horrific bug.
|
o  changeset:   2:7b393734ccf7
|  user:        Steve Losh <steve@stevelosh.com>
|  date:        Fri Oct 02 23:42:13 2009 -0400
|  summary:     Do some more work.
|
o  changeset:   1:26ac605206b4
|  user:        Steve Losh <steve@stevelosh.com>
|  date:        Fri Oct 02 23:42:08 2009 -0400
|  summary:     Do some work.
|
o  changeset:   0:ef4afb3d9699
   user:        Steve Losh <steve@stevelosh.com>
   date:        Fri Oct 02 23:42:00 2009 -0400
   summary:     Initial commit.

$

这样的话更容易看出哪里出现了分支了吧。

我个人的话喜欢 hg glog 的输出内容更简洁一些,因为通常我并不需要那么多的提交信息。我将我的 ~/.hgrc 文件修改包含如下内容:

[defaults]
glog = --template 'changeset:   {rev}:{node|short} {tags}\nsummary:     {desc|firstline|fill68|tabindent|tabindent}\n\n'

通过将这个模板设为默认,我的 hg glog 输出内容就像这样:

$ hg glog
@  changeset:   8:b58f37a6f0af tip
|  summary:     Oh god the server is on fire fix it now.
|
| o    changeset:   7:8f54b4d0d885
| |\   summary:     Go back to the old wording.
| | |
| | o  changeset:   6:1dff6084cda4
| | |  summary:     Actually, the wording was fine.
| | |
| o |  changeset:   5:ce29b9e5288f
| |/   summary:     Add some content.
| |
| o  changeset:   4:3c52ba0b77af
| |  summary:     Change some wording around.
| |
o |  changeset:   3:fee36cf81486
|/   summary:     Fix a horrific bug.
|
o  changeset:   2:7b393734ccf7
|  summary:     Do some more work.
|
o  changeset:   1:26ac605206b4
|  summary:     Do some work.
|
o  changeset:   0:ef4afb3d9699
   summary:     Initial commit.

$

对我来说,这更容易理解并且包含了所有我所需要的信息。假如对某个变更集我想了解更多的话,我会使用 hg log -r REV 或是 hg show REV

便捷的指定版本

作者:Steve Losh
日期:2009-10-05

没有必要总是去使用数字 – Mercurial 还有好多手段藏而待用呢。

大部分的 Mercurial 命令需要你指定一个版本以执行。比如: hg update REV 会更新到版本 REV ,还有 hg diff -c REV 会向你展示版本 REV 的变更。

最普通的方法让 Mercurial 去执行某一个版本便是使用本地版本号。比如: hg update 30 会将工作目录更新到版本 30

如果你知道想要的版本号那是不错了 (或是不介意用 hg log 去找一下),但是 Mercurial 还有许多便捷的方法可以使其变得更容易。

哈希值

在本地代码库里大部分时间你可能只会使用版本号作为指定版本唯一的方式。通常这并没什么问题,不过如果你想告知某人一个特殊的版本时你应该使用 唯一的哈希值 作为那个版本的标识。

你可以通过 hg log 来获得版本的哈希值 – 它显示在版本号的后面。如下:

$ hg log -r 30
changeset:   30:f7744f53cf93
...

在此例中 f7744f53cf93 便是你会用到的哈希值,如果你要告诉某人的话。

标签

你可以在任意能使用版本号的地方使用一个标签名。假如你有一个标签名为 1.0 表示版本 30 ,那么你可以使用 hg update 1.0 获得和 hg update 30 同样的结果。

命名分支

假如你使用过命名分支(通过 hg branch branchname 创建)那么可以使用 branchname 来作为 “branchname 分支的最后一次版本提交” 的版本号的代替。

当你常常要跳转分支使用的时候这会非常的方便:

$ hg update feature-branch
... 从一个新特性开始工作 ...
$ hg commit -m 'Add part of the new feature.'
$ hg update default
... 修正一个默认分支上非常紧急的问题 ...
$ hg commit -m 'Fix the bug that set the servers on fire.'
$ hg update feature-branch
... 再回到之前离开的特性分支上 ...

这在你想要进行合并时也会很有用(记住,hg merge 可以通过一个版本号来劲行合并):

$ hg update default
$ hg merge --rev feature-branch
$ hg commit -m 'Merge in the new feature.'
当前父版本

一个更鲜为人知的指定版本的技巧是使用 . 代替 当前工作目录的父亲版本

$ hg commit -m 'Finish up some changes.'
$ hg log --change .
... 显示你刚刚提交的那个版本的变更 ...
$ hg diff --rev 12:.
... 显示版本12与你刚刚提交之间的不同 ...
$ hg update -C .
... 清除所有工作目录未提交的变更并维持版本的不变 ...
Tip 的祖先版本

如果你使用一个负数代替版本时它意味着 “从代码库的tip版本倒着数的第X个版本” 。 -1 表示tip版本本身, -2 表示tip版本的父版本,依次类推。

这用在你进行合并时可能会显得比较棘手,但假如你只是需要从tip版本向后回溯几个版本的话还是很有用的。

其他诀窍

其实还有很多方法来指定版本,试试 hg help revisions 了解更多。

如果你是个正在尝试 Mercurial 的 git 用户并且需要 revison^ 语法,可以去看看 parentrevspec extension 它向 Mercurial 加入了这个语法。

便利且有趣的 Shortlog

作者:Steve Losh
日期:2009-10-07

通过添加一个 hg shortlog 别名命令会让你做到许多很棒的事情。

许多 Mercurial 命令都可以通过 --template 选项来自定义输出内容。你可以使用 hg help templating 对你能够使用模板干哪些事情做一个深入的了解。

在本贴士中,我们将会使用到一个非常小巧但却是异常强大的模板。

Shortlog 模板

让我门先来看看一个非常简单的模板示例,用于 hg log

hg log --template '{rev}:{node|short} {desc|firstline}\n'

这个命令将会输出代码库中所有变更集的记录,每行一条,并且每一行包括版本号、哈希值以及摘要。看起来像是这样:

81:966ff708eb3a Add the Shortcuts for Specifying Revisions beginner tip.
80:3dca217e76a2 Change the title to something better.
79:4edca6026448 Change the title to something more description.
78:bea31254eba5 Add the Graphlog beginner tip.
77:5ef6bf0c5081 Add scrollbars to code blocks if needed.
76:dd1fa17eaa1f Reduce the number of tips on the front page to 4 per category.
75:f3d5a6d9d5a5 Fix the nested <p> tag issue.
74:e6a76edf8032 Add the Creating Repositories Over SSH advanced tip.
73:a4f1c617f01f Reword "N.B." to "Note" because it looks better before the colon.
72:e44939482007 Mention the feature requirement for HTTP User Auth.
... 其他的行 ...

这在你想要了解状况但又不需要太多信息的时候将会很有用处。接下来,让我们向 你的~/.hgrc文件 添加下面的别名命令:

[alias]
slog = log --template '{rev}:{node|short} {desc|firstline}\n'

现在你可以使用 hg slog 来输出一个非常简洁的记录了。不过我们这还没有结束呢。

计数

这个模板有一处非常特别的地方: 每条记录项占据一行 。这意味着我们可以使用UNIX 的 wc (worldcount) 工具来计算行数,并由此得出变更集的多少。

例如,我们可以计算代码库中的变更集数目:

$ hg slog | wc -l
  82

这可真心没用,因为我们可以通过最新变更集的版本号来得知。不过真正有趣的地方现在才开始呢,我们可以使用 hg log 的过滤选项来选择我们想要计算的变更集数目,来试试吧。

计算是合并的变更数目:

hg slog --only-merges | wc -l

计算非合并的变更数目:

hg slog --no-merges | wc -l

计算为 ‘Steve’ 提交的变更数目:

hg slog --user Steve | wc -l

计算过去三天提交的变更数目:

hg slog --date -3 | wc -l

计算自2月1号以来提交的变更数目:

hg slog --date '>Feb 1' | wc -l

计算字三月以来 Steve 提交的非合并变更数目:

hg slog --no-merges --user Steve --date '>Mar 1' | wc -l

使用像这样的模板 (每行一个变更集) 可以方便的计数任何你能使用 hg log 过滤而得到的项目。试试 hg help log 了解更多的过滤方法。

免费托管于 BitBucket

作者:Steve Losh
日期:2009-10-13

你可以免费托管你的静态网站到 BitBucket 上。

BitBucket 的一个尚未文档化的 (就我所知是这样) 特性便是允许你将一个静态网站托管于其上。你可以像下面这样快速且简单的开始:

  1. 在 BitBucket 上创建一个名为 yourusername.bitbucket.org 的代码库。
  2. 将其 Clone 到你本地。
  3. 添加一个简单的 index.html 文件。
  4. 将其 Push 到 BitBucket 上。

现在访问 http://yourusername.bitbucket.org/ 你便能看到你刚刚上传的 index.html 文件的内容了。

BitBucket 会将指定代码库的 tip 版本里所有东西作为一个静态网站展现出来。这与GitHub 的用户级的 “pages” 特性相类似,除了你的文件不会被 Jekyll 或是其他的过滤器运行。

不幸的是,BitBucket 并没有一个与 GitHub 的项目级 “pages” 对应的东西。

始终使用 Git Diffs

作者:Steve Losh
日期:2009-10-22

难道你会去用一个还在兼容于1985年发布的程序的 diffs 工具?

Mercurial 像 hg diff 一类命令的默认 diffs 输出风格是还在兼容于 UNIX patch 工具的风格。我猜你可能常常使用 patch 并还感觉不错,不过我们可不这么认为。

Git 采用了一种新的格式,它的一些新特性确保了 diffs 更易读,并且 Mercurial 也可以利用这一格式。

Mercurial 维基页面 解释了如何使用它,但在这里我们会向你展示使用方法以便你不用再去读它。 编辑你的~/.hgrc文件 如下:

[diff]
git = True

就是这样!所有 Mercurial 命令的 diffs 输出都将会使用这个更好的格式。现在当你使用 hg rename 重命名一个文件时 diffs 会告诉你 “文件 X 重命名为 Y” 而不是分为删除了一个文件再添加了一个文件。

在 Push 之前查看变更集

作者:Ryan Wilcox
日期:2009-10-27

查看自你最后一次 push 之后创建的变更集。

不管何时你向 Mercurial 提交过东西后,直到你真正将其向另一个服务器 push 之前那个变更集通常都会继续保留在你的机器上。这不像 Subversion 之类的集中式系统一样,它的 push 是另一个分开的步骤。可是有时在你将所有变更发送给别人的时候你又会想要确切的知道到底 push 的是哪些变更集,又该怎么办呢。

Mercurial 有这样一个特性能够帮到你: outgoing 命令。例如:

$ hg outgoing default
comparing with ssh://hg@bitbucket.org/rwilcox/somehgrepo/
searching for changes
changeset:   110:bf9aaaf1ebf3
user:        Ryan Wilcox <rwilcox@wilcoxd.com>
date:        Sat Oct 24 09:36:59 2009 -0400
summary:     A change

changeset:   111:223342c3061f
user:        Ryan Wilcox <rwilcox@wilcoxd.com>
date:        Sat Oct 24 20:52:12 2009 -0400
summary:     another change

changeset:   112:e13f56188516
user:        Ryan Wilcox <rwilcox@wilcoxd.com>
date:        Sat Oct 24 21:06:45 2009 -0400
summary:     last change

outgoing 命令所带的参数便是你想要进行比较的代码库,而 “default” 则是指使用默认的路径而不是另外指定一个。

恢复错误的文件

作者:Ryan Wilcox
日期:2009-11-30

教你如何清除那些不想提交的变更。

假如这有一个你不想要的变更。比如:

$ hg status
M fileone.txt
M filetwo.txt

在复查变更时你发觉 filetwo.txt 是没用的想清理掉它。当然你 可以 打开文件亲手去删除你的变更,但是 Mercurial 给了你一个更好的选择: hg revert

$ hg revert filetwo.txt

假如你有许多文件都做了变更 (例如你想放弃之前的工作从头开始),那可以用 --all 命令:

$ hg revert --all
reverting fileone.txt
reverting filetwo.txt

这和 git reset --hard HEAD^ 命令很像,有没有一点 git 的熟悉感呢。

找出不同的变更

作者:Steve Losh
日期:2009-12-09

你能不能说出哪些变更集属于版本 X不是 属于版本 Y 呢?

本文受到 mercurial-devel 邮件列表一封邮件 的启发。

那个问题简单的来说就是:你怎样能确定哪些变更集属于版本 X不是 属于版本 Y ?这在你更新使用的软件并想知道新老版本之间有何不同的时候将会很有用。

听起来是个很简单的任务,不过这里还是有一些你值得注意的技巧在里面。

Note

本贴士中我会使用 shortlog 别名 来代替 hg log 命令使输出内容更易读。所有工作都和 hg log 一样正确的执行 (因为 hg slog 就是 hg log 添加了模板的别名命令而已),所以请放心使用。

简单(但不正确)的方法

让我们先用最简单的方法来列出版本: --rev 选项。比方说我们有一个简单的代码库的结构图看起来就像下面这样:

$ hg glog
o  4 Fix another bug. (6 seconds ago by Steve Losh) tip
|
o  3 Fix a bug. (16 seconds ago by Steve Losh)
|
@  2 Add another simple feature. (34 seconds ago by Steve Losh)
|
o  1 Add a simple feature. (40 seconds ago by Steve Losh)
|
o  0 Initial revision. (7 minutes ago by Steve Losh)

假如你当前正在版本 2 并想知道你更新到 tip 之后会发生哪些变更,你可能会用像下面这样的操作:

$ hg slog --rev 2:tip
2 Add another simple feature. (5 minutes ago by Steve Losh)
3 Fix a bug. (5 minutes ago by Steve Losh)
4 Fix another bug. (5 minutes ago by Steve Losh) tip

你可以看到输出内容中居然还包括了版本 2 ,这并不需要列举出来的因为你就正处于这个版本。好吧,这并不是什么大问题,你完全可以忽略掉它。

可是,当你同时在代码库的多个分支上进行工作时这个方法就没用了。比如:

$ hg glog
@  6 Fix a critical bug. (1 second ago by Steve Losh) tip
|
| o  5 Start the rewrite of the UI. (24 seconds ago by Steve Losh)  ui-rewrite
| |
o |  4 Fix another bug. (8 minutes ago by Steve Losh)
| |
o |  3 Fix a bug. (8 minutes ago by Steve Losh)
| |
o |  2 Add another simple feature. (9 minutes ago by Steve Losh)
|/
o  1 Add a simple feature. (9 minutes ago by Steve Losh)
|
o  0 Initial revision. (16 minutes ago by Steve Losh)

$ hg slog --rev 2:tip
2 Add another simple feature. (9 minutes ago by Steve Losh)
3 Fix a bug. (9 minutes ago by Steve Losh)
4 Fix another bug. (9 minutes ago by Steve Losh)
5 Start the rewrite of the UI. (54 seconds ago by Steve Losh)
6 Fix a critical bug. (31 seconds ago by Steve Losh) tip

注意 hg slog 命令的输出中包含了变更集 5 。它可是另一个分支上的,从 2 更新到 tip (6) 根本不会包括 5 里的变更。

这发生原因是因为当你指定一个版本范围时 Mercurial 是按照版本号顺序步进的去执行 它们。这也就是说 1:4 真正表示的是 “ 123 还有 4 不管它们之间有没有分支出现”。

通过一些其他的 hg log 选项我们能比这做的更好。

正确的方法

如果我们回退几步并仔细思考下我们正试图解决的问题,我们可以将其简化为一个更简单的定义。我们想要查看所有的变更集是:

  • 属于目标版本(即其祖先)
  • 属于源版本

解决第一个问题,我们可以使用两个选项的组合, --rev--follow ,就像这样:

$ hg slog --rev tip:0 --follow
6 Fix a critical bug. (11 minutes ago by Steve Losh) tip
4 Fix another bug. (20 minutes ago by Steve Losh)
3 Fix a bug. (20 minutes ago by Steve Losh)
2 Add another simple feature. (20 minutes ago by Steve Losh)
1 Add a simple feature. (21 minutes ago by Steve Losh)
0 Initial revision. (28 minutes ago by Steve Losh)

注意这里并没有显示其他分支上多余的变更集。

使用 --rev DESTINATION:0 假设 --follow 就是说“显示所有是 DESTINATION 祖先的变更集”。 试试 hg help log 了解所有选项的作用。

接下来我们还有一件事要做 – 从列表中移除属于我们当前版本的变更集:

$ hg slog --rev tip:0 --follow --prune 2
6 Fix a critical bug. (16 minutes ago by Steve Losh) tip
4 Fix another bug. (25 minutes ago by Steve Losh)
3 Fix a bug. (25 minutes ago by Steve Losh)

就是这样!变更集 643 就是从我们示例代码库中将 2 更新到 6 后生效的变更集。

这个命令通常的格式就是这样:

hg slog --rev DESTINATION:0 --follow --prune SOURCE

当然你也可以全部都使用缩写来指定。比如你想知道从你当前工作的版本更新到 tip 会包含哪些变更:

hg slog -r tip:0 -fP .

Note

这个命令在你“向后”更新的时候 不会 有用。它只会向你展示那些添加的变更集 – 它不会提到属于 SOURCE 属于 DESTINATION 的变更集。

了解进度

作者:David Harrigan
日期:2010-03-24

是不是觉得 hg 对你有所隐瞒呢?想要知道它在做些什么?这有办法了!

有时当使用 Mercurial 生成大量文件时提示符就卡在那里好长时间不动了。不过还好,从 Mercurial 1.5 起你可以用一个新的插件来解决这个问题了。 编辑你的~/.hgrc文件 包含像下面的内容:

[extensions]
progress =

当这个极棒小插件启用时你可以看到如下画面:

_images/progress-verify.png

看到那个漂亮的进度条了么?这是另一个简单的例子:

_images/progress-clone-remote.png

我希望你能够觉得这个小贴士有用并且它能在你的 Mercurial 日常使用中帮到你。想要了解这个插件的更多信息,你可以到 Mercurial 官网上 它的页面 进行查询。

进阶贴士

Nudge — 优雅的 Push 版本

作者:Steve Losh
日期:2009-09-28

添加 hg nudge 别名以仅 push 当前工作目录的父版本。

有一件会使大部分 git 用户困惑的事情,就是当运行 Mercurial 的 hg push 命令时, Mercurial 默认会 push 代码库中 所有 的变更集,而 git 仅仅只 push 当前的分支。

如果你更喜欢 git 的习惯 (可能你频繁的在分支之间工作并不停的进行 push),可以简单添加一个和此习惯接近的别名。

Mercurial 允许你使用 . 作为指定“当前工作目录的父亲版本”的快捷方式。在 push 的时候使用它即意味着你可以运行 hg push --rev . 仅 push 工作目录的父版本(以及祖先)。这样的话你就不用再去关心会 push 到你没有工作的其他分支了。

添加这个命令,可以像下面这样 编辑你的~/.hgrc文件

[alias]
nudge = push --rev .

现在你可以使用 hg nudge 来仅仅 push 你的当前工作的分支了。

Fetch 扩展

作者:Zachary Voase
日期:2009-09-29

如果你是自 Git 迁移过来并怀念 git pull 的自动合并功能的话,这将是你正寻找的扩展。

新近自 Git 迁移过来的用户常常会惊讶于 hg pull 的行为。与之相反的 git pull 会更新工作目录、自动合并与提交,而 hg pull 仅仅只是添加远程的变更集到你的本地库并不会对你的工作目录进行任何操作。

十有八九你会想要自动合并的方式。幸运的是,这并不是什么难事。 编辑你的~/.hgrc文件 并添加以下内容:

[extensions]
hgext.fetch =

现在,你可以从这样:

$ hg pull
$ hg update remote_head
$ hg merge local_head
$ hg commit -m "Merged."

变为这样:

$ hg fetch

默认情况下, fetch 会使用 pull 来的远程变更的头作为合并后的第一父亲,而你本地变更的头作为第二父亲。你也可以像下面这样获得相反的结果:

$ hg fetch --switch-parent

了解更多信息,可查阅 wiki 文档hg help fetch 帮助。

自动检测重命名

作者:Steve Losh
日期:2009-09-30

Mercurial 能够识别出哪些添加/删除操作实际上是重命名, 如果 你使用了适当的命令的话。

hg addremove 命令在你手动的对大量文件进行操作的时候会显得很方便。你可以使用你喜欢的任意方式(Finder,windows Explorer,shell等等)来改变原有结构,然后再运行 hg addremove 命令让 Mercurial 来识别你做了哪些改变。

这有一个 hg addremove 鲜为人知的特性,就是当你移动或重命名一个文件时它能将其识别并把重命名操作记录为删除和添加操作代替。将操作记录为重命名会让 Mercurial 合并变更更智能。

为了使 Mercurial 能够检测出重命名,你可以把 hg addremove--similarity 选项一起使用:

$ hg addremove --similarity 100

那个数字是个百分值。在此例中,Mercurial 会将一对添加/删除操作认为是一个重命名操作仅仅当添加的文件被确认为(100%相似)是被删除的文件时。

使用一个小些的数字能够匹配包括进行过其他变更的重命名操作,但是会增加误报的风险。一个好的习惯是将所有你的文件与目录变更作为依次提交,并把对这些文件的 文本内容 变更作为另一次提交。

如果你发现你对这个操作使用得相当频繁的话你可以通过 修改你的~/.hgrc文件--similarity 100 作为默认选项:

[defaults]
addremove = --similarity 100

注意,使用 [defaults] 会影响到 所有 运行的命令,包括当其作为脚本运行时亦是。

HTTPS 用户认证配置

作者:Zachary Voase
日期:2009-10-01

配置 Mercurial 以便每次凭借 HTTPS 进行 push/pull 时不再提示输入密码。

如果你将 HTTPS 作为你对一个库进行 push/pull 操作的选择,你会发觉你每次这样做时 Mercurial 都会向你寻求认证。幸运的是,这里只需在你的 ~/.hgrc 文件做一个简单的配置便可解决这个问题。

Note

这是一个 Mercurial 1.3 推出的新特性。如果你的版本比其更老你需要更新以使用此贴士!

Warning

本贴士涉及到将你的用户名与密码作为普通文本放到 ~/.hgrc 中。这通常会比下面这样做带来更多的安全问题:

  • 使用 SSH 和 ssh-agent (参见 这篇文章 ),或是
  • 每次都输入你的密码

如果你不是 100% 的确认你是唯一一个能够访问你的 ~/.hgrc 的人,那就此停下。

你的 ~/.hgrc 文件中的 [auth] 段包含了 HTTP 认证需要的凭证。每一组凭证都可以任意取名;根据本贴士的目的我们假定你使用 BitBucket 托管你的代码库,所有将这组凭证叫做 bb

将下面内容添加到你的~/.hgrc中

[auth]
bb.prefix = https://bitbucket.org
bb.username = {username}
bb.password = {password}

{username}{password} 替换为你的 BitBucket 认证。

你也可以指定拥有不同 prefix 的多组认证。比如说,你有两个 BitBucket 帐号:

[auth]
bb1.prefix = https://bitbucket.org/foo/
bb1.username = foo
bb1.password = foo_passwd

bb2.prefix = https://bitbucket.org/bar/
bb2.username = bar
bb2.password = bar_passwd

当向任意 URI 以 http://bitbucket.org/foo/ 为起始的库 push 时将会使用 ‘foo’ 帐号,’bar’ 同理。这样的话,不管怎样,你可以利用这一情况让 Mercurial 始终选择与指定 prefix 最匹配的那组认证。因此,假设你有如下配置:

[auth]
bb1.prefix = https://bitbucket.org/
bb1.username = foo
bb1.password = foo_passwd

bb2.prefix = https://bitbucket.org/bar/
bb2.username = bar
bb2.password = bar_passwd

这样所有的非 /bar/ 库都会使用 ‘foo’ 帐号,因为它是唯一匹配的认证。 /bar/ 则会使用 ‘bar’ 帐号,虽然它们都能够匹配上但是 ‘bar’ 更准确。

最后,你可以告诉 Mercurial 一个 prefix 能够 同时 匹配 HTTP 与 HTTPS,通过去掉 prefix 字段的协议部分并添加一个 schemes 字段到认证中:

[auth]
bb.prefix = bitbucket.org
bb.username = foo
bb.password = foo_passwd
bb.schemes = http https

想要了解更多的信息,请查阅 hgrc 的 auth 文档

通过 SSH 来创建代码库

作者:Steve Losh
日期:2009-10-02

你并不用登录到服务器上去创建一个新库,你可以用 hg clone 来做到。

假设你有一些代码库处于其他电脑上,并且你 使用 SSH 来对它们进行 push 和 pull

接着你又在本地创建了一个新库并进行了一些作业,然后想在服务器上创建这个库?最普遍的做法是先登录到服务器上并创建一个空库:

$ ssh yourserver
$ cd path/to/repos
$ hg init newrepo
$ logout
$ hg push ssh://yourserver/path/to/repos/newrepos

这样能办到啊,但是需要敲太多次的键盘了。 Mercurial 有一个特性会帮到你:你可以使用 hg clone 通过 ssh 来 创建 一个新库:

$ hg clone . ssh://yourserver/path/to/repos/newrepos

Note

你仍然需要手动添加新路径到 .hg/hgrc 去。

使用 Bash 打开 BitBucket

作者:Steve Losh
日期:2009-10-08

对手动的去打开浏览器进入一个 BitBucket 的库页面感到厌烦了?

如果你工作的许多代码托管于 BitBucket ,你可能会发觉你会十分频繁的进入到它们的项目主页去。你可以通过向你的 ~/.bashrc 文件添加一个小函数来避免手动的去打开浏览器并敲下 URL 。

对于 Mac OS X

如果你使用 OS X 将下面内容添加到你的 ~/.bashrc 文件:

bitb() {
    local P="$(hg paths 2>/dev/null | grep 'bitbucket.org' | head -1)"
    local URL="$(echo $P | sed -e's|.*\(bitbucket.org.*\)|http://\1|')"
    [[ -n $URL ]] && open $URL || echo "No BitBucket path found!"
}

一但你添加了它,打开一个新的终端或是运行 source ~/.bashrc 。现在你可以使用 bitb 来打开你当前工作的代码库的 BitBucket 页面了。

对于 Cygwin on Windows

如果你使用 Cygwin 将下面内容添加到你的 ~/.bashrc 文件:

bitb() {
    local P="$(hg paths 2>/dev/null | grep 'bitbucket.org' | head -1)"
    local URL="$(echo $P | sed -e's|.*\(bitbucket.org.*\)|http://\1|')"
    [[ -n $URL ]] && cygstart $URL || echo "No BitBucket path found!"
}

一但你添加了它,打开一个新的 Cygwin 窗口或是运行 source ~/.bashrc 。现在你可以使用 bitb 来打开你当前工作的代码库的 BitBucket 页面了。

对于 Linux

如果你使用 Linux 将下面内容添加到你的 ~/.bashrc 文件:

bitb() {
    local P="$(hg paths 2>/dev/null | grep 'bitbucket.org' | head -1)"
    local URL="$(echo $P | sed -e's|.*\(bitbucket.org.*\)|http://\1|')"
    [[ -n $URL ]] && /path/to/your/browser $URL || echo "No BitBucket path found!"
}

/path/to/your/browser 替换为你浏览器的正确路径。

一但你添加了它,打开一个新的终端或是运行 source ~/.bashrc 。现在你可以使用 bitb 来打开你当前工作的代码库的 BitBucket 页面了。

对于其他系统

如果你使用的系统并没有被列举在这里,那你需要修改的最重要的一行便是最后一行。将 OS X 示例中的 open 替换为你用来在命令行打开 URL 的命令,然后对你的改变做一个注释以便其他人也能使用它!

减少按键次数

作者:Steve Losh
日期:2009-10-30

有些事使用别名命令的话可能会令你惊讶。

如果你常常使用到 Mercurial 的命令行接口的话,这或许值得你花店时间来添加一些你常常使用的命令的别名。

有一件你可能没有意识到的事情是你在创建别名命令时并不仅限于字母 – 几乎任何东西,除了 shell 的元字符外都是被允许的。

这有一些想法能帮你开始([编辑你的~/.hgrc文件]来使用它们):

[alias]
cm = commit --message
up = update --check
. = summary
? = compass
: = status

, = glog -l15 --template '\033[33;40m{rev} \033[37;40m{desc|firstline|fill68} \033[1;30;40m({date|age} ago by {author|person})\033[0;37;40m \033[33;40m{tags}\033[37;40m \033[35;40m{branches}\033[37;40m\n\n'

,+ = , -l1000000000

创建 Git 镜像

作者:Steve Losh
日期:2009-11-09

你选择了 Mercurial,但还是有很多人更喜欢 git 。让他们在对你的项目作出贡献时更方便些。

在所有的像 Mercurial 一样的分布式版本控制系统中来说, git 很可能是最受欢迎的。如果你有项目使用的是 Mercurial,那你可以方便且快捷的创建一个你的项目的 git 镜像,这样的话 git 用户便能对其作出贡献了!

安装 hg-git

首先,你需要下载 hg-git 插件:

easy_install dulwich
hg clone http://bitbucket.org/durin42/hg-git/

现在 编辑你的~/.hgrc文件 包含以下内容:

[extensions]
hggit = /path/to/hg-git
创建一个 GitHub 帐号

你需要一个地方放置你的 git 镜像, GitHub 是一个理想的选择。继续并 注册 一个 GitHub 帐号如果你没有的话。

在 GitHub 上创建一个库

现在你拥有了一个 GitHub 帐号,你需要通过 “New Repository” 按钮来创建一个代码库。

一但你创建了一个新库,你将会看到一个与下面类似的页面:

_images/github.jpg

看到那个 git@github.com:username/project.git 的 URL 没?记住它,因为你在 push 你的镜像时你将会用到它。

Push 你的项目

现在你已经装好了 hg-git 并且为你的项目在 GitHub 上创建好了一个代码库,你还需要将你的 Mercurial 库 push 到 GitHub 上去。首先,通过编辑你项目里的 .hg/hgrc 来将 git 的 URL 添加到你的 Mercurial 代码库里去:

[paths]
git = git+ssh://git@github.com/username/project.git

Note

重要注意事项: 你需要把 github.com 后面的 : 替换为一个 / (正斜杠)。这是必须的,因为 Mercruial 就是这样来操作代码库的路径的!

当然,你还需要将 usernameproject 替换为适当的值。

现在你仅需要向 git 路径 push 以创建你的镜像了:

hg push git

这将会耗费一些时间,尤其当你的代码库比较大时。一但它结束了的话你便在 http://github.com/username/project/ 上拥有了一个能100%正常运转的 git 镜像了。 Git 用户便能够通过运行 git clone git://github.com/username/project.git 来克隆你的项目了并且可能连你使用的是 Mercurial 都不会意识到。

接受贡献

创建了一个镜像以提供给 git 用户克隆干的非常漂亮了,但最终总会有人在 GitHub 上向你发送 pull 请求的(如果你的项目很吸引人的话)。

hg-git 简单的解决了来自 git 用户的贡献。首先,添加贡献者的 fork 到你的项目路径:

[paths]
git = git+ssh://git@github.com/username/project.git
contributor = git+ssh://git@github.com/contributor_username/project.git

Note

再次, 确认你将 github.com 后面的 : 替换为了 / (正斜杠)!

接下来 pull 他们的变更到你的 Mercurial 代码库中:

hg pull contributor

你可以使用 graphlog 来观察你的代码库在这时看起来是怎么样一个状况(还有是否需要合并)。

假如你需要(或是想)合并的话,合并然后将他们的贡献 push 到你的 Mercurial 主库和你的 git 镜像上去:

hg push
hg push git

这里包含了所有的基础!如果你拥有一个大量分支的工作流的话事情可能会变得复杂,不过至少这个贴士在你接受来自 git 用户的 patch 时会帮到你。

使用 Convert 来分解你的库

作者:Thomas G. Willis
日期:2009-11-16

如果你的库已经过度的庞大了,你宁愿包含其中的项目拥有它们自己的库么?可烦人的是,历史记录怎么办呢?

假设你有一个代码库发展为包含了太多的项目(文件夹)。并且你确定你最好将每一个项目(文件夹)分割为一个独立的代码库。你可以使用 convert 扩展来做到并且还保留你的变更历史。

比如,一个库展开来像是这样的:

/yourrepository
    /DatabaseFoo
    /SweetBusinessLogic
    /BaseUI
    /AnotherDamnContentManagementSystem

你已经决定在某个时候 AnotherDamnContentManagementSystem 真的应该归为它自己的代码库中去,并且很久以前你都已经意识到这了,你会发现将它们所有整合到一块作为一个库这对你来说实在是个糟糕的选择,就如同整个版本控制都属于一个超级昂贵的操作时你依然还在使用 Perforce 一样。

幸运的是,convert 扩展能帮你在与风险投资者的会面午餐展示你的工作之前免去这些令人为难的决定。

首先 开启 convert 扩展 :

[extensions]
convert =

convert 命令有一个 --filemap 选项允许你指定在操作中哪些是你想要包含其中的与哪些是你不想要的。你甚至可以进行重命名作为操作的一部分。这个我们要执行操作的 filemap 看起来会像是这样的:

include AnotherDamnContentManagementSystem
rename .

然后你的 convert 命令看起来回事这样:

$ hg convert --filemap myfilemap bigrepo AnotherDamnContentManagementSystem-Repo

就是这样,AnotherDamnContentManagementSystem 现在拥有它自己的 Mercurial 代码库了。

合并代码库

作者:Steve Losh
日期:2009-11-17

你意识到这的时候你会怎么做:“噢,文档可能应该和代码放到同一个库里?”

Thomas 的上一个贴士有关 分解代码库 让我想到要写一篇与之相反的东西:合并两个不同的库为一个库。

假设这有一个你工作的项目,代码放在 project 中还有文档放在 docs 中。你可能会觉得将它们放到同一个库中会很棒,这样当有人克隆你的项目代码时它们也得到了文档。

可能 会仅仅是创建一个新的库然后把所有的数据拷贝进去而已,但是这样并不会将你那些出色的变更历史保留下来。那就让我们来看看怎样合并这些分隔的代码库吧。

创建用来合并的新库

首先我们将会创建一个新库用来存放所有的东西:

$ ls
total 24
drwxr-xr-x  5 sjl   170B Nov 17 19:56 docs
drwxr-xr-x  4 sjl   136B Nov 17 19:58 project

$ mv project project-code

$ hg init project

$ ls
total 24
drwxr-xr-x  5 sjl   170B Nov 17 19:56 docs
drwxr-xr-x  3 sjl   102B Nov 17 20:04 project
drwxr-xr-x  4 sjl   136B Nov 17 19:58 project-code

我们暂时先把 project 重命名为 project-code 以免与新库冲突。

各库准备

我们可不想只是把所有的东西直接扔到新库的根目录下就完了,所以让我们一点点的来做吧。首先我们会把 project 库中的所有东西移到一个 src/ 目录下:

$ cd project-code

$ mkdir src

$ mv * src
mv: rename src to src/src: Invalid argument

$ ls
total 0
drwxr-xr-x  3 sjl   102B Nov 17 20:08 src

$ hg addremove --similarity 100
removing myproject.py
adding src/myproject.py
recording removal of myproject.py as rename to src/myproject.py (100% similar)

$ hg commit -m 'Move the code into the src/ directory.'

现在我们对 docs 做同样的事情:

$ cd ../docs

$ mkdir docs

$ mv * docs
mv: rename docs to docs/docs: Invalid argument

$ ls
total 0
drwxr-xr-x  4 sjl   136B Nov 17 20:11 docs

$ hg addremove --similarity 100
removing LICENSE
removing README
adding docs/LICENSE
adding docs/README
recording removal of LICENSE as rename to docs/LICENSE (100% similar)
recording removal of README as rename to docs/README (100% similar)

$ hg commit -m 'Move the documentation into the docs/ directory.'
Pull 全部库

现在我们把结构调整为了我们想要的样子了,我们需要把两个库都 pull 到 project 去:

$ cd ..

$ ls
total 24
drwxr-xr-x  4 sjl   136B Nov 17 20:12 docs
drwxr-xr-x  3 sjl   102B Nov 17 20:04 project
drwxr-xr-x  4 sjl   136B Nov 17 20:08 project-code

$ cd project

$ ls

$ hg pull --update ../project-code
pulling from ../project-code
requesting all changes
adding changesets
adding manifests
adding file changes
added 4 changesets with 4 changes to 2 files
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

$ ls
total 0
drwxr-xr-x  3 sjl   102B Nov 17 20:15 src

$ hg pull --force --update ../docs
pulling from ../docs
searching for changes
warning: repository is unrelated
adding changesets
adding manifests
adding file changes
added 3 changesets with 4 changes to 4 files (+1 heads)
not updating, since new heads added
(run 'hg heads' to see heads, 'hg merge' to merge)

$ ls
total 0
drwxr-xr-x  3 sjl   102B Nov 17 20:15 src

注意这里我们在 hg pull 后用了 --force 选项,这也就是对 Mercurial 说:“好了好了,我知道我在做什么,我真的是想合并这些库。”

合并代码库

看一看上一个 ls 命令的输出。看到没这依旧只有 src/ 目录?我们需要合并两个库到一块以得到一个真正 “合并好的” 代码库。

为了让其更清晰一些,让我们来看看新库的图志:

$ hg glog
o  6 Move the documentation into the docs/ directory. (7 minutes ago by Steve Losh) tip
|
o  5 Add a LICENSE file. (22 minutes ago by Steve Losh)
|
o  4 Add a README file. (22 minutes ago by Steve Losh)

@  3 Move the code into the src/ directory. (10 minutes ago by Steve Losh)
|
o  2 Fix a bug. (21 minutes ago by Steve Losh)
|
o  1 Implement some basic functionality. (21 minutes ago by Steve Losh)
|
o  0 Start the project. (21 minutes ago by Steve Losh)

看见没我们居然有两个分隔开的图志?变更集0到3连在一起,而变更集4到6连在一起。现在我们需要合并这两个图志到一块,这不是什么问题因为我们事先已将文件目录结构组织好了,所以这里不会有任何冲突:

$ hg update 6
2 files updated, 0 files merged, 1 files removed, 0 files unresolved

$ hg merge 3
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)

$ hg commit -m 'Combine the source and docs repositories.'

现在看一看图志:

$ hg glog
@    7 Combine the source and docs repositories. (37 seconds ago by Steve Losh) tip
|\
| o  6 Move the documentation into the docs/ directory. (11 minutes ago by Steve Losh)
| |
| o  5 Add a LICENSE file. (26 minutes ago by Steve Losh)
| |
| o  4 Add a README file. (27 minutes ago by Steve Losh)
|
o  3 Move the code into the src/ directory. (15 minutes ago by Steve Losh)
|
o  2 Fix a bug. (25 minutes ago by Steve Losh)
|
o  1 Implement some basic functionality. (25 minutes ago by Steve Losh)
|
o  0 Start the project. (26 minutes ago by Steve Losh)

$ ls
total 0
drwxr-xr-x  4 sjl   136B Nov 17 20:22 docs
drwxr-xr-x  3 sjl   102B Nov 17 20:22 src

我们的两个不同的库现在已经完美的合并为了一个,而且变更集也完整无缺!现在我们可以把老的库删掉了还有可以把新的这个库 push 到公共服务器上提供给大家使用了。

这真是非常的漂亮因为我们并没有改变到变更集的哈希值,这即是说我们能够轻易的合并来自那些依然在使用老的分隔的代码库的用户的变更集。

处理合并时的二进制文件

作者:Ryan Wilcox
日期:2009-11-30

大部分时间我们都在同文本文件和源代码等打交道,但有时我们会把二进制文件放进我们的代码库中,这时处理那些不可避免的合并冲突并不像源代码那么容易。

假设你搭建了一个网站并且你为这个网站保留了一张图片在 Mercurial 的库中。最后有两个人同时试图去修改那个图片,于是产生了一个合并冲突。

为 Mercurial 设置不同的合并工具

在你的 ~/.hgrc 文件中,你应该添加以下段:

[merge-tools]
diff_images.args = $output $other

[merge-patterns]
**.png = diff_images

现在,创建一个 diff_images 的 shell 脚本,将其设置为可执行的,然后放到你的 $PATH 中去。我的像是这样:

open -a GraphicConverter $1 $2 -W
# opens the first and second parameter with GraphicConverter, waiting
# until same is quit before letting the shell continue.

现在如果一个合并包含了有 .png 文件的冲突都将会打开 GraphicConverter 。这将会打开两张图片:一张是现在在你的源码树上的,而另一张是来自 Mercurial 的。你能够区分出它们的不同,因为来自 Mercurial 的那一张在文件扩展名后面还跟有一串随机字符。例如,你的冲突文件名为 image.png , GraphicConverter 会打开两个窗口: images.pngimage.png~other.bQkQxd

手动的将新文件中的变更加到原来的文件中去 (image.png),做好后保存原来的那份并退出 GraphicConverter ,这样变更就会被提交了。

这个设置是怎么工作的

首先, diff_images.args 设置了两个参数传给图像处理工具:

  • $output 是 Mercurial 将会提交的文件,并且包含了第一个父亲的版本
  • $other 是你要合并的那个修订的版本

这里还有其他 .args 参数提供的选项:

  • $local$output 的一份拷贝,但是此文件的变更都会在合并时被忽略
  • $base 是出现文件内容冲突之前的正常修订中的文件

你可以使用这些来设置一个三路合并,如果需要的话,或是增强 diff_images 来向用户展示合并 之前 发生混乱的文件的内容。

接下来, [merge-patterns] 段表明了当一个文件名匹配上了指定的模式时应该使用哪个合并工具。

如果没有 merge-pattern 段的话, diff_images 会考虑一个 diff 候补,但这会被忽略掉因为 Mercurial 会认为 diff_images 没能力处理产生 diff 的二进制文件。向 [merge-patten] 添加行告诉 Mercurial diff_images 能够处理指定的文件类型。

代替加入 merge-patterns 段,你也可以添加一行内容,类似 diff_images.args ,告诉 Mercurial diff_images 能够处理好二进制文件: diff_images.binary = True

不管怎么说,这会让 diff_images 在 GraphicConverter 不能胜任的时候从 所有的 二进制 diff 工具中选一个候选者出来(比如,选择 GraphicConverter 对 mp3 进行 diff 可不是什么好主意)。

当发生非常糟糕的错误时:终止合并

合并 能够被终止时可以使用 hg revert 这一手段,当你尝试它后会得到:

$ hg revert --all
abort: uncommitted merge - please provide a specific revision

但你仅仅只是想清除掉你的合并工作并从擦除处再开始工作而已,那再使用 hg update --clean

设计 Mercurial 的 CLI

作者:Steve Losh
日期:2010-01-15

Mercurial 的命令行接口很不错,但是再做一小点改进的话能让它做的更好!

Mercurial 拥有一个很棒的命令行接口并且很多人觉得使用它就已足够不再需要什么 GUI 来管理它们的代码库了。不管怎么说,我们可以通过利用 Mercurial 的模板特性来让其做的更好。

在本贴士中我会把我用的一些模板贴出来并向你展示应该怎么使用它们。如果你想对在实际工作中怎样使用模板了解更多细节的话,请查阅 hg help templating

如果你喜欢你看到的这些的话,你可以通过从 BitBucket 上它们的 代码库 中克隆来获取我的模板:

hg clone http://bitbucket.org/sjl/mercurial-cli-templates/

Note

我对我的终端配色进行了自定义,所以对你来说配色看起来会不一样。如果你喜欢我使用的配色方案的话你可以读读我写的有关它的 文章

[TOC]

简短的记录

之前的贴士 中我讲述了怎样去创建一个 hg slog 别名命令,它对于计数变更集非常有用。用以正确的格式的话它在你的日常工作中也会变得很用。我的 hg slog 命令输出如下:

_images/slog.jpg

为了使用这个模板你要 编辑你的~/.hgrc文件 包含以下内容:

[alias]
slog = log --style=/full/path/to/map-cmdline.slog
漂亮的记录

短的记录可以很好的对之前的一些变更集做一个快速的回顾,但是对一个特定的变更集要了解更多的细节的话我创建了一个 hg nlog 别名命令,它看起来像这样:

_images/nlog.jpg

为了使用这个模板你要 编辑你的~/.hgrc文件 包含以下内容:

[alias]
nlog = log --style=/full/path/to/map-cmdline.nlog
简单的图志

命令 graphlog 对于回顾有分支的库的历史来说相当的完美,但是我们能够使用另一个模板让其更紧凑和易读。结构看起来像是这样:

_images/glog.jpg

为了使用这个模板你要 编辑你的~/.hgrc文件 包含以下内容:

[alias]
sglog = glog --style=/full/path/to/map-cmdline.sglog
贡献

如果你还有其他你觉得有用的模板,或是对我的有什么改进的话,请随意在 BitBucket 上的库中进行 fork !