Mercurial_ The Definitive Guide - Bryan O'Sullivan [94]
Figure 12-1. Applied and unapplied patches in the MQ patch stack
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.
$ 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
Notice that once we have popped a patch or two patches, the output of qseries remains the same, while that of qapplied has changed.
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 Getting the Best Performance Out of MQ.)
$ hg qpush -a
applying second.patch
now at: second.patch
$ cat file1
line 1
line 2
line 3
line 4
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.
$ echo 'file 3, line 1' >> file3
$ hg qnew add-file3.patch
$ hg qnew -f add-file3.patch
abort: patch "add-file3.patch" already exists
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!
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.
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.
More About Patches
MQ uses the GNU patch command to apply patches, so it’s helpful to know a few more detailed aspects of how patch works, and about patches themselves.
The Strip Count
If you look at the file headers in a patch, you will notice that the pathnames usually have an extra component on the front that isn’t present in the actual pathname. This is a holdover from the way that people used to generate patches (people still do this, but it’s somewhat rare with modern revision control tools).
Alice would unpack a tarball, edit her files, then decide that she wanted to create a patch. So she’d rename her working directory, unpack the tarball again (hence the need for the rename), and use the -r and -N options to diff to recursively generate a patch between the unmodified directory and the modified one. The result would be that the name of