Mercurial_ The Definitive Guide - Bryan O'Sullivan [104]
$ hg qpop -a
patch queue now empty
$ hg qselect
no active guards
$ hg qselect foo
number of unguarded, unapplied patches has changed from 1 to 2
$ hg qselect
foo
In case you’re interested, the currently selected guards are stored in the guards file.
$ cat .hg/patches/guards
foo
We can see the effect the selected guards have when we run qpush.
$ hg qpush -a
applying hello.patch
applying goodbye.patch
now at: goodbye.patch
A guard cannot start with a + or - character. The name of a guard must not contain whitespace, but most other characters are acceptable. If you try to use a guard with an invalid name, MQ will complain:
$ hg qselect +foo
abort: guard '+foo' starts with invalid character: '+'
Changing the selected guards changes the patches that are applied.
$ hg qselect quux
number of guarded, applied patches has changed from 0 to 2
$ hg qpop -a
patch queue now empty
$ hg qpush -a
patch series already fully applied
You can see in the example below that negative guards take precedence over positive guards.
$ hg qselect foo bar
number of unguarded, unapplied patches has changed from 0 to 2
$ hg qpop -a
no patches applied
$ hg qpush -a
applying hello.patch
applying goodbye.patch
now at: goodbye.patch
MQ’s Rules for Applying Patches
The rules that MQ uses when deciding whether to apply a patch are as follows:
A patch that has no guards is always applied.
If the patch has any negative guard that matches any currently selected guard, the patch is skipped.
If the patch has any positive guard that matches any currently selected guard, the patch is applied.
If the patch has positive or negative guards, but none matches any currently selected guard, the patch is skipped.
Trimming the Work Environment
In working on the device driver I mentioned earlier, I don’t apply the patches to a normal Linux kernel tree. Instead, I use a repository that contains only a snapshot of the source files and headers that are relevant to Infiniband development. This repository is 1% of the size of a kernel repository, so it’s easier to work with.
I then choose a “base” version on top of which the patches are applied. This is a snapshot of the Linux kernel tree as of a revision of my choosing. When I take the snapshot, I record the changeset ID from the kernel repository in the commit message. Since the snapshot preserves the “shape” and content of the relevant parts of the kernel tree, I can apply my patches on top of either my tiny repository or a normal kernel tree.
Normally, the base tree atop which the patches apply should be a snapshot of a very recent upstream tree. This best facilitates the development of patches that can easily be submitted upstream with few or no modifications.
Dividing Up the Series File
I categorize the patches in the series file into a number of logical groups. Each section of like patches begins with a block of comments that describes the purpose of the patches that follow.
The sequence of patch groups that I maintain follows. The ordering of these groups is important; I’ll describe why after I introduce the groups.
The “accepted” group. Patches that the development team has submitted to the maintainer of the Infiniband subsystem and that he has accepted, but that are not present in the snapshot that the tiny repository is based on. These are “read only” patches, present only to transform the tree into a similar state as it is in the upstream maintainer’s repository.
The “rework” group. Patches that I have submitted, but that the upstream maintainer has requested modifications to before he will accept them.
The “pending” group. Patches that I have not yet submitted to the upstream maintainer, but that we have finished working on. These will be “read only” for a while. If the upstream maintainer accepts them upon submission, I’ll move them to the end of the “accepted” group. If he requests that I modify any, I’ll