hgbook
annotate en/mq.tex @ 7:339e75288632
More progress on MQ chapter and general support.
Added a note environment.
Fixed generated HTML so it wouldn't use huge escaped entities for everything.
Wrote a small amount of actual content.
Added a note environment.
Fixed generated HTML so it wouldn't use huge escaped entities for everything.
Wrote a small amount of actual content.
author | Bryan O'Sullivan <bos@serpentine.com> |
---|---|
date | Mon Jun 26 12:25:11 2006 -0700 (2006-06-26) |
parents | 33a2e7b9978d |
children | a25335b56825 |
rev | line source |
---|---|
bos@1 | 1 \chapter{Managing change with Mercurial Queues} |
bos@1 | 2 \label{chap:mq} |
bos@1 | 3 |
bos@1 | 4 \section{The patch management problem} |
bos@1 | 5 \label{sec:mq:patch-mgmt} |
bos@1 | 6 |
bos@1 | 7 Here is a common scenario: you need to install a software package from |
bos@1 | 8 source, but you find a bug that you must fix in the source before you |
bos@1 | 9 can start using the package. You make your changes, forget about the |
bos@1 | 10 package for a while, and a few months later you need to upgrade to a |
bos@1 | 11 newer version of the package. If the newer version of the package |
bos@1 | 12 still has the bug, you must extract your fix from the older source |
bos@1 | 13 tree and apply it against the newer version. This is a tedious task, |
bos@1 | 14 and it's easy to make mistakes. |
bos@1 | 15 |
bos@1 | 16 This is a simple case of the ``patch management'' problem. You have |
bos@1 | 17 an ``upstream'' source tree that you can't change; you need to make |
bos@1 | 18 some local changes on top of the upstream tree; and you'd like to be |
bos@1 | 19 able to keep those changes separate, so that you can apply them to |
bos@1 | 20 newer versions of the upstream source. |
bos@1 | 21 |
bos@1 | 22 The patch management problem arises in many situations. Probably the |
bos@1 | 23 most visible is that a user of an open source software project will |
bos@3 | 24 contribute a bug fix or new feature to the project's maintainers in the |
bos@1 | 25 form of a patch. |
bos@1 | 26 |
bos@1 | 27 Distributors of operating systems that include open source software |
bos@1 | 28 often need to make changes to the packages they distribute so that |
bos@1 | 29 they will build properly in their environments. |
bos@1 | 30 |
bos@1 | 31 When you have few changes to maintain, it is easy to manage a single |
bos@1 | 32 patch using the standard \texttt{diff} and \texttt{patch} programs. |
bos@1 | 33 Once the number of changes grows, it starts to makes sense to maintain |
bos@1 | 34 patches as discrete ``chunks of work,'' so that for example a single |
bos@1 | 35 patch will contain only one bug fix (the patch might modify several |
bos@1 | 36 files, but it's doing ``only one thing''), and you may have a number |
bos@1 | 37 of such patches for different bugs you need fixed and local changes |
bos@3 | 38 you require. In this situation, if you submit a bug fix patch to the |
bos@1 | 39 upstream maintainers of a package and they include your fix in a |
bos@1 | 40 subsequent release, you can simply drop that single patch when you're |
bos@1 | 41 updating to the newer release. |
bos@1 | 42 |
bos@1 | 43 Maintaining a single patch against an upstream tree is a little |
bos@1 | 44 tedious and error-prone, but not difficult. However, the complexity |
bos@1 | 45 of the problem grows rapidly as the number of patches you have to |
bos@1 | 46 maintain increases. With more than a tiny number of patches in hand, |
bos@1 | 47 understanding which ones you have applied and maintaining them moves |
bos@1 | 48 from messy to overwhelming. |
bos@1 | 49 |
bos@1 | 50 Fortunately, Mercurial includes a powerful extension, Mercurial Queues |
bos@1 | 51 (or simply ``MQ''), that massively simplifies the patch management |
bos@1 | 52 problem. |
bos@1 | 53 |
bos@1 | 54 \section{The prehistory of Mercurial Queues} |
bos@1 | 55 \label{sec:mq:history} |
bos@1 | 56 |
bos@1 | 57 During the late 1990s, several Linux kernel developers started to |
bos@1 | 58 maintain ``patch series'' that modified the behaviour of the Linux |
bos@1 | 59 kernel. Some of these series were focused on stability, some on |
bos@1 | 60 feature coverage, and others were more speculative. |
bos@1 | 61 |
bos@1 | 62 The sizes of these patch series grew rapidly. In 2002, Andrew Morton |
bos@1 | 63 published some shell scripts he had been using to automate the task of |
bos@1 | 64 managing his patch queues. Andrew was successfully using these |
bos@1 | 65 scripts to manage hundreds (sometimes thousands) of patches on top of |
bos@1 | 66 the Linux kernel. |
bos@1 | 67 |
bos@1 | 68 \subsection{A patchwork quilt} |
bos@1 | 69 \label{sec:mq:quilt} |
bos@1 | 70 |
bos@1 | 71 |
bos@1 | 72 In early 2003, Andreas Gruenbacher and Martin Quinson borrowed the |
bos@2 | 73 approach of Andrew's scripts and published a tool called ``patchwork |
bos@2 | 74 quilt''~\cite{web:quilt}, or simply ``quilt'' |
bos@2 | 75 (see~\cite{gruenbacher:2005} for a paper describing it). Because |
bos@2 | 76 quilt substantially automated patch management, it rapidly gained a |
bos@2 | 77 large following among open source software developers. |
bos@1 | 78 |
bos@1 | 79 Quilt manages a \emph{stack of patches} on top of a directory tree. |
bos@1 | 80 To begin, you tell quilt to manage a directory tree; it stores away |
bos@1 | 81 the names and contents of all files in the tree. To fix a bug, you |
bos@1 | 82 create a new patch (using a single command), edit the files you need |
bos@1 | 83 to fix, then ``refresh'' the patch. |
bos@1 | 84 |
bos@1 | 85 The refresh step causes quilt to scan the directory tree; it updates |
bos@1 | 86 the patch with all of the changes you have made. You can create |
bos@1 | 87 another patch on top of the first, which will track the changes |
bos@1 | 88 required to modify the tree from ``tree with one patch applied'' to |
bos@1 | 89 ``tree with two patches applied''. |
bos@1 | 90 |
bos@1 | 91 You can \emph{change} which patches are applied to the tree. If you |
bos@1 | 92 ``pop'' a patch, the changes made by that patch will vanish from the |
bos@1 | 93 directory tree. Quilt remembers which patches you have popped, |
bos@1 | 94 though, so you can ``push'' a popped patch again, and the directory |
bos@1 | 95 tree will be restored to contain the modifications in the patch. Most |
bos@1 | 96 importantly, you can run the ``refresh'' command at any time, and the |
bos@1 | 97 topmost applied patch will be updated. This means that you can, at |
bos@1 | 98 any time, change both which patches are applied and what |
bos@1 | 99 modifications those patches make. |
bos@1 | 100 |
bos@1 | 101 Quilt knows nothing about revision control tools, so it works equally |
bos@3 | 102 well on top of an unpacked tarball or a Subversion repository. |
bos@1 | 103 |
bos@1 | 104 \subsection{From patchwork quilt to Mercurial Queues} |
bos@1 | 105 \label{sec:mq:quilt-mq} |
bos@1 | 106 |
bos@1 | 107 In mid-2005, Chris Mason took the features of quilt and wrote an |
bos@1 | 108 extension that he called Mercurial Queues, which added quilt-like |
bos@1 | 109 behaviour to Mercurial. |
bos@1 | 110 |
bos@1 | 111 The key difference between quilt and MQ is that quilt knows nothing |
bos@1 | 112 about revision control systems, while MQ is \emph{integrated} into |
bos@1 | 113 Mercurial. Each patch that you push is represented as a Mercurial |
bos@1 | 114 changeset. Pop a patch, and the changeset goes away. |
bos@1 | 115 |
bos@1 | 116 This integration makes understanding patches and debugging their |
bos@1 | 117 effects \emph{enormously} easier. Since every applied patch has an |
bos@1 | 118 associated changeset, you can use \hgcmdargs{log}{\emph{filename}} to |
bos@1 | 119 see which changesets and patches affected a file. You can use the |
bos@1 | 120 \hgext{bisect} extension to binary-search through all changesets and |
bos@1 | 121 applied patches to see where a bug got introduced or fixed. You can |
bos@1 | 122 use the \hgcmd{annotate} command to see which changeset or patch |
bos@1 | 123 modified a particular line of a source file. And so on. |
bos@1 | 124 |
bos@1 | 125 Because quilt does not care about revision control tools, it is still |
bos@1 | 126 a tremendously useful piece of software to know about for situations |
bos@1 | 127 where you cannot use Mercurial and MQ. |
bos@2 | 128 \section{Getting started with Mercurial Queues} |
bos@2 | 129 \label{sec:mq:start} |
bos@1 | 130 |
bos@3 | 131 Because MQ is implemented as an extension, you must explicitly enable |
bos@3 | 132 before you can use it. (You don't need to download anything; MQ ships |
bos@3 | 133 with the standard Mercurial distribution.) To enable MQ, edit your |
bos@4 | 134 \tildefile{.hgrc} file, and add the lines in figure~\ref{ex:mq:config}. |
bos@2 | 135 |
bos@7 | 136 \begin{figure}[h] |
bos@4 | 137 \begin{codesample4} |
bos@4 | 138 [extensions] |
bos@4 | 139 hgext.mq = |
bos@4 | 140 \end{codesample4} |
bos@4 | 141 \label{ex:mq:config} |
bos@4 | 142 \caption{Contents to add to \tildefile{.hgrc} to enable the MQ extension} |
bos@4 | 143 \end{figure} |
bos@3 | 144 |
bos@3 | 145 Once the extension is enabled, it will make a number of new commands |
bos@7 | 146 available. To verify that the extension is working, you can use |
bos@7 | 147 \hgcmd{help} to see if the \hgcmd{qinit} command is now available; see |
bos@7 | 148 the example in figure~\ref{ex:mq:enabled}. |
bos@3 | 149 |
bos@7 | 150 \begin{figure}[h] |
bos@4 | 151 \interaction{mq.qinit-help.help} |
bos@4 | 152 \caption{How to verify that MQ is enabled} |
bos@4 | 153 \label{ex:mq:enabled} |
bos@4 | 154 \end{figure} |
bos@1 | 155 |
bos@7 | 156 You can use MQ with \emph{any} Mercurial repository; to start, simply |
bos@7 | 157 prepare the repository using the \hgcmd{qinit} command (see |
bos@7 | 158 figure~\ref{ex:mq:qinit}). This command creates an empty directory |
bos@7 | 159 called \filename{.hg/patches}, where MQ will keep its metadata. As |
bos@7 | 160 with many Mercurial commands, the \hgcmd{qinit} command prints nothing |
bos@7 | 161 if it succeeds. |
bos@7 | 162 |
bos@7 | 163 \begin{figure}[h] |
bos@7 | 164 \interaction{mq.tutorial.qinit} |
bos@7 | 165 \caption{Preparing a repository for use with MQ} |
bos@7 | 166 \label{ex:mq:qinit} |
bos@7 | 167 \end{figure} |
bos@7 | 168 |
bos@7 | 169 \begin{figure}[h] |
bos@7 | 170 \interaction{mq.tutorial.qnew} |
bos@7 | 171 \caption{Creating a new patch} |
bos@7 | 172 \label{ex:mq:qnew} |
bos@7 | 173 \end{figure} |
bos@7 | 174 |
bos@7 | 175 To commence work on a new patch, use the \hgcmd{qnew} command. This |
bos@7 | 176 command takes one argument, the name of the patch to create. MQ will |
bos@7 | 177 use this as the name of an actual file in the \filename{.hg/patches} |
bos@7 | 178 directory, as you can see in figure~\ref{ex:mq:qnew}. |
bos@7 | 179 |
bos@7 | 180 Now also present in the \filename{.hg/patches} directory are two new |
bos@7 | 181 files, \filename{series} and \filename{status}. The \filename{series} |
bos@7 | 182 file lists all of the patches that MQ knows about for this repository, |
bos@7 | 183 with one patch per line. The \filename{status} file lists all of the |
bos@7 | 184 patches that MQ has \emph{applied} in this repository. |
bos@7 | 185 |
bos@7 | 186 \begin{note} |
bos@7 | 187 You may sometimes want to edit the \filename{series} file by hand; |
bos@7 | 188 for example, to change the sequence in which some patches are |
bos@7 | 189 applied. However, manually editing the \filename{status} file is |
bos@7 | 190 almost always a bad idea, as it's easy to corrupt MQ's idea of what |
bos@7 | 191 is happening. |
bos@7 | 192 \end{note} |
bos@7 | 193 |
bos@1 | 194 %%% Local Variables: |
bos@1 | 195 %%% mode: latex |
bos@1 | 196 %%% TeX-master: "00book" |
bos@1 | 197 %%% End: |