现在的位置: 首页 > 综合 > 正文

Mercurial Queues (MQ) <二>

2013年09月22日 ⁄ 综合 ⁄ 共 10043字 ⁄ 字号 评论关闭

Getting started with Mercurial Queues 

Because MQ is implemented as an extension, you must explicitly enable before you can use it. (You don't need to download anything; MQ ships with the standard Mercurial
distribution.) To enable MQ, edit your ~/.hgrc file, and add the lines below. 

因为MQ是个插件,所以在你使用它之前确认它是能用的(不需用去下载任何东西;MQ和标准的Mercurial绑在一起)。为了激活MQ,编辑根目录下的.hgrc文件(~/.hgrc),添加下面一行:

[extensions]
hgext.mq =


Once the extension is enabled, it will make a number of new commands available. To verify that the extension is working, you can use hg help to
see if the qinit command is now available. 

当插件可以使用了,它会产生一些新的可用的命令。核实插件是否可以工作,可以用hg help去查看qinit命令是不是可用

$ hg help qinit
hg qinit [-c]

init a new queue repository

    The queue repository is unversioned by default. If -c is
    specified, qinit will create a separate nested repository
    for patches (qinit -c may also be run later to convert
    an unversioned patch repository into a versioned one).
    You can use qcommit to commit changes to this queue repository.

options:

 -c --create-repo  create queue repository

use "hg -v help qinit" to show global options


You can use MQ with any Mercurial repository, and its commands only operate within that repository. To get started, simply prepare
the repository using the qinit command. 

在任何Mercurial respository中都可以使用MQ,并且MQ的命令也只能在repository中操作。用qinit命令准备一下repository,然后开始接着开始。

$ hg init mq-sandbox
$ cd mq-sandbox
$ echo 'line 1' > file1
$ echo 'another line 1' > file2
$ hg add file1 file2
$ hg commit -m'first change'
$ hg qinit

This command creates an empty directory called .hg/patches, where MQ will keep its metadata. As with many Mercurial commands, the qinit command
prints nothing if it succeeds. No comments

qinit命令会创建一个名为“.hg/patches”的空目录,MQ保存其元数据。跟许多Mercurial命令一样,qinit命令操作成功后也不会打印任何东西。

Creating a new patch 创建新的patch

To begin work on a new patch, use the qnew command. This command takes one argument, the name of the patch to create. 2
comments

用qnew命令开始新的patch,这个命令有一个参数,要创建的patch的名字。

MQ will use this as the name of an actual file in the .hg/patches directory, as you can see below.No
comments

$ hg tip
changeset:   0:ba8df3126338
tag:         tip
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Tue May 05 06:55:41 2009 +0000
summary:     first change

$ hg qnew first.patch
$ hg tip
changeset:   1:0eef7631d242
tag:         qtip
tag:         first.patch
tag:         tip
tag:         qbase
user:        Bryan O'Sullivan <bos@serpentine.com>
date:        Tue May 05 06:55:41 2009 +0000
summary:     [mq]: first.patch

$ ls .hg/patches
first.patch  series  status

No comments

Also newly present in the .hg/patches directory are two other files, series and status. The seriesfile
lists all of the patches that MQ knows about for this repository, with one patch per line. Mercurial uses the status file for internal book-keeping; it tracks all of the patches that MQ hasapplied in
this repository. 1 comment

.hg/patches目录新产生了两个其他文件,series和status。series文件列出了所有MQ所知道的在这个repository中的patch,一行一个patch。Mercurial用status文件做内部的保存序列;它跟踪所有的已经在这个repository中应用的patch。

[Note] Note

You may sometimes want to edit the series file by hand; for example, to change the sequence in which some patches are applied. However, manually editing the status file
is almost always a bad idea, as it's easy to corrupt MQ's idea of what is happening. 3 comments

你可能有时候想去编辑series文件;例如,去改变一些已经被应用的patch的序列.然而,通常编辑status文件一直都是不好的想法,很容易造成冲突。

Once you have created your new patch, you can edit files in the working directory as you usually would. All of the normal Mercurial commands, such as hg diff and hg
annotate
, work exactly as they did before. 

在你创建新的patch之后,你当然可以像以前一样编辑工作目录下的文件,所有的Mercurial命令,如hg diff和 hg annotate都可以用

Refreshing a patch

When you reach a point where you want to save your work, use the qrefresh command to update the patch you are working on. 

当你想去保存你的工作时,用qrefresh命令去更新你正在工作的patch。

$ echo 'line 2' >> file1
$ hg diff
diff -r 0eef7631d242 file1
--- a/file1	Tue May 05 06:55:41 2009 +0000
+++ b/file1	Tue May 05 06:55:41 2009 +0000
@@ -1,1 +1,2 @@
 line 1
+line 2
$ hg qrefresh
$ hg diff
$ hg tip --style=compact --patch
1[qtip,first.patch,tip,qbase]   b737e7b1c206   2009-05-05 06:55 +0000   bos
  [mq]: first.patch

diff -r ba8df3126338 -r b737e7b1c206 file1
--- a/file1	Tue May 05 06:55:41 2009 +0000
+++ b/file1	Tue May 05 06:55:41 2009 +0000
@@ -1,1 +1,2 @@
 line 1
+line 2

No comments

This command folds the changes you have made in the working directory into your patch, and updates its corresponding changeset to contain those changes. No
comments

这个qrefresh命令把你在工作目录做的改变折叠地存放到你当前工作的patch中,并更新他相应的changeset以包含这些改变。

You can run qrefresh as often as you like, so it's a good way to “checkpoint” your work. Refresh your patch at an opportune time;
try an experiment; and if the experiment doesn't work out, hg revert your modifications back to the last time you refreshed. 

$ echo 'line 3' >> file1
$ hg status
M file1
$ hg qrefresh
$ hg tip --style=compact --patch
1[qtip,first.patch,tip,qbase]   a2efdba241e8   2009-05-05 06:55 +0000   bos
  [mq]: first.patch

diff -r ba8df3126338 -r a2efdba241e8 file1
--- a/file1	Tue May 05 06:55:41 2009 +0000
+++ b/file1	Tue May 05 06:55:42 2009 +0000
@@ -1,1 +1,3 @@
 line 1
+line 2
+line 3

No comments

Stacking and tracking patches

Once you have finished working on a patch, or need to work on another, you can use the qnewcommand again to create a new patch. Mercurial will apply this
patch on top of your existing patch. 

当你完成了在一个patch上的工作或者需要去在另外一个patch上工作,再用qnew命令去创建一个新的patch。Mercurial将把这个patch放到已经存在的patch的顶端。

$ hg qnew second.patch
$ hg log --style=compact --limit=2
2[qtip,second.patch,tip]   4bb84cd8876a   2009-05-05 06:55 +0000   bos
  [mq]: second.patch

1[first.patch,qbase]   a2efdba241e8   2009-05-05 06:55 +0000   bos
  [mq]: first.patch

$ echo 'line 4' >> file1
$ hg qrefresh
$ hg tip --style=compact --patch
2[qtip,second.patch,tip]   8287e9f12f96   2009-05-05 06:55 +0000   bos
  [mq]: second.patch

diff -r a2efdba241e8 -r 8287e9f12f96 file1
--- a/file1	Tue May 05 06:55:42 2009 +0000
+++ b/file1	Tue May 05 06:55:42 2009 +0000
@@ -1,3 +1,4 @@
 line 1
 line 2
 line 3
+line 4

$ hg annotate file1
0: line 1
1: line 2
1: line 3
2: line 4

No comments

Notice that the patch contains the changes in our prior patch as part of its context (you can see this more clearly in the output of hg annotate). 

注意:这个patch包含了我们先前的patch中做的那些修改(可以通过hg annotate命令查看更详细的内容)

So far, with the exception of qnew and qrefresh, we've been careful to only use regular Mercurial commands.
However, MQ provides many commands that are easier to use when you are thinking about patches, as illustrated below. No comments

$ hg qseries
first.patch
second.patch
$ hg qapplied
first.patch
second.patch

No comments

  • The qseries command lists every patch that MQ knows about in this repository, from oldest to newest (most recently created). No
    comments

    qseries命令列出MQ所知道的在这个respository中的每个patch,从最旧的到最新的。

  • The qapplied command lists every patch that MQ has applied in this repository, again from oldest to newest (most recently applied). No
    comments

    qapplied命令列出了MQ所应用的在这个respository中的每个patch,从最旧的到最新的。

Manipulating the patch stack

The previous discussion implied that there must be a difference between “known” and “applied” patches, and there is. MQ can manage a patch without
it being applied in the repository. No comments

前面的讨论暗示"known"和"applied"patch一定有一些不一样,确实,MQ能够管理一个还没有应用到repository中的patch。很强大是吧。

An applied patch has a corresponding changeset in the repository, and the effects of the patch and changeset are visible in the working directory. You can undo the
application of a patch using the qpop command. MQ still knows about, or manages, a popped patch, but the patch no longer has a corresponding changeset in the repository, and
the working directory does not contain the changes made by the patch. Figure 12.1,
“Applied and unapplied patches in the MQ patch stack”
illustrates the difference between applied and tracked patches. 

一个applied patch在repository中有一个相应的changeset, patch和changeset的作用很明显。你可以用qpop命令取消程序的patch。MQ仍然知道或者说管理一个已经卸载的patch,但是这个patch在repository中不再有相应的changeset.工作目录中也不包含在这个patch中做的修改。下图展示了applied patch和tracked patch的不同。

Figure 12.1. Applied and unapplied patches in the MQ patch stack

XXX add text


You can reapply an unapplied, or popped, patch using the qpush command. This creates a new changeset to correspond to the patch, and the patch's changes once
again become present in the working directory. See below for examples of qpop and qpush in action. 1
comment

你可以用qpush命令重新应用一个没有被应用的或者是已经卸载的patch,这将创建一个新的changeset对应这个patch,patch中的修改也将在此显示在工作目录中。看下面关于qpop和qpush的例子。

$ hg qapplied
first.patch
second.patch
$ hg qpop
now at: first.patch
$ hg qseries
first.patch
second.patch
$ hg qapplied
first.patch
$ cat file1
line 1
line 2
line 3

No comments

Notice that once we have popped a patch or two patches, the output of qseries remains the same, while that of qapplied has
changed. No comments

注意,当我们卸载掉一个patch或者两个patch时,qseries的输出是一样的,但是qapplied的输出会有些改变,卸载掉的patch将会消失。

Pushing and popping many patches

While qpush and qpop each operate on a single patch at a time by default, you can push and pop many patches
in one go. The hg -a option to qpush causes it to push all unapplied patches, while the -a option to qpop causes
it to pop all applied patches. (For some more ways to push and pop many patches, see the section called
“Getting the best performance out of MQ”
 below.) 

默认地,qpush和qpop一次只能操作一个单一的patch,你可以一次push和pop多个patch。qpush命令后加上-a选项能push所有未被应用的patch,qpop加上-a选项能pop掉所有已经应用的patch。

$ hg qpush -a
applying second.patch
now at: second.patch
$ cat file1
line 1
line 2
line 3
line 4

No comments

Safety checks, and overriding them  

Several MQ commands check the working directory before they do anything, and fail if they find any modifications. They do this to ensure that you won't lose any changes that you have made, but not yet incorporated into a patch.
The example below illustrates this; the qnew command will not create a new patch if there are outstanding changes, caused in this case by the hg add of file3

一些MQ命令在执行之前会检查工作目录,如果发现有任何的改动,执行结果会失败。做这些是为了确保你不会扔掉任何你已经做的改变,但是也不会合并到一个patch里。下面的例子显示了这一点;如果有一些没有解决的changes,qnew命令不会创建新的patch,是因为没有用hg add增加file3文件。

$ echo 'file 3, line 1' >> file3
$ hg qnew add-file3.patch
$ hg qnew -f add-file3.patch
abort: patch "add-file3.patch" already exists

No comments

Commands that check the working directory all take an “I know what I'm doing” option, which is always named -f. The exact meaning of -f depends
on the command. For example, hg qnew hg -f will incorporate any outstanding changes into the new patch it creates, but hg qpop hg
-f
 will revert modifications to any files affected by the patch that it is popping. Be sure to read the documentation for a command's -f option before you use it! 2
comments

Working on several patches at once

The qrefresh command always refreshes the topmost applied patch. This means that you can suspend work on one patch (by refreshing it), pop
or push to make a different patch the top, and work on that patch for a while. No comments

qrefresh命令总refresh最顶端被应用的patch。这意味着你可以将正在工作的patch,pop或者push去使得不同的patch作为顶端patch,然后在这个patch上做操作。

Here's an example that illustrates how you can use this ability. Let's say you're developing a new feature as two patches. The first is a change to the core of your software, and the second—layered on top of the first—changes
the user interface to use the code you just added to the core. If you notice a bug in the core while you're working on the UI patch, it's easy to fix the core. Simply qrefresh the UI patch to save your in-progress
changes, and qpop down to the core patch. Fix the core bug, qrefresh the core patch, and qpush back to the UI patch to
continue where you left off. 2 comments

抱歉!评论已关闭.