Using Mercurial Queues Extension

The "merge heads" problem

If you're using Mercurial revision control system for your source repository along with a couple of other developers, you're probably familiar with the following situation. You have developed your changeset and committed into your clone, being ready to push. If you're considerate, you run hg incoming to check there are no new changesets in the parent repository, sometimes just to find out someone pushed a new changeset a minute ago. If you push without checking incoming, you're creating two heads in the parent repository, which someone has to merge (the usual changeset comment being "merge heads"). This is one situation where Mercurial patch queue is very useful.

Developing multiple changesets at once

Another situation, where Mercurial patch queues are handy is when you're working on a number of different changesets at once and you don't want to create a different repository clone for each of them (consider a repository of several gigabytes and small changesets).

Mercurial patch queue allows to manage all your work-in-progress changesets aside from your clone's work directory. Actually, the patches are stored in ./hg/patches of your clone and can be selectively applied and unapplied.

Using the patch queue extension

Not to duplicate information available elsewhere, I suggest you to have a look at the Mercurial Queues Extension page. There's also a quick example on the MqTutorial page. You can see that it's relatively straightforward.

Following image is trying to demonstrate the flexibility of the patch queue. You can maintain patches X and Y aside from the committed revisions in your clone, typically updating your clone by:

$ hg qpop -a
$ hg pull -u
$ hg qpush; hg qpush

Mq schema


Tips & tricks

Converting the patch to a changeset

When your patch is ready to be committed as a revision, you should check and modify the revision comment by:

$ hg qref -m "revision comment"

and then you can commit the patch by:

$ hg qdel -r <patch_name>

Note that you're actually deleting the patch (which is correct), but the -r option is very important here as it makes the new revision from it (without it the patch will be deleted, but not committed!). 

Working with binary files

If you commit binary files to your repository, using patch queue will fail with the default [diff] settings. You need to add the following to your ~/.hgrc file:

[diff]
# prevent qrefresh from updating timestamps
nodates=1
# force all patches to always be in git format
git=1

Queue tags and useful aliases

As you may have noticed, applied patches are marked with various tags like qparent (last revision you pulled), qbase (first patch applied), qtip (last patch applied). These can be used with advantage to create a couple of useful macros in the [alias] section of ~/.hgrc.

[alias]
# show files affected by all applied patches
qpstatus = status --rev qparent
# show diff for all applied patches
qpdiff = diff --rev qparent
# show revision history since qparent (last pulled revision)
qlog = log -r qtip:qparent

Altering patch order in the queue

Sometimes you may want to modify the order in which the patches are applied. This can be done by simple qpoping all patches and modifying the .hg/patches/series file in your clone.


Comments:

Another useful shell alias:
alias viq='vim `hg root`/.hg/patches/'

Posted by David Wolever on January 26, 2010 at 11:55 AM CET #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Solaris l10n & i18n, locales, keyboards, fonts and related topics.

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today