bos@558: bos@558: dongsheng@625: bos@572: bos@558: Managing change with Mercurial Queues bos@558: dongsheng@625: bos@558: The patch management problem bos@558: bos@558: Here is a common scenario: you need to install a software bos@558: package from source, but you find a bug that you must fix in the bos@558: source before you can start using the package. You make your bos@558: changes, forget about the package for a while, and a few months bos@558: later you need to upgrade to a newer version of the package. If bos@558: the newer version of the package still has the bug, you must bos@558: extract your fix from the older source tree and apply it against bos@558: the newer version. This is a tedious task, and it's easy to bos@558: make mistakes. bos@558: bos@558: This is a simple case of the patch management bos@558: problem. You have an upstream source tree that bos@558: you can't change; you need to make some local changes on top of bos@558: the upstream tree; and you'd like to be able to keep those bos@558: changes separate, so that you can apply them to newer versions bos@558: of the upstream source. bos@558: bos@558: The patch management problem arises in many situations. bos@558: Probably the most visible is that a user of an open source bos@558: software project will contribute a bug fix or new feature to the bos@558: project's maintainers in the form of a patch. bos@558: bos@558: Distributors of operating systems that include open source bos@558: software often need to make changes to the packages they bos@558: distribute so that they will build properly in their bos@558: environments. bos@558: bos@558: When you have few changes to maintain, it is easy to manage bos@558: a single patch using the standard diff and bos@558: patch programs (see section for a discussion of these bos@559: tools). Once the number of changes grows, it starts to make bos@559: sense to maintain patches as discrete chunks of bos@559: work, so that for example a single patch will contain bos@559: only one bug fix (the patch might modify several files, but it's bos@559: doing only one thing), and you may have a number bos@559: of such patches for different bugs you need fixed and local bos@559: changes you require. In this situation, if you submit a bug fix bos@559: patch to the upstream maintainers of a package and they include bos@559: your fix in a subsequent release, you can simply drop that bos@559: single patch when you're updating to the newer release. bos@558: bos@558: Maintaining a single patch against an upstream tree is a bos@558: little tedious and error-prone, but not difficult. However, the bos@558: complexity of the problem grows rapidly as the number of patches bos@558: you have to maintain increases. With more than a tiny number of bos@558: patches in hand, understanding which ones you have applied and bos@558: maintaining them moves from messy to overwhelming. bos@558: bos@558: Fortunately, Mercurial includes a powerful extension, bos@558: Mercurial Queues (or simply MQ), that massively bos@558: simplifies the patch management problem. bos@558: bos@558: dongsheng@625: bos@558: The prehistory of Mercurial Queues bos@558: bos@558: During the late 1990s, several Linux kernel developers bos@558: started to maintain patch series that modified bos@558: the behaviour of the Linux kernel. Some of these series were bos@558: focused on stability, some on feature coverage, and others were bos@558: more speculative. bos@558: bos@558: The sizes of these patch series grew rapidly. In 2002, bos@558: Andrew Morton published some shell scripts he had been using to bos@558: automate the task of managing his patch queues. Andrew was bos@558: successfully using these scripts to manage hundreds (sometimes bos@558: thousands) of patches on top of the Linux kernel. bos@558: dongsheng@625: bos@558: A patchwork quilt bos@558: bos@558: In early 2003, Andreas Gruenbacher and Martin Quinson bos@558: borrowed the approach of Andrew's scripts and published a tool bos@558: called patchwork quilt bos@558: web:quilt, or simply quilt bos@558: (see gruenbacher:2005 for a paper bos@558: describing it). Because quilt substantially automated patch bos@558: management, it rapidly gained a large following among open bos@558: source software developers. bos@558: bos@558: Quilt manages a stack of patches on bos@558: top of a directory tree. To begin, you tell quilt to manage a bos@558: directory tree, and tell it which files you want to manage; it bos@558: stores away the names and contents of those files. To fix a bos@558: bug, you create a new patch (using a single command), edit the bos@558: files you need to fix, then refresh the bos@558: patch. bos@558: bos@558: The refresh step causes quilt to scan the directory tree; bos@558: it updates the patch with all of the changes you have made. bos@558: You can create another patch on top of the first, which will bos@558: track the changes required to modify the tree from tree bos@558: with one patch applied to tree with two bos@558: patches applied. bos@558: bos@558: You can change which patches are bos@558: applied to the tree. If you pop a patch, the bos@558: changes made by that patch will vanish from the directory bos@558: tree. Quilt remembers which patches you have popped, though, bos@558: so you can push a popped patch again, and the bos@558: directory tree will be restored to contain the modifications bos@558: in the patch. Most importantly, you can run the bos@558: refresh command at any time, and the topmost bos@558: applied patch will be updated. This means that you can, at bos@558: any time, change both which patches are applied and what bos@558: modifications those patches make. bos@558: bos@558: Quilt knows nothing about revision control tools, so it bos@558: works equally well on top of an unpacked tarball or a bos@558: Subversion working copy. bos@558: bos@558: dongsheng@625: bos@558: From patchwork quilt to Mercurial Queues bos@558: bos@558: In mid-2005, Chris Mason took the features of quilt and bos@558: wrote an extension that he called Mercurial Queues, which bos@558: added quilt-like behaviour to Mercurial. bos@558: bos@558: The key difference between quilt and MQ is that quilt bos@558: knows nothing about revision control systems, while MQ is bos@558: integrated into Mercurial. Each patch bos@558: that you push is represented as a Mercurial changeset. Pop a bos@558: patch, and the changeset goes away. bos@558: bos@558: Because quilt does not care about revision control tools, bos@558: it is still a tremendously useful piece of software to know bos@558: about for situations where you cannot use Mercurial and bos@558: MQ. bos@558: bos@558: bos@558: bos@558: bos@558: The huge advantage of MQ bos@558: bos@558: I cannot overstate the value that MQ offers through the bos@558: unification of patches and revision control. bos@558: bos@558: A major reason that patches have persisted in the free bos@559: software and open source world&emdash;in spite of the bos@559: availability of increasingly capable revision control tools over bos@559: the years&emdash;is the agility they bos@559: offer. bos@558: bos@558: Traditional revision control tools make a permanent, bos@558: irreversible record of everything that you do. While this has bos@558: great value, it's also somewhat stifling. If you want to bos@558: perform a wild-eyed experiment, you have to be careful in how bos@558: you go about it, or you risk leaving unneeded&emdash;or worse, bos@559: misleading or destabilising&emdash;traces of your missteps and bos@559: errors in the permanent revision record. bos@558: bos@558: By contrast, MQ's marriage of distributed revision control bos@558: with patches makes it much easier to isolate your work. Your bos@558: patches live on top of normal revision history, and you can make bos@558: them disappear or reappear at will. If you don't like a patch, bos@558: you can drop it. If a patch isn't quite as you want it to be, bos@559: simply fix it&emdash;as many times as you need to, until you bos@559: have refined it into the form you desire. bos@558: bos@558: As an example, the integration of patches with revision bos@558: control makes understanding patches and debugging their bos@558: effects&emdash;and their interplay with the code they're based bos@559: on&emdash;enormously easier. Since every bos@559: applied patch has an associated changeset, you can give hg log a file name to see which bos@559: changesets and patches affected the file. You can use the bos@559: hg bisect command to bos@559: binary-search through all changesets and applied patches to see bos@559: where a bug got introduced or fixed. You can use the hg annotate command to see which bos@558: changeset or patch modified a particular line of a source file. bos@558: And so on. bos@558: bos@558: dongsheng@625: bos@558: Understanding patches bos@558: bos@558: Because MQ doesn't hide its patch-oriented nature, it is bos@558: helpful to understand what patches are, and a little about the bos@558: tools that work with them. bos@558: bos@558: The traditional Unix diff command bos@558: compares two files, and prints a list of differences between bos@558: them. The patch command understands these bos@558: differences as modifications to make to a bos@558: file. Take a look below for a simple example of these commands bos@558: in action. bos@558: bos@567: &interaction.mq.dodiff.diff; bos@558: bos@558: The type of file that diff generates (and bos@558: patch takes as input) is called a bos@558: patch or a diff; there is no bos@558: difference between a patch and a diff. (We'll use the term bos@558: patch, since it's more commonly used.) bos@558: bos@558: A patch file can start with arbitrary text; the bos@558: patch command ignores this text, but MQ uses bos@558: it as the commit message when creating changesets. To find the bos@558: beginning of the patch content, patch bos@558: searches for the first line that starts with the string bos@558: diff -. bos@558: bos@558: MQ works with unified diffs bos@558: (patch can accept several other diff formats, bos@558: but MQ doesn't). A unified diff contains two kinds of header. bos@558: The file header describes the file being bos@558: modified; it contains the name of the file to modify. When bos@558: patch sees a new file header, it looks for a bos@558: file with that name to start modifying. bos@558: bos@558: After the file header comes a series of bos@558: hunks. Each hunk starts with a header; bos@558: this identifies the range of line numbers within the file that bos@558: the hunk should modify. Following the header, a hunk starts and bos@558: ends with a few (usually three) lines of text from the bos@558: unmodified file; these are called the bos@558: context for the hunk. If there's only a bos@558: small amount of context between successive hunks, bos@558: diff doesn't print a new hunk header; it just bos@558: runs the hunks together, with a few lines of context between bos@558: modifications. bos@558: bos@558: Each line of context begins with a space character. Within bos@558: the hunk, a line that begins with bos@558: - means remove this bos@558: line, while a line that begins with bos@558: + means insert this bos@558: line. For example, a line that is modified is bos@558: represented by one deletion and one insertion. bos@558: bos@558: We will return to some of the more subtle aspects of patches dongsheng@625: later (in section ), but you bos@559: should have bos@559: enough information now to use MQ. bos@558: bos@558: dongsheng@625: bos@558: Getting started with Mercurial Queues bos@558: bos@558: Because MQ is implemented as an extension, you must bos@558: explicitly enable before you can use it. (You don't need to bos@558: download anything; MQ ships with the standard Mercurial bos@559: distribution.) To enable MQ, edit your ~/.hgrc file, and add the lines bos@559: below. bos@558: bos@558: [extensions] hgext.mq = bos@558: bos@558: Once the extension is enabled, it will make a number of new bos@558: commands available. To verify that the extension is working, bos@558: you can use hg help to see if bos@559: the qinit command is now bos@558: available. bos@558: bos@567: &interaction.mq.qinit-help.help; bos@558: bos@558: You can use MQ with any Mercurial bos@558: repository, and its commands only operate within that bos@558: repository. To get started, simply prepare the repository using bos@559: the qinit command. bos@559: bos@567: &interaction.mq.tutorial.qinit; bos@559: bos@559: This command creates an empty directory called .hg/patches, where bos@558: MQ will keep its metadata. As with many Mercurial commands, the bos@559: qinit command prints nothing bos@558: if it succeeds. bos@558: bos@558: bos@558: Creating a new patch bos@558: bos@558: To begin work on a new patch, use the qnew command. This command takes bos@559: one argument, the name of the patch to create. bos@559: bos@559: MQ will use this as the name of an actual file in the bos@559: .hg/patches directory, as you bos@559: can see below. bos@559: bos@567: &interaction.mq.tutorial.qnew; bos@558: bos@558: Also newly present in the .hg/patches directory are two bos@558: other files, series and bos@558: status. The series file lists all of the bos@558: patches that MQ knows about for this repository, with one bos@558: patch per line. Mercurial uses the status file for internal bos@558: book-keeping; it tracks all of the patches that MQ has bos@558: applied in this repository. bos@558: bos@558: bos@558: You may sometimes want to edit the series file by hand; for bos@558: example, to change the sequence in which some patches are bos@558: applied. However, manually editing the status file is almost always a bos@558: bad idea, as it's easy to corrupt MQ's idea of what is bos@558: happening. bos@558: bos@558: bos@558: Once you have created your new patch, you can edit files bos@558: in the working directory as you usually would. All of the bos@558: normal Mercurial commands, such as hg bos@558: diff and hg bos@558: annotate, work exactly as they did before. bos@558: bos@558: bos@558: bos@558: Refreshing a patch bos@558: bos@558: When you reach a point where you want to save your work, bos@559: use the qrefresh command bos@559: to update the patch you are working on. bos@558: bos@567: &interaction.mq.tutorial.qrefresh; bos@558: bos@559: This command folds the changes you have made in the bos@559: working directory into your patch, and updates its bos@559: corresponding changeset to contain those changes. bos@559: bos@559: You can run qrefresh bos@559: as often as you like, so it's a good way to bos@559: checkpoint your work. Refresh your patch at an bos@559: opportune time; try an experiment; and if the experiment bos@558: doesn't work out, hg revert bos@558: your modifications back to the last time you refreshed. bos@558: bos@567: &interaction.mq.tutorial.qrefresh2; bos@558: bos@558: bos@558: bos@558: Stacking and tracking patches bos@558: bos@558: Once you have finished working on a patch, or need to work bos@559: on another, you can use the qnew command again to create a bos@559: new patch. Mercurial will apply this patch on top of your bos@559: existing patch. bos@559: bos@567: &interaction.mq.tutorial.qnew2; bos@559: Notice that the patch contains the changes in our prior bos@559: patch as part of its context (you can see this more clearly in bos@559: the output of hg bos@558: annotate). bos@558: bos@558: So far, with the exception of qnew and qrefresh, we've been careful to bos@558: only use regular Mercurial commands. However, MQ provides bos@558: many commands that are easier to use when you are thinking bos@559: about patches, as illustrated below. bos@559: bos@567: &interaction.mq.tutorial.qseries; bos@558: bos@558: bos@558: The qseries command lists every bos@558: patch that MQ knows about in this repository, from oldest bos@558: to newest (most recently bos@559: created). bos@559: bos@558: The qapplied command lists every bos@558: patch that MQ has applied in this bos@558: repository, again from oldest to newest (most recently bos@559: applied). bos@559: bos@558: bos@558: bos@558: bos@558: Manipulating the patch stack bos@558: bos@558: The previous discussion implied that there must be a bos@558: difference between known and bos@558: applied patches, and there is. MQ can manage a bos@558: patch without it being applied in the repository. bos@558: bos@558: An applied patch has a corresponding bos@558: changeset in the repository, and the effects of the patch and bos@558: changeset are visible in the working directory. You can undo bos@558: the application of a patch using the qpop command. MQ still bos@558: knows about, or manages, a popped patch, bos@558: but the patch no longer has a corresponding changeset in the bos@558: repository, and the working directory does not contain the bos@558: changes made by the patch. Figure illustrates bos@559: the difference between applied and tracked patches. bos@558: dongsheng@625: bos@559: XXX bos@559: add textApplied and bos@559: unapplied patches in the MQ patch bos@559: stack bos@558: bos@558: bos@558: You can reapply an unapplied, or popped, patch using the bos@559: qpush command. This bos@558: creates a new changeset to correspond to the patch, and the bos@558: patch's changes once again become present in the working bos@559: directory. See below for examples of qpop and qpush in action. bos@567: &interaction.mq.tutorial.qpop; bos@558: bos@559: Notice that once we have popped a patch or two patches, bos@559: the output of qseries bos@559: remains the same, while that of qapplied has changed. bos@559: bos@559: bos@558: bos@558: bos@558: Pushing and popping many patches bos@558: bos@559: While qpush and bos@559: qpop each operate on a bos@558: single patch at a time by default, you can push and pop many bos@558: patches in one go. The option to bos@559: qpush causes it to push bos@558: all unapplied patches, while the option to qpop causes it to pop all applied bos@558: patches. (For some more ways to push and pop many patches, dongsheng@625: see section bos@559: below.) bos@558: bos@567: &interaction.mq.tutorial.qpush-a; bos@558: bos@558: bos@558: bos@558: Safety checks, and overriding them bos@558: bos@558: Several MQ commands check the working directory before bos@558: they do anything, and fail if they find any modifications. bos@558: They do this to ensure that you won't lose any changes that bos@559: you have made, but not yet incorporated into a patch. The bos@559: example below illustrates this; the qnew command will not create a bos@558: new patch if there are outstanding changes, caused in this bos@558: case by the hg add of bos@558: file3. bos@558: bos@567: &interaction.mq.tutorial.add; bos@558: bos@558: Commands that check the working directory all take an bos@558: I know what I'm doing option, which is always bos@558: named . The exact meaning of bos@558: depends on the command. For example, bos@558: hg qnew bos@559: will incorporate any outstanding changes into the new patch it bos@558: creates, but hg qpop bos@559: will revert modifications to any files affected by the patch bos@559: that it is popping. Be sure to read the documentation for a bos@558: command's option before you use it! bos@558: bos@558: bos@558: bos@558: Working on several patches at once bos@558: bos@559: The qrefresh command bos@558: always refreshes the topmost applied bos@558: patch. This means that you can suspend work on one patch (by bos@558: refreshing it), pop or push to make a different patch the top, bos@558: and work on that patch for a bos@558: while. bos@558: bos@558: Here's an example that illustrates how you can use this bos@558: ability. Let's say you're developing a new feature as two bos@558: patches. The first is a change to the core of your software, bos@559: and the second&emdash;layered on top of the bos@559: first&emdash;changes the user interface to use the code you bos@559: just added to the core. If you notice a bug in the core while bos@559: you're working on the UI patch, it's easy to fix the core. bos@559: Simply qrefresh the UI bos@559: patch to save your in-progress changes, and qpop down to the core patch. Fix bos@559: the core bug, qrefresh the bos@559: core patch, and qpush back bos@558: to the UI patch to continue where you left off. bos@558: bos@558: bos@558: dongsheng@625: bos@558: More about patches bos@558: bos@558: MQ uses the GNU patch command to apply bos@558: patches, so it's helpful to know a few more detailed aspects of bos@558: how patch works, and about patches bos@558: themselves. bos@558: bos@558: bos@558: The strip count bos@558: bos@558: If you look at the file headers in a patch, you will bos@558: notice that the pathnames usually have an extra component on bos@558: the front that isn't present in the actual path name. This is bos@558: a holdover from the way that people used to generate patches bos@558: (people still do this, but it's somewhat rare with modern bos@558: revision control tools). bos@558: bos@558: Alice would unpack a tarball, edit her files, then decide bos@558: that she wanted to create a patch. So she'd rename her bos@558: working directory, unpack the tarball again (hence the need bos@558: for the rename), and use the and options to bos@558: diff to recursively generate a patch bos@558: between the unmodified directory and the modified one. The bos@558: result would be that the name of the unmodified directory bos@558: would be at the front of the left-hand path in every file bos@558: header, and the name of the modified directory would be at the bos@558: front of the right-hand path. bos@558: bos@558: Since someone receiving a patch from the Alices of the net bos@558: would be unlikely to have unmodified and modified directories bos@558: with exactly the same names, the patch bos@558: command has a option bos@558: that indicates the number of leading path name components to bos@558: strip when trying to apply a patch. This number is called the bos@558: strip count. bos@558: bos@558: An option of -p1 means bos@558: use a strip count of one. If bos@558: patch sees a file name bos@558: foo/bar/baz in a file header, it will bos@558: strip foo and try to patch a file named bos@558: bar/baz. (Strictly speaking, the strip bos@558: count refers to the number of path bos@558: separators (and the components that go with them bos@558: ) to strip. A strip count of one will turn bos@558: foo/bar into bar, bos@558: but /foo/bar (notice the extra leading bos@558: slash) into foo/bar.) bos@558: bos@558: The standard strip count for patches is bos@558: one; almost all patches contain one leading path name bos@558: component that needs to be stripped. Mercurial's hg diff command generates path names bos@558: in this form, and the hg bos@558: import command and MQ expect patches to have a bos@558: strip count of one. bos@558: bos@558: If you receive a patch from someone that you want to add bos@558: to your patch queue, and the patch needs a strip count other bos@558: than one, you cannot just qimport the patch, because bos@559: qimport does not yet have bos@558: a -p option (see issue bos@558: 311). Your best bet is to qnew a patch of your own, then bos@558: use patch -pN to apply their patch, bos@558: followed by hg addremove to bos@558: pick up any files added or removed by the patch, followed by bos@559: hg qrefresh. This bos@559: complexity may become unnecessary; see issue bos@559: 311 for details. bos@559: bos@558: bos@558: bos@558: Strategies for applying a patch bos@558: bos@558: When patch applies a hunk, it tries a bos@558: handful of successively less accurate strategies to try to bos@558: make the hunk apply. This falling-back technique often makes bos@558: it possible to take a patch that was generated against an old bos@558: version of a file, and apply it against a newer version of bos@558: that file. bos@558: bos@558: First, patch tries an exact match, bos@558: where the line numbers, the context, and the text to be bos@558: modified must apply exactly. If it cannot make an exact bos@558: match, it tries to find an exact match for the context, bos@558: without honouring the line numbering information. If this bos@558: succeeds, it prints a line of output saying that the hunk was bos@558: applied, but at some offset from the bos@558: original line number. bos@558: bos@558: If a context-only match fails, patch bos@558: removes the first and last lines of the context, and tries a bos@558: reduced context-only match. If the hunk bos@558: with reduced context succeeds, it prints a message saying that bos@558: it applied the hunk with a fuzz factor bos@558: (the number after the fuzz factor indicates how many lines of bos@558: context patch had to trim before the patch bos@558: applied). bos@558: bos@558: When neither of these techniques works, bos@558: patch prints a message saying that the hunk bos@558: in question was rejected. It saves rejected hunks (also bos@558: simply called rejects) to a file with the same bos@558: name, and an added .rej bos@558: extension. It also saves an unmodified copy of the file with bos@558: a .orig extension; the bos@558: copy of the file without any extensions will contain any bos@558: changes made by hunks that did apply bos@558: cleanly. If you have a patch that modifies bos@558: foo with six hunks, and one of them fails bos@558: to apply, you will have: an unmodified bos@558: foo.orig, a foo.rej bos@558: containing one hunk, and foo, containing bos@558: the changes made by the five successful hunks. bos@558: bos@558: bos@558: bos@558: Some quirks of patch representation bos@558: bos@558: There are a few useful things to know about how bos@558: patch works with files. bos@558: bos@558: This should already be obvious, but bos@558: patch cannot handle binary bos@559: files. bos@559: bos@558: Neither does it care about the executable bit; bos@558: it creates new files as readable, but not bos@559: executable. bos@559: bos@558: patch treats the removal of bos@558: a file as a diff between the file to be removed and the bos@558: empty file. So your idea of I deleted this bos@558: file looks like every line of this file bos@559: was deleted in a patch. bos@559: bos@558: It treats the addition of a file as a diff bos@558: between the empty file and the file to be added. So in a bos@558: patch, your idea of I added this file looks bos@558: like every line of this file was bos@559: added. bos@559: bos@558: It treats a renamed file as the removal of the bos@558: old name, and the addition of the new name. This means bos@558: that renamed files have a big footprint in patches. (Note bos@558: also that Mercurial does not currently try to infer when bos@559: files have been renamed or copied in a patch.) bos@559: bos@558: patch cannot represent bos@558: empty files, so you cannot use a patch to represent the bos@558: notion I added this empty file to the bos@559: tree. bos@559: bos@559: bos@558: bos@558: Beware the fuzz bos@558: bos@558: While applying a hunk at an offset, or with a fuzz factor, bos@558: will often be completely successful, these inexact techniques bos@558: naturally leave open the possibility of corrupting the patched bos@558: file. The most common cases typically involve applying a bos@558: patch twice, or at an incorrect location in the file. If bos@558: patch or qpush ever mentions an offset or bos@558: fuzz factor, you should make sure that the modified files are bos@558: correct afterwards. bos@558: bos@558: It's often a good idea to refresh a patch that has applied bos@558: with an offset or fuzz factor; refreshing the patch generates bos@558: new context information that will make it apply cleanly. I bos@558: say often, not always, because bos@558: sometimes refreshing a patch will make it fail to apply bos@558: against a different revision of the underlying files. In some bos@558: cases, such as when you're maintaining a patch that must sit bos@558: on top of multiple versions of a source tree, it's acceptable bos@558: to have a patch apply with some fuzz, provided you've verified bos@558: the results of the patching process in such cases. bos@558: bos@558: bos@558: bos@558: Handling rejection bos@558: bos@559: If qpush fails to bos@558: apply a patch, it will print an error message and exit. If it bos@558: has left .rej files bos@558: behind, it is usually best to fix up the rejected hunks before bos@558: you push more patches or do any further work. bos@558: bos@558: If your patch used to apply cleanly, bos@558: and no longer does because you've changed the underlying code bos@558: that your patches are based on, Mercurial Queues can help; see bos@559: section for details. bos@558: bos@558: Unfortunately, there aren't any great techniques for bos@558: dealing with rejected hunks. Most often, you'll need to view bos@558: the .rej file and edit the bos@558: target file, applying the rejected hunks by hand. bos@558: bos@558: If you're feeling adventurous, Neil Brown, a Linux kernel bos@558: hacker, wrote a tool called wiggle bos@558: web:wiggle, which is more vigorous than bos@558: patch in its attempts to make a patch bos@558: apply. bos@558: bos@558: Another Linux kernel hacker, Chris Mason (the author of bos@558: Mercurial Queues), wrote a similar tool called bos@558: mpatch web:mpatch, bos@558: which takes a simple approach to automating the application of bos@558: hunks rejected by patch. The bos@558: mpatch command can help with four common bos@558: reasons that a hunk may be rejected: bos@558: bos@558: bos@558: The context in the middle of a hunk has bos@559: changed. bos@559: bos@558: A hunk is missing some context at the bos@559: beginning or end. bos@559: bos@558: A large hunk might apply better&emdash;either bos@559: entirely or in part&emdash;if it was broken up into bos@559: smaller hunks. bos@559: bos@558: A hunk removes lines with slightly different bos@559: content than those currently present in the file. bos@559: bos@558: bos@558: If you use wiggle or bos@558: mpatch, you should be doubly careful to bos@558: check your results when you're done. In fact, bos@558: mpatch enforces this method of bos@558: double-checking the tool's output, by automatically dropping bos@558: you into a merge program when it has done its job, so that you bos@558: can verify its work and finish off any remaining bos@558: merges. bos@558: bos@558: bos@558: dongsheng@625: bos@558: Getting the best performance out of MQ bos@558: bos@558: MQ is very efficient at handling a large number of patches. bos@558: I ran some performance experiments in mid-2006 for a talk that I bos@558: gave at the 2006 EuroPython conference bos@558: web:europython. I used as my data set the bos@558: Linux 2.6.17-mm1 patch series, which consists of 1,738 patches. bos@558: I applied these on top of a Linux kernel repository containing bos@558: all 27,472 revisions between Linux 2.6.12-rc2 and Linux bos@558: 2.6.17. bos@558: bos@558: On my old, slow laptop, I was able to hg qpush all bos@558: 1,738 patches in 3.5 minutes, and hg qpop bos@559: bos@558: them all in 30 seconds. (On a newer laptop, the time to push bos@558: all patches dropped to two minutes.) I could qrefresh one of the biggest patches bos@558: (which made 22,779 lines of changes to 287 files) in 6.6 bos@558: seconds. bos@558: bos@558: Clearly, MQ is well suited to working in large trees, but bos@558: there are a few tricks you can use to get the best performance bos@558: of it. bos@558: bos@558: First of all, try to batch operations bos@558: together. Every time you run qpush or qpop, these commands scan the bos@558: working directory once to make sure you haven't made some bos@558: changes and then forgotten to run qrefresh. On a small tree, the bos@558: time that this scan takes is unnoticeable. However, on a bos@558: medium-sized tree (containing tens of thousands of files), it bos@558: can take a second or more. bos@558: bos@559: The qpush and qpop commands allow you to push and bos@558: pop multiple patches at a time. You can identify the bos@558: destination patch that you want to end up at. bos@559: When you qpush with a bos@558: destination specified, it will push patches until that patch is bos@558: at the top of the applied stack. When you qpop to a destination, MQ will pop bos@558: patches until the destination patch is at the top. bos@558: bos@558: You can identify a destination patch using either the name bos@558: of the patch, or by number. If you use numeric addressing, bos@558: patches are counted from zero; this means that the first patch bos@558: is zero, the second is one, and so on. bos@558: bos@558: dongsheng@625: bos@558: Updating your patches when the underlying code bos@558: changes bos@558: bos@558: It's common to have a stack of patches on top of an bos@558: underlying repository that you don't modify directly. If you're bos@558: working on changes to third-party code, or on a feature that is bos@558: taking longer to develop than the rate of change of the code bos@558: beneath, you will often need to sync up with the underlying bos@558: code, and fix up any hunks in your patches that no longer apply. bos@558: This is called rebasing your patch bos@558: series. bos@558: bos@558: The simplest way to do this is to hg bos@559: qpop your patches, then hg pull changes into the underlying bos@559: repository, and finally hg qpush your bos@558: patches again. MQ will stop pushing any time it runs across a bos@558: patch that fails to apply during conflicts, allowing you to fix bos@559: your conflicts, qrefresh the bos@558: affected patch, and continue pushing until you have fixed your bos@558: entire stack. bos@558: bos@558: This approach is easy to use and works well if you don't bos@558: expect changes to the underlying code to affect how well your bos@558: patches apply. If your patch stack touches code that is modified bos@558: frequently or invasively in the underlying repository, however, bos@558: fixing up rejected hunks by hand quickly becomes bos@558: tiresome. bos@558: bos@559: It's possible to partially automate the rebasing process. bos@559: If your patches apply cleanly against some revision of the bos@558: underlying repo, MQ can use this information to help you to bos@558: resolve conflicts between your patches and a different bos@558: revision. bos@558: bos@558: The process is a little involved. bos@558: bos@558: To begin, hg qpush bos@558: -a all of your patches on top of the revision bos@559: where you know that they apply cleanly. bos@559: bos@558: Save a backup copy of your patch directory using bos@558: hg qsave . bos@558: This prints the name of the directory that it has saved the bos@558: patches in. It will save the patches to a directory called bos@558: .hg/patches.N, where bos@558: N is a small integer. It also commits a bos@558: save changeset on top of your applied bos@558: patches; this is for internal book-keeping, and records the bos@558: states of the series and bos@559: status files. bos@559: bos@559: Use hg pull to bos@559: bring new changes into the underlying repository. (Don't bos@559: run hg pull -u; see below bos@559: for why.) bos@559: bos@558: Update to the new tip revision, using hg update to override bos@559: the patches you have pushed. bos@559: bos@558: Merge all patches using bos@559: \hgcmdargs{qpush}{ }. The option to bos@559: qpush tells MQ to bos@558: perform a three-way merge if the patch fails to bos@559: apply. bos@559: bos@558: bos@558: During the hg qpush , bos@559: each patch in the series bos@559: file is applied normally. If a patch applies with fuzz or bos@559: rejects, MQ looks at the queue you qsaved, and performs a three-way bos@558: merge with the corresponding changeset. This merge uses bos@558: Mercurial's normal merge machinery, so it may pop up a GUI merge bos@558: tool to help you to resolve problems. bos@558: bos@558: When you finish resolving the effects of a patch, MQ bos@558: refreshes your patch based on the result of the merge. bos@558: bos@558: At the end of this process, your repository will have one bos@558: extra head from the old patch queue, and a copy of the old patch bos@558: queue will be in .hg/patches.N. You can remove the bos@559: extra head using hg qpop -a -n bos@558: patches.N or hg bos@558: strip. You can delete .hg/patches.N once you are sure bos@558: that you no longer need it as a backup. bos@558: bos@558: bos@558: bos@558: Identifying patches bos@558: bos@558: MQ commands that work with patches let you refer to a patch bos@558: either by using its name or by a number. By name is obvious bos@558: enough; pass the name foo.patch to qpush, for example, and it will bos@558: push patches until foo.patch is bos@558: applied. bos@558: bos@558: As a shortcut, you can refer to a patch using both a name bos@558: and a numeric offset; foo.patch-2 means bos@558: two patches before foo.patch, bos@558: while bar.patch+4 means four patches bos@558: after bar.patch. bos@558: bos@558: Referring to a patch by index isn't much different. The bos@558: first patch printed in the output of qseries is patch zero (yes, it's bos@558: one of those start-at-zero counting systems); the second is bos@558: patch one; and so on. bos@558: bos@558: MQ also makes it easy to work with patches when you are bos@558: using normal Mercurial commands. Every command that accepts a bos@558: changeset ID will also accept the name of an applied patch. MQ bos@558: augments the tags normally in the repository with an eponymous bos@558: one for each applied patch. In addition, the special tags bos@558: \index{tags!special tag bos@558: names!qbase}qbase and bos@558: \index{tags!special tag bos@558: names!qtip}qtip identify bos@558: the bottom-most and topmost applied patches, bos@558: respectively. bos@558: bos@558: These additions to Mercurial's normal tagging capabilities bos@558: make dealing with patches even more of a breeze. bos@558: bos@558: Want to patchbomb a mailing list with your bos@558: latest series of changes? bos@559: hg email qbase:qtip bos@559: bos@559: (Don't know what patchbombing is? See dongsheng@625: section .) bos@559: bos@558: Need to see all of the patches since bos@558: foo.patch that have touched files in a bos@558: subdirectory of your tree? bos@558: bos@558: hg log -r foo.patch:qtip subdir bos@559: bos@559: bos@558: bos@558: bos@558: Because MQ makes the names of patches available to the rest bos@558: of Mercurial through its normal internal tag machinery, you bos@558: don't need to type in the entire name of a patch when you want bos@558: to identify it by name. bos@558: bos@558: Another nice consequence of representing patch names as tags bos@558: is that when you run the hg log bos@558: command, it will display a patch's name as a tag, simply as part bos@558: of its normal output. This makes it easy to visually bos@558: distinguish applied patches from underlying bos@559: normal revisions. The following example shows a bos@559: few normal Mercurial commands in use with applied bos@559: patches. bos@559: bos@567: &interaction.mq.id.output; bos@558: bos@558: bos@558: bos@558: Useful things to know about bos@558: bos@558: There are a number of aspects of MQ usage that don't fit bos@558: tidily into sections of their own, but that are good to know. bos@558: Here they are, in one place. bos@558: bos@558: bos@558: Normally, when you qpop a patch and qpush it again, the changeset bos@558: that represents the patch after the pop/push will have a bos@558: different identity than the changeset bos@558: that represented the hash beforehand. See section for bos@559: information as to why this is. bos@559: bos@558: It's not a good idea to hg merge changes from another bos@558: branch with a patch changeset, at least if you want to bos@558: maintain the patchiness of that changeset and bos@558: changesets below it on the patch stack. If you try to do bos@558: this, it will appear to succeed, but MQ will become bos@559: confused. bos@559: bos@559: bos@559: dongsheng@625: bos@558: Managing patches in a repository bos@558: bos@558: Because MQ's .hg/patches directory resides bos@558: outside a Mercurial repository's working directory, the bos@558: underlying Mercurial repository knows nothing bos@558: about the management or presence of patches. bos@558: bos@558: This presents the interesting possibility of managing the bos@558: contents of the patch directory as a Mercurial repository in its bos@558: own right. This can be a useful way to work. For example, you bos@558: can work on a patch for a while, qrefresh it, then hg commit the current state of the bos@558: patch. This lets you roll back to that version bos@558: of the patch later on. bos@558: bos@558: You can then share different versions of the same patch bos@558: stack among multiple underlying repositories. I use this when I bos@558: am developing a Linux kernel feature. I have a pristine copy of bos@558: my kernel sources for each of several CPU architectures, and a bos@558: cloned repository under each that contains the patches I am bos@558: working on. When I want to test a change on a different bos@558: architecture, I push my current patches to the patch repository bos@558: associated with that kernel tree, pop and push all of my bos@558: patches, and build and test that kernel. bos@558: bos@558: Managing patches in a repository makes it possible for bos@558: multiple developers to work on the same patch series without bos@558: colliding with each other, all on top of an underlying source bos@558: base that they may or may not control. bos@558: bos@558: bos@558: MQ support for patch repositories bos@558: bos@558: MQ helps you to work with the .hg/patches directory as a bos@558: repository; when you prepare a repository for working with bos@559: patches using qinit, you bos@559: can pass the option to create the .hg/patches directory as a bos@558: Mercurial repository. bos@558: bos@558: bos@558: If you forget to use the option, you bos@559: can simply go into the .hg/patches directory at any bos@559: time and run hg init. bos@559: Don't forget to add an entry for the status file to the .hgignore file, though bos@558: bos@558: (hg qinit bos@558: does this for you automatically); you bos@558: really don't want to manage the bos@558: status file. bos@558: bos@558: bos@558: As a convenience, if MQ notices that the .hg/patches directory is a bos@558: repository, it will automatically hg bos@558: add every patch that you create and import. bos@558: bos@558: MQ provides a shortcut command, qcommit, that runs hg commit in the .hg/patches bos@558: directory. This saves some bothersome typing. bos@558: bos@558: Finally, as a convenience to manage the patch directory, bos@558: you can define the alias mq on Unix bos@558: systems. For example, on Linux systems using the bos@558: bash shell, you can include the following bos@559: snippet in your ~/.bashrc. bos@559: bos@559: alias mq=`hg -R $(hg bos@559: root)/.hg/patches' bos@558: bos@558: You can then issue commands of the form mq bos@558: pull from the main repository. bos@558: bos@558: bos@558: bos@558: A few things to watch out for bos@558: bos@558: MQ's support for working with a repository full of patches bos@558: is limited in a few small respects. bos@558: bos@558: MQ cannot automatically detect changes that you make to bos@558: the patch directory. If you hg bos@558: pull, manually edit, or hg bos@558: update changes to patches or the series file, you will have to bos@558: hg qpop and bos@558: then hg qpush in bos@558: the underlying repository to see those changes show up there. bos@558: If you forget to do this, you can confuse MQ's idea of which bos@558: patches are applied. bos@558: bos@558: bos@558: dongsheng@625: bos@558: Third party tools for working with patches bos@558: bos@558: Once you've been working with patches for a while, you'll bos@558: find yourself hungry for tools that will help you to understand bos@558: and manipulate the patches you're dealing with. bos@558: bos@558: The diffstat command bos@558: web:diffstat generates a histogram of the bos@558: modifications made to each file in a patch. It provides a good bos@559: way to get a sense of a patch&emdash;which files bos@559: it affects, and how much change it introduces to each file and bos@559: as a whole. (I find that it's a good idea to use bos@558: diffstat's option as a matter of bos@558: course, as otherwise it will try to do clever things with bos@558: prefixes of file names that inevitably confuse at least bos@558: me.) bos@558: bos@567: &interaction.mq.tools.tools; bos@558: bos@558: The patchutils package bos@558: web:patchutils is invaluable. It provides a bos@558: set of small utilities that follow the Unix bos@558: philosophy; each does one useful thing with a patch. bos@558: The patchutils command I use bos@558: most is filterdiff, which extracts subsets bos@558: from a patch file. For example, given a patch that modifies bos@558: hundreds of files across dozens of directories, a single bos@558: invocation of filterdiff can generate a bos@558: smaller patch that only touches files whose names match a bos@558: particular glob pattern. See section for another bos@558: example. bos@558: bos@558: bos@558: bos@558: Good ways to work with patches bos@558: bos@558: Whether you are working on a patch series to submit to a bos@558: free software or open source project, or a series that you bos@558: intend to treat as a sequence of regular changesets when you're bos@558: done, you can use some simple techniques to keep your work well bos@558: organised. bos@558: bos@558: Give your patches descriptive names. A good name for a bos@558: patch might be rework-device-alloc.patch, bos@558: because it will immediately give you a hint what the purpose of bos@558: the patch is. Long names shouldn't be a problem; you won't be bos@558: typing the names often, but you will be bos@558: running commands like qapplied and qtop over and over. Good naming bos@558: becomes especially important when you have a number of patches bos@558: to work with, or if you are juggling a number of different tasks bos@558: and your patches only get a fraction of your attention. bos@558: bos@558: Be aware of what patch you're working on. Use the qtop command and skim over the text bos@558: of your patches frequently&emdash;for example, using hg tip )&emdash;to be sure bos@559: of where you stand. I have several times worked on and qrefreshed a patch other than the bos@558: one I intended, and it's often tricky to migrate changes into bos@558: the right patch after making them in the wrong one. bos@558: bos@558: For this reason, it is very much worth investing a little bos@558: time to learn how to use some of the third-party tools I dongsheng@625: described in section , bos@559: particularly bos@559: diffstat and filterdiff. bos@559: The former will give you a quick idea of what changes your patch bos@559: is making, while the latter makes it easy to splice hunks bos@559: selectively out of one patch and into another. bos@558: bos@558: bos@558: bos@558: MQ cookbook bos@558: bos@558: bos@558: Manage <quote>trivial</quote> patches bos@558: bos@558: Because the overhead of dropping files into a new bos@558: Mercurial repository is so low, it makes a lot of sense to bos@558: manage patches this way even if you simply want to make a few bos@558: changes to a source tarball that you downloaded. bos@558: bos@558: Begin by downloading and unpacking the source tarball, and bos@567: turning it into a Mercurial repository. bos@567: bos@567: &interaction.mq.tarball.download; bos@558: bos@558: Continue by creating a patch stack and making your bos@567: changes. bos@567: bos@567: &interaction.mq.tarball.qinit; bos@558: bos@558: Let's say a few weeks or months pass, and your package bos@558: author releases a new version. First, bring their changes bos@567: into the repository. bos@567: bos@567: &interaction.mq.tarball.newsource; bos@567: bos@567: The pipeline starting with hg bos@558: locate above deletes all files in the working bos@558: directory, so that hg bos@558: commit's option can bos@558: actually tell which files have really been removed in the bos@558: newer version of the source. bos@558: bos@558: Finally, you can apply your patches on top of the new bos@567: tree. bos@567: bos@567: &interaction.mq.tarball.repush; bos@558: bos@558: dongsheng@625: bos@558: Combining entire patches bos@558: bos@558: MQ provides a command, qfold that lets you combine bos@558: entire patches. This folds the patches you bos@558: name, in the order you name them, into the topmost applied bos@558: patch, and concatenates their descriptions onto the end of its bos@558: description. The patches that you fold must be unapplied bos@558: before you fold them. bos@558: bos@558: The order in which you fold patches matters. If your bos@558: topmost applied patch is foo, and you bos@559: qfold bos@558: bar and quux into it, bos@558: you will end up with a patch that has the same effect as if bos@558: you applied first foo, then bos@558: bar, followed by bos@558: quux. bos@558: bos@558: bos@558: bos@558: Merging part of one patch into another bos@558: bos@558: Merging part of one patch into bos@558: another is more difficult than combining entire bos@558: patches. bos@558: bos@558: If you want to move changes to entire files, you can use bos@558: filterdiff's and options to choose the bos@558: modifications to snip out of one patch, concatenating its bos@558: output onto the end of the patch you want to merge into. You bos@558: usually won't need to modify the patch you've merged the bos@558: changes from. Instead, MQ will report some rejected hunks bos@559: when you qpush it (from bos@558: the hunks you moved into the other patch), and you can simply bos@559: qrefresh the patch to drop bos@558: the duplicate hunks. bos@558: bos@558: If you have a patch that has multiple hunks modifying a bos@558: file, and you only want to move a few of those hunks, the job bos@558: becomes more messy, but you can still partly automate it. Use bos@558: lsdiff -nvv to print some metadata about bos@567: the patch. bos@567: bos@567: &interaction.mq.tools.lsdiff; bos@558: bos@558: This command prints three different kinds of bos@558: number: bos@558: bos@558: (in the first column) a file bos@558: number to identify each file modified in the bos@559: patch; bos@559: bos@558: (on the next line, indented) the line number bos@559: within a modified file where a hunk starts; and bos@559: bos@558: (on the same line) a hunk bos@559: number to identify that hunk. bos@559: bos@558: bos@558: You'll have to use some visual inspection, and reading of bos@558: the patch, to identify the file and hunk numbers you'll want, bos@558: but you can then pass them to to bos@558: filterdiff's and options, to bos@558: select exactly the file and hunk you want to extract. bos@558: bos@558: Once you have this hunk, you can concatenate it onto the bos@558: end of your destination patch and continue with the remainder dongsheng@625: of section . bos@558: bos@558: bos@558: bos@558: bos@558: Differences between quilt and MQ bos@558: bos@558: If you are already familiar with quilt, MQ provides a bos@558: similar command set. There are a few differences in the way bos@558: that it works. bos@558: bos@558: You will already have noticed that most quilt commands have bos@558: MQ counterparts that simply begin with a bos@558: q. The exceptions are quilt's bos@558: add and remove commands, bos@558: the counterparts for which are the normal Mercurial hg add and hg bos@558: remove commands. There is no MQ equivalent of the bos@558: quilt edit command. bos@558: bos@558: bos@558: bos@558: bos@558: