Online Book Reader

Home Category

Mercurial_ The Definitive Guide - Bryan O'Sullivan [103]

By Root 902 0
the driver from compiling.

The second is to maintain a single source tree filled with conditional statements that turn chunks of code on or off depending on the intended target. Because these “ifdefs” are not allowed in the Linux kernel tree, a manual or automatic process must be followed to strip them out and yield a clean tree. A code base maintained in this fashion rapidly becomes a rat’s nest of conditional blocks that are difficult to understand and maintain.

Neither of these approaches is well suited to a situation where you don’t “own” the canonical copy of a source tree. In the case of a Linux driver that is distributed with the standard kernel, Linus’s tree contains the copy of the code that will be treated by the world as canonical. The upstream version of “my” driver can be modified by people I don’t know, without me even finding out about it until after the changes show up in Linus’s tree.

These approaches have the added weakness of making it difficult to generate well-formed patches to submit upstream.

In principle, Mercurial Queues seems like a good candidate to manage a development scenario such as the above. While this is indeed the case, MQ contains a few added features that make the job more pleasant.

Conditionally Applying Patches with Guards

Perhaps the best way to maintain sanity with so many targets is to be able to choose specific patches to apply for a given situation. MQ provides a feature called “guards” (which originated from quilt’s guards command) that does just this. To start off, let’s create a simple repository for experimenting in.

$ hg qinit

$ hg qnew hello.patch

$ echo hello > hello

$ hg add hello

$ hg qrefresh

$ hg qnew goodbye.patch

$ echo goodbye > goodbye

$ hg add goodbye

$ hg qrefresh

This gives us a tiny repository that contains two patches that don’t have any dependencies on each other, because they touch different files.

The idea behind conditional application is that you can “tag” a patch with a guard, which is simply a text string of your choosing, then tell MQ to select specific guards to use when applying patches. MQ will then either apply, or skip over, a guarded patch, depending on the guards that you have selected.

A patch can have an arbitrary number of guards; each one is positive (“apply this patch if this guard is selected”) or negative (“skip this patch if this guard is selected”). A patch with no guards is always applied.

Controlling the Guards on a Patch

The qguard command lets you determine which guards should apply to a patch, or display the guards that are already in effect. Without any arguments, it displays the guards on the current topmost patch.

$ hg qguard

goodbye.patch: unguarded

To set a positive guard on a patch, prefix the name of the guard with +.

$ hg qguard +foo

$ hg qguard

goodbye.patch: +foo

To set a negative guard on a patch, prefix the name of the guard with -.

$ hg qguard -- hello.patch -quux

$ hg qguard hello.patch

hello.patch: -quux

Notice that we prefixed the arguments to the hg + qguard command with a -- here, so that Mercurial would not interpret the text -quux as an option.

* * *

Setting versus modifying


The qguard command sets the guards on a patch; it doesn’t modify them. What this means is that if you run hg qguard +a +b on a patch, then hg qguard +c on the same patch, the only guard that will be set on it afterwards is +c.

* * *

Mercurial stores guards in the series file; the form in which they are stored is easy both to understand and to edit by hand. (In other words, you don’t have to use the qguard command if you don’t want to; it’s okay to simply edit the series file.)

$ cat .hg/patches/series

hello.patch #-quux

goodbye.patch #+foo

Selecting the Guards to Use

The qselect command determines which guards are active at a given time. The effect of this is to determine which patches MQ will apply the next time you run qpush. It has no other effect; in particular, it doesn’t do anything to patches that are already applied.

With no arguments, the qselect

Return Main Page Previous Page Next Page

®Online Book Reader