rev |
line source |
bos@558
|
1 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
|
bos@558
|
2
|
bos@558
|
3 <chapter id="chap:mq">
|
bos@572
|
4 <?dbhtml filename="managing-change-with-mercurial-queues.html"?>
|
bos@558
|
5 <title>Managing change with Mercurial Queues</title>
|
bos@558
|
6
|
bos@558
|
7 <sect1 id="sec:mq:patch-mgmt">
|
bos@558
|
8 <title>The patch management problem</title>
|
bos@558
|
9
|
bos@584
|
10 <para id="x_3ac">Here is a common scenario: you need to install a software
|
bos@558
|
11 package from source, but you find a bug that you must fix in the
|
bos@558
|
12 source before you can start using the package. You make your
|
bos@558
|
13 changes, forget about the package for a while, and a few months
|
bos@558
|
14 later you need to upgrade to a newer version of the package. If
|
bos@558
|
15 the newer version of the package still has the bug, you must
|
bos@558
|
16 extract your fix from the older source tree and apply it against
|
bos@558
|
17 the newer version. This is a tedious task, and it's easy to
|
bos@558
|
18 make mistakes.</para>
|
bos@558
|
19
|
bos@584
|
20 <para id="x_3ad">This is a simple case of the <quote>patch management</quote>
|
bos@558
|
21 problem. You have an <quote>upstream</quote> source tree that
|
bos@558
|
22 you can't change; you need to make some local changes on top of
|
bos@558
|
23 the upstream tree; and you'd like to be able to keep those
|
bos@558
|
24 changes separate, so that you can apply them to newer versions
|
bos@558
|
25 of the upstream source.</para>
|
bos@558
|
26
|
bos@584
|
27 <para id="x_3ae">The patch management problem arises in many situations.
|
bos@558
|
28 Probably the most visible is that a user of an open source
|
bos@558
|
29 software project will contribute a bug fix or new feature to the
|
bos@558
|
30 project's maintainers in the form of a patch.</para>
|
bos@558
|
31
|
bos@584
|
32 <para id="x_3af">Distributors of operating systems that include open source
|
bos@558
|
33 software often need to make changes to the packages they
|
bos@558
|
34 distribute so that they will build properly in their
|
bos@558
|
35 environments.</para>
|
bos@558
|
36
|
bos@584
|
37 <para id="x_3b0">When you have few changes to maintain, it is easy to manage
|
bos@558
|
38 a single patch using the standard <command>diff</command> and
|
bos@592
|
39 <command>patch</command> programs (see <xref
|
bos@559
|
40 linkend="sec:mq:patch"/> for a discussion of these
|
bos@559
|
41 tools). Once the number of changes grows, it starts to make
|
bos@559
|
42 sense to maintain patches as discrete <quote>chunks of
|
bos@559
|
43 work,</quote> so that for example a single patch will contain
|
bos@559
|
44 only one bug fix (the patch might modify several files, but it's
|
bos@559
|
45 doing <quote>only one thing</quote>), and you may have a number
|
bos@559
|
46 of such patches for different bugs you need fixed and local
|
bos@559
|
47 changes you require. In this situation, if you submit a bug fix
|
bos@559
|
48 patch to the upstream maintainers of a package and they include
|
bos@559
|
49 your fix in a subsequent release, you can simply drop that
|
bos@559
|
50 single patch when you're updating to the newer release.</para>
|
bos@558
|
51
|
bos@584
|
52 <para id="x_3b1">Maintaining a single patch against an upstream tree is a
|
bos@558
|
53 little tedious and error-prone, but not difficult. However, the
|
bos@558
|
54 complexity of the problem grows rapidly as the number of patches
|
bos@558
|
55 you have to maintain increases. With more than a tiny number of
|
bos@558
|
56 patches in hand, understanding which ones you have applied and
|
bos@558
|
57 maintaining them moves from messy to overwhelming.</para>
|
bos@558
|
58
|
bos@584
|
59 <para id="x_3b2">Fortunately, Mercurial includes a powerful extension,
|
bos@558
|
60 Mercurial Queues (or simply <quote>MQ</quote>), that massively
|
bos@558
|
61 simplifies the patch management problem.</para>
|
bos@558
|
62
|
bos@558
|
63 </sect1>
|
bos@558
|
64 <sect1 id="sec:mq:history">
|
bos@558
|
65 <title>The prehistory of Mercurial Queues</title>
|
bos@558
|
66
|
bos@584
|
67 <para id="x_3b3">During the late 1990s, several Linux kernel developers
|
bos@558
|
68 started to maintain <quote>patch series</quote> that modified
|
bos@672
|
69 the behavior of the Linux kernel. Some of these series were
|
bos@558
|
70 focused on stability, some on feature coverage, and others were
|
bos@558
|
71 more speculative.</para>
|
bos@558
|
72
|
bos@584
|
73 <para id="x_3b4">The sizes of these patch series grew rapidly. In 2002,
|
bos@558
|
74 Andrew Morton published some shell scripts he had been using to
|
bos@558
|
75 automate the task of managing his patch queues. Andrew was
|
bos@558
|
76 successfully using these scripts to manage hundreds (sometimes
|
bos@558
|
77 thousands) of patches on top of the Linux kernel.</para>
|
bos@558
|
78
|
bos@558
|
79 <sect2 id="sec:mq:quilt">
|
bos@558
|
80 <title>A patchwork quilt</title>
|
bos@558
|
81
|
bos@584
|
82 <para id="x_3b5">In early 2003, Andreas Gruenbacher and Martin Quinson
|
bos@558
|
83 borrowed the approach of Andrew's scripts and published a tool
|
bos@558
|
84 called <quote>patchwork quilt</quote>
|
bos@558
|
85 <citation>web:quilt</citation>, or simply <quote>quilt</quote>
|
bos@558
|
86 (see <citation>gruenbacher:2005</citation> for a paper
|
bos@558
|
87 describing it). Because quilt substantially automated patch
|
bos@558
|
88 management, it rapidly gained a large following among open
|
bos@558
|
89 source software developers.</para>
|
bos@558
|
90
|
bos@584
|
91 <para id="x_3b6">Quilt manages a <emphasis>stack of patches</emphasis> on
|
bos@558
|
92 top of a directory tree. To begin, you tell quilt to manage a
|
bos@558
|
93 directory tree, and tell it which files you want to manage; it
|
bos@558
|
94 stores away the names and contents of those files. To fix a
|
bos@558
|
95 bug, you create a new patch (using a single command), edit the
|
bos@558
|
96 files you need to fix, then <quote>refresh</quote> the
|
bos@558
|
97 patch.</para>
|
bos@558
|
98
|
bos@584
|
99 <para id="x_3b7">The refresh step causes quilt to scan the directory tree;
|
bos@558
|
100 it updates the patch with all of the changes you have made.
|
bos@558
|
101 You can create another patch on top of the first, which will
|
bos@558
|
102 track the changes required to modify the tree from <quote>tree
|
bos@558
|
103 with one patch applied</quote> to <quote>tree with two
|
bos@558
|
104 patches applied</quote>.</para>
|
bos@558
|
105
|
bos@584
|
106 <para id="x_3b8">You can <emphasis>change</emphasis> which patches are
|
bos@558
|
107 applied to the tree. If you <quote>pop</quote> a patch, the
|
bos@558
|
108 changes made by that patch will vanish from the directory
|
bos@558
|
109 tree. Quilt remembers which patches you have popped, though,
|
bos@558
|
110 so you can <quote>push</quote> a popped patch again, and the
|
bos@558
|
111 directory tree will be restored to contain the modifications
|
bos@558
|
112 in the patch. Most importantly, you can run the
|
bos@558
|
113 <quote>refresh</quote> command at any time, and the topmost
|
bos@558
|
114 applied patch will be updated. This means that you can, at
|
bos@558
|
115 any time, change both which patches are applied and what
|
bos@558
|
116 modifications those patches make.</para>
|
bos@558
|
117
|
bos@584
|
118 <para id="x_3b9">Quilt knows nothing about revision control tools, so it
|
bos@558
|
119 works equally well on top of an unpacked tarball or a
|
bos@558
|
120 Subversion working copy.</para>
|
bos@682
|
121 </sect2>
|
bos@682
|
122
|
bos@558
|
123 <sect2 id="sec:mq:quilt-mq">
|
bos@558
|
124 <title>From patchwork quilt to Mercurial Queues</title>
|
bos@558
|
125
|
bos@584
|
126 <para id="x_3ba">In mid-2005, Chris Mason took the features of quilt and
|
bos@558
|
127 wrote an extension that he called Mercurial Queues, which
|
bos@672
|
128 added quilt-like behavior to Mercurial.</para>
|
bos@558
|
129
|
bos@584
|
130 <para id="x_3bb">The key difference between quilt and MQ is that quilt
|
bos@558
|
131 knows nothing about revision control systems, while MQ is
|
bos@558
|
132 <emphasis>integrated</emphasis> into Mercurial. Each patch
|
bos@558
|
133 that you push is represented as a Mercurial changeset. Pop a
|
bos@558
|
134 patch, and the changeset goes away.</para>
|
bos@558
|
135
|
bos@584
|
136 <para id="x_3bc">Because quilt does not care about revision control tools,
|
bos@558
|
137 it is still a tremendously useful piece of software to know
|
bos@558
|
138 about for situations where you cannot use Mercurial and
|
bos@558
|
139 MQ.</para>
|
bos@558
|
140
|
bos@558
|
141 </sect2>
|
bos@558
|
142 </sect1>
|
bos@558
|
143 <sect1>
|
bos@558
|
144 <title>The huge advantage of MQ</title>
|
bos@558
|
145
|
bos@584
|
146 <para id="x_3bd">I cannot overstate the value that MQ offers through the
|
bos@558
|
147 unification of patches and revision control.</para>
|
bos@558
|
148
|
bos@584
|
149 <para id="x_3be">A major reason that patches have persisted in the free
|
bos@559
|
150 software and open source world&emdash;in spite of the
|
bos@559
|
151 availability of increasingly capable revision control tools over
|
bos@559
|
152 the years&emdash;is the <emphasis>agility</emphasis> they
|
bos@559
|
153 offer.</para>
|
bos@558
|
154
|
bos@584
|
155 <para id="x_3bf">Traditional revision control tools make a permanent,
|
bos@558
|
156 irreversible record of everything that you do. While this has
|
bos@558
|
157 great value, it's also somewhat stifling. If you want to
|
bos@558
|
158 perform a wild-eyed experiment, you have to be careful in how
|
bos@558
|
159 you go about it, or you risk leaving unneeded&emdash;or worse,
|
bos@559
|
160 misleading or destabilising&emdash;traces of your missteps and
|
bos@559
|
161 errors in the permanent revision record.</para>
|
bos@558
|
162
|
bos@584
|
163 <para id="x_3c0">By contrast, MQ's marriage of distributed revision control
|
bos@558
|
164 with patches makes it much easier to isolate your work. Your
|
bos@558
|
165 patches live on top of normal revision history, and you can make
|
bos@558
|
166 them disappear or reappear at will. If you don't like a patch,
|
bos@558
|
167 you can drop it. If a patch isn't quite as you want it to be,
|
bos@559
|
168 simply fix it&emdash;as many times as you need to, until you
|
bos@559
|
169 have refined it into the form you desire.</para>
|
bos@558
|
170
|
bos@584
|
171 <para id="x_3c1">As an example, the integration of patches with revision
|
bos@558
|
172 control makes understanding patches and debugging their
|
bos@558
|
173 effects&emdash;and their interplay with the code they're based
|
bos@559
|
174 on&emdash;<emphasis>enormously</emphasis> easier. Since every
|
bos@559
|
175 applied patch has an associated changeset, you can give <command
|
bos@559
|
176 role="hg-cmd">hg log</command> a file name to see which
|
bos@559
|
177 changesets and patches affected the file. You can use the
|
bos@559
|
178 <command role="hg-cmd">hg bisect</command> command to
|
bos@559
|
179 binary-search through all changesets and applied patches to see
|
bos@559
|
180 where a bug got introduced or fixed. You can use the <command
|
bos@558
|
181 role="hg-cmd">hg annotate</command> command to see which
|
bos@558
|
182 changeset or patch modified a particular line of a source file.
|
bos@558
|
183 And so on.</para>
|
bos@682
|
184 </sect1>
|
bos@682
|
185
|
bos@558
|
186 <sect1 id="sec:mq:patch">
|
bos@558
|
187 <title>Understanding patches</title>
|
bos@558
|
188
|
bos@584
|
189 <para id="x_3c2">Because MQ doesn't hide its patch-oriented nature, it is
|
bos@558
|
190 helpful to understand what patches are, and a little about the
|
bos@558
|
191 tools that work with them.</para>
|
bos@558
|
192
|
bos@584
|
193 <para id="x_3c3">The traditional Unix <command>diff</command> command
|
bos@558
|
194 compares two files, and prints a list of differences between
|
bos@558
|
195 them. The <command>patch</command> command understands these
|
bos@558
|
196 differences as <emphasis>modifications</emphasis> to make to a
|
bos@558
|
197 file. Take a look below for a simple example of these commands
|
bos@558
|
198 in action.</para>
|
bos@558
|
199
|
bos@567
|
200 &interaction.mq.dodiff.diff;
|
bos@558
|
201
|
bos@584
|
202 <para id="x_3c4">The type of file that <command>diff</command> generates (and
|
bos@558
|
203 <command>patch</command> takes as input) is called a
|
bos@558
|
204 <quote>patch</quote> or a <quote>diff</quote>; there is no
|
bos@558
|
205 difference between a patch and a diff. (We'll use the term
|
bos@558
|
206 <quote>patch</quote>, since it's more commonly used.)</para>
|
bos@558
|
207
|
bos@584
|
208 <para id="x_3c5">A patch file can start with arbitrary text; the
|
bos@558
|
209 <command>patch</command> command ignores this text, but MQ uses
|
bos@558
|
210 it as the commit message when creating changesets. To find the
|
bos@558
|
211 beginning of the patch content, <command>patch</command>
|
bos@558
|
212 searches for the first line that starts with the string
|
bos@558
|
213 <quote><literal>diff -</literal></quote>.</para>
|
bos@558
|
214
|
bos@584
|
215 <para id="x_3c6">MQ works with <emphasis>unified</emphasis> diffs
|
bos@558
|
216 (<command>patch</command> can accept several other diff formats,
|
bos@558
|
217 but MQ doesn't). A unified diff contains two kinds of header.
|
bos@558
|
218 The <emphasis>file header</emphasis> describes the file being
|
bos@558
|
219 modified; it contains the name of the file to modify. When
|
bos@558
|
220 <command>patch</command> sees a new file header, it looks for a
|
bos@558
|
221 file with that name to start modifying.</para>
|
bos@558
|
222
|
bos@584
|
223 <para id="x_3c7">After the file header comes a series of
|
bos@558
|
224 <emphasis>hunks</emphasis>. Each hunk starts with a header;
|
bos@558
|
225 this identifies the range of line numbers within the file that
|
bos@558
|
226 the hunk should modify. Following the header, a hunk starts and
|
bos@558
|
227 ends with a few (usually three) lines of text from the
|
bos@558
|
228 unmodified file; these are called the
|
bos@558
|
229 <emphasis>context</emphasis> for the hunk. If there's only a
|
bos@558
|
230 small amount of context between successive hunks,
|
bos@558
|
231 <command>diff</command> doesn't print a new hunk header; it just
|
bos@558
|
232 runs the hunks together, with a few lines of context between
|
bos@558
|
233 modifications.</para>
|
bos@558
|
234
|
bos@584
|
235 <para id="x_3c8">Each line of context begins with a space character. Within
|
bos@558
|
236 the hunk, a line that begins with
|
bos@558
|
237 <quote><literal>-</literal></quote> means <quote>remove this
|
bos@558
|
238 line,</quote> while a line that begins with
|
bos@558
|
239 <quote><literal>+</literal></quote> means <quote>insert this
|
bos@558
|
240 line.</quote> For example, a line that is modified is
|
bos@558
|
241 represented by one deletion and one insertion.</para>
|
bos@558
|
242
|
bos@584
|
243 <para id="x_3c9">We will return to some of the more subtle aspects of patches
|
bos@592
|
244 later (in <xref linkend="sec:mq:adv-patch"/>), but you
|
bos@559
|
245 should have
|
bos@559
|
246 enough information now to use MQ.</para>
|
bos@682
|
247 </sect1>
|
bos@682
|
248
|
bos@558
|
249 <sect1 id="sec:mq:start">
|
bos@558
|
250 <title>Getting started with Mercurial Queues</title>
|
bos@558
|
251
|
bos@584
|
252 <para id="x_3ca">Because MQ is implemented as an extension, you must
|
bos@558
|
253 explicitly enable before you can use it. (You don't need to
|
bos@558
|
254 download anything; MQ ships with the standard Mercurial
|
bos@559
|
255 distribution.) To enable MQ, edit your <filename
|
bos@559
|
256 role="home">~/.hgrc</filename> file, and add the lines
|
bos@559
|
257 below.</para>
|
bos@558
|
258
|
bos@580
|
259 <programlisting>[extensions]
|
bos@580
|
260 hgext.mq =</programlisting>
|
bos@558
|
261
|
bos@584
|
262 <para id="x_3cb">Once the extension is enabled, it will make a number of new
|
bos@558
|
263 commands available. To verify that the extension is working,
|
bos@558
|
264 you can use <command role="hg-cmd">hg help</command> to see if
|
bos@559
|
265 the <command role="hg-ext-mq">qinit</command> command is now
|
bos@558
|
266 available.</para>
|
bos@558
|
267
|
bos@682
|
268 &interaction.mq.qinit-help.help;
|
bos@558
|
269
|
bos@584
|
270 <para id="x_3cc">You can use MQ with <emphasis>any</emphasis> Mercurial
|
bos@558
|
271 repository, and its commands only operate within that
|
bos@558
|
272 repository. To get started, simply prepare the repository using
|
bos@559
|
273 the <command role="hg-ext-mq">qinit</command> command.</para>
|
bos@559
|
274
|
bos@682
|
275 &interaction.mq.tutorial.qinit;
|
bos@559
|
276
|
bos@584
|
277 <para id="x_3cd">This command creates an empty directory called <filename
|
bos@558
|
278 role="special" class="directory">.hg/patches</filename>, where
|
bos@558
|
279 MQ will keep its metadata. As with many Mercurial commands, the
|
bos@559
|
280 <command role="hg-ext-mq">qinit</command> command prints nothing
|
bos@558
|
281 if it succeeds.</para>
|
bos@558
|
282
|
bos@558
|
283 <sect2>
|
bos@558
|
284 <title>Creating a new patch</title>
|
bos@558
|
285
|
bos@584
|
286 <para id="x_3ce">To begin work on a new patch, use the <command
|
bos@559
|
287 role="hg-ext-mq">qnew</command> command. This command takes
|
bos@559
|
288 one argument, the name of the patch to create.</para>
|
bos@559
|
289
|
bos@584
|
290 <para id="x_3cf">MQ will use this as the name of an actual file in the
|
bos@559
|
291 <filename role="special"
|
bos@559
|
292 class="directory">.hg/patches</filename> directory, as you
|
bos@559
|
293 can see below.</para>
|
bos@559
|
294
|
bos@682
|
295 &interaction.mq.tutorial.qnew;
|
bos@558
|
296
|
bos@584
|
297 <para id="x_3d0">Also newly present in the <filename role="special"
|
bos@558
|
298 class="directory">.hg/patches</filename> directory are two
|
bos@558
|
299 other files, <filename role="special">series</filename> and
|
bos@558
|
300 <filename role="special">status</filename>. The <filename
|
bos@558
|
301 role="special">series</filename> file lists all of the
|
bos@558
|
302 patches that MQ knows about for this repository, with one
|
bos@558
|
303 patch per line. Mercurial uses the <filename
|
bos@558
|
304 role="special">status</filename> file for internal
|
bos@558
|
305 book-keeping; it tracks all of the patches that MQ has
|
bos@558
|
306 <emphasis>applied</emphasis> in this repository.</para>
|
bos@558
|
307
|
bos@558
|
308 <note>
|
bos@584
|
309 <para id="x_3d1"> You may sometimes want to edit the <filename
|
bos@558
|
310 role="special">series</filename> file by hand; for
|
bos@558
|
311 example, to change the sequence in which some patches are
|
bos@558
|
312 applied. However, manually editing the <filename
|
bos@558
|
313 role="special">status</filename> file is almost always a
|
bos@558
|
314 bad idea, as it's easy to corrupt MQ's idea of what is
|
bos@558
|
315 happening.</para>
|
bos@558
|
316 </note>
|
bos@558
|
317
|
bos@584
|
318 <para id="x_3d2">Once you have created your new patch, you can edit files
|
bos@558
|
319 in the working directory as you usually would. All of the
|
bos@558
|
320 normal Mercurial commands, such as <command role="hg-cmd">hg
|
bos@558
|
321 diff</command> and <command role="hg-cmd">hg
|
bos@558
|
322 annotate</command>, work exactly as they did before.</para>
|
bos@682
|
323 </sect2>
|
bos@682
|
324
|
bos@558
|
325 <sect2>
|
bos@558
|
326 <title>Refreshing a patch</title>
|
bos@558
|
327
|
bos@584
|
328 <para id="x_3d3">When you reach a point where you want to save your work,
|
bos@559
|
329 use the <command role="hg-ext-mq">qrefresh</command> command
|
bos@559
|
330 to update the patch you are working on.</para>
|
bos@558
|
331
|
bos@682
|
332 &interaction.mq.tutorial.qrefresh;
|
bos@558
|
333
|
bos@584
|
334 <para id="x_3d4">This command folds the changes you have made in the
|
bos@559
|
335 working directory into your patch, and updates its
|
bos@559
|
336 corresponding changeset to contain those changes.</para>
|
bos@559
|
337
|
bos@584
|
338 <para id="x_3d5">You can run <command role="hg-ext-mq">qrefresh</command>
|
bos@559
|
339 as often as you like, so it's a good way to
|
bos@559
|
340 <quote>checkpoint</quote> your work. Refresh your patch at an
|
bos@559
|
341 opportune time; try an experiment; and if the experiment
|
bos@558
|
342 doesn't work out, <command role="hg-cmd">hg revert</command>
|
bos@558
|
343 your modifications back to the last time you refreshed.</para>
|
bos@558
|
344
|
bos@682
|
345 &interaction.mq.tutorial.qrefresh2;
|
bos@682
|
346 </sect2>
|
bos@682
|
347
|
bos@558
|
348 <sect2>
|
bos@558
|
349 <title>Stacking and tracking patches</title>
|
bos@558
|
350
|
bos@584
|
351 <para id="x_3d6">Once you have finished working on a patch, or need to work
|
bos@559
|
352 on another, you can use the <command
|
bos@559
|
353 role="hg-ext-mq">qnew</command> command again to create a
|
bos@559
|
354 new patch. Mercurial will apply this patch on top of your
|
bos@559
|
355 existing patch.</para>
|
bos@559
|
356
|
bos@682
|
357 &interaction.mq.tutorial.qnew2;
|
bos@682
|
358
|
bos@584
|
359 <para id="x_3d7">Notice that the patch contains the changes in our prior
|
bos@559
|
360 patch as part of its context (you can see this more clearly in
|
bos@559
|
361 the output of <command role="hg-cmd">hg
|
bos@558
|
362 annotate</command>).</para>
|
bos@558
|
363
|
bos@584
|
364 <para id="x_3d8">So far, with the exception of <command
|
bos@559
|
365 role="hg-ext-mq">qnew</command> and <command
|
bos@559
|
366 role="hg-ext-mq">qrefresh</command>, we've been careful to
|
bos@558
|
367 only use regular Mercurial commands. However, MQ provides
|
bos@558
|
368 many commands that are easier to use when you are thinking
|
bos@559
|
369 about patches, as illustrated below.</para>
|
bos@559
|
370
|
bos@682
|
371 &interaction.mq.tutorial.qseries;
|
bos@558
|
372
|
bos@558
|
373 <itemizedlist>
|
bos@584
|
374 <listitem><para id="x_3d9">The <command
|
bos@559
|
375 role="hg-ext-mq">qseries</command> command lists every
|
bos@558
|
376 patch that MQ knows about in this repository, from oldest
|
bos@558
|
377 to newest (most recently
|
bos@559
|
378 <emphasis>created</emphasis>).</para>
|
bos@559
|
379 </listitem>
|
bos@584
|
380 <listitem><para id="x_3da">The <command
|
bos@559
|
381 role="hg-ext-mq">qapplied</command> command lists every
|
bos@558
|
382 patch that MQ has <emphasis>applied</emphasis> in this
|
bos@558
|
383 repository, again from oldest to newest (most recently
|
bos@559
|
384 applied).</para>
|
bos@559
|
385 </listitem></itemizedlist>
|
bos@682
|
386 </sect2>
|
bos@682
|
387
|
bos@558
|
388 <sect2>
|
bos@558
|
389 <title>Manipulating the patch stack</title>
|
bos@558
|
390
|
bos@584
|
391 <para id="x_3db">The previous discussion implied that there must be a
|
bos@558
|
392 difference between <quote>known</quote> and
|
bos@558
|
393 <quote>applied</quote> patches, and there is. MQ can manage a
|
bos@558
|
394 patch without it being applied in the repository.</para>
|
bos@558
|
395
|
bos@584
|
396 <para id="x_3dc">An <emphasis>applied</emphasis> patch has a corresponding
|
bos@558
|
397 changeset in the repository, and the effects of the patch and
|
bos@558
|
398 changeset are visible in the working directory. You can undo
|
bos@558
|
399 the application of a patch using the <command
|
bos@559
|
400 role="hg-ext-mq">qpop</command> command. MQ still
|
bos@558
|
401 <emphasis>knows about</emphasis>, or manages, a popped patch,
|
bos@558
|
402 but the patch no longer has a corresponding changeset in the
|
bos@558
|
403 repository, and the working directory does not contain the
|
bos@592
|
404 changes made by the patch. <xref
|
bos@559
|
405 linkend="fig:mq:stack"/> illustrates
|
bos@559
|
406 the difference between applied and tracked patches.</para>
|
bos@558
|
407
|
bos@592
|
408 <figure id="fig:mq:stack">
|
bos@592
|
409 <title>Applied and unapplied patches in the MQ patch
|
bos@592
|
410 stack</title>
|
bos@592
|
411 <mediaobject>
|
bos@594
|
412 <imageobject><imagedata fileref="figs/mq-stack.png"/></imageobject>
|
bos@592
|
413 <textobject><phrase>XXX add text</phrase></textobject>
|
bos@592
|
414 </mediaobject>
|
bos@592
|
415 </figure>
|
bos@558
|
416
|
bos@584
|
417 <para id="x_3de">You can reapply an unapplied, or popped, patch using the
|
bos@559
|
418 <command role="hg-ext-mq">qpush</command> command. This
|
bos@558
|
419 creates a new changeset to correspond to the patch, and the
|
bos@558
|
420 patch's changes once again become present in the working
|
bos@559
|
421 directory. See below for examples of <command
|
bos@559
|
422 role="hg-ext-mq">qpop</command> and <command
|
bos@559
|
423 role="hg-ext-mq">qpush</command> in action.</para>
|
bos@682
|
424
|
bos@682
|
425 &interaction.mq.tutorial.qpop;
|
bos@558
|
426
|
bos@584
|
427 <para id="x_3df">Notice that once we have popped a patch or two patches,
|
bos@559
|
428 the output of <command role="hg-ext-mq">qseries</command>
|
bos@559
|
429 remains the same, while that of <command
|
bos@559
|
430 role="hg-ext-mq">qapplied</command> has changed.</para>
|
bos@559
|
431
|
bos@682
|
432 </sect2>
|
bos@682
|
433
|
bos@558
|
434 <sect2>
|
bos@558
|
435 <title>Pushing and popping many patches</title>
|
bos@558
|
436
|
bos@584
|
437 <para id="x_3e0">While <command role="hg-ext-mq">qpush</command> and
|
bos@559
|
438 <command role="hg-ext-mq">qpop</command> each operate on a
|
bos@558
|
439 single patch at a time by default, you can push and pop many
|
bos@558
|
440 patches in one go. The <option
|
bos@559
|
441 role="hg-ext-mq-cmd-qpush-opt">hg -a</option> option to
|
bos@559
|
442 <command role="hg-ext-mq">qpush</command> causes it to push
|
bos@558
|
443 all unapplied patches, while the <option
|
bos@558
|
444 role="hg-ext-mq-cmd-qpop-opt">-a</option> option to <command
|
bos@559
|
445 role="hg-ext-mq">qpop</command> causes it to pop all applied
|
bos@558
|
446 patches. (For some more ways to push and pop many patches,
|
bos@592
|
447 see <xref linkend="sec:mq:perf"/> below.)</para>
|
bos@558
|
448
|
bos@682
|
449 &interaction.mq.tutorial.qpush-a;
|
bos@682
|
450 </sect2>
|
bos@682
|
451
|
bos@558
|
452 <sect2>
|
bos@558
|
453 <title>Safety checks, and overriding them</title>
|
bos@558
|
454
|
bos@584
|
455 <para id="x_3e1">Several MQ commands check the working directory before
|
bos@558
|
456 they do anything, and fail if they find any modifications.
|
bos@558
|
457 They do this to ensure that you won't lose any changes that
|
bos@559
|
458 you have made, but not yet incorporated into a patch. The
|
bos@559
|
459 example below illustrates this; the <command
|
bos@559
|
460 role="hg-ext-mq">qnew</command> command will not create a
|
bos@558
|
461 new patch if there are outstanding changes, caused in this
|
bos@558
|
462 case by the <command role="hg-cmd">hg add</command> of
|
bos@558
|
463 <filename>file3</filename>.</para>
|
bos@558
|
464
|
bos@682
|
465 &interaction.mq.tutorial.add;
|
bos@558
|
466
|
bos@584
|
467 <para id="x_3e2">Commands that check the working directory all take an
|
bos@558
|
468 <quote>I know what I'm doing</quote> option, which is always
|
bos@558
|
469 named <option>-f</option>. The exact meaning of
|
bos@558
|
470 <option>-f</option> depends on the command. For example,
|
bos@558
|
471 <command role="hg-cmd">hg qnew <option
|
bos@559
|
472 role="hg-ext-mq-cmd-qnew-opt">hg -f</option></command>
|
bos@559
|
473 will incorporate any outstanding changes into the new patch it
|
bos@558
|
474 creates, but <command role="hg-cmd">hg qpop <option
|
bos@559
|
475 role="hg-ext-mq-cmd-qpop-opt">hg -f</option></command>
|
bos@559
|
476 will revert modifications to any files affected by the patch
|
bos@559
|
477 that it is popping. Be sure to read the documentation for a
|
bos@558
|
478 command's <option>-f</option> option before you use it!</para>
|
bos@682
|
479 </sect2>
|
bos@682
|
480
|
bos@558
|
481 <sect2>
|
bos@558
|
482 <title>Working on several patches at once</title>
|
bos@558
|
483
|
bos@584
|
484 <para id="x_3e3">The <command role="hg-ext-mq">qrefresh</command> command
|
bos@558
|
485 always refreshes the <emphasis>topmost</emphasis> applied
|
bos@558
|
486 patch. This means that you can suspend work on one patch (by
|
bos@558
|
487 refreshing it), pop or push to make a different patch the top,
|
bos@558
|
488 and work on <emphasis>that</emphasis> patch for a
|
bos@558
|
489 while.</para>
|
bos@558
|
490
|
bos@584
|
491 <para id="x_3e4">Here's an example that illustrates how you can use this
|
bos@558
|
492 ability. Let's say you're developing a new feature as two
|
bos@558
|
493 patches. The first is a change to the core of your software,
|
bos@559
|
494 and the second&emdash;layered on top of the
|
bos@559
|
495 first&emdash;changes the user interface to use the code you
|
bos@559
|
496 just added to the core. If you notice a bug in the core while
|
bos@559
|
497 you're working on the UI patch, it's easy to fix the core.
|
bos@559
|
498 Simply <command role="hg-ext-mq">qrefresh</command> the UI
|
bos@559
|
499 patch to save your in-progress changes, and <command
|
bos@559
|
500 role="hg-ext-mq">qpop</command> down to the core patch. Fix
|
bos@559
|
501 the core bug, <command role="hg-ext-mq">qrefresh</command> the
|
bos@559
|
502 core patch, and <command role="hg-ext-mq">qpush</command> back
|
bos@558
|
503 to the UI patch to continue where you left off.</para>
|
bos@682
|
504 </sect2>
|
bos@682
|
505 </sect1>
|
bos@682
|
506
|
bos@558
|
507 <sect1 id="sec:mq:adv-patch">
|
bos@558
|
508 <title>More about patches</title>
|
bos@558
|
509
|
bos@584
|
510 <para id="x_3e5">MQ uses the GNU <command>patch</command> command to apply
|
bos@558
|
511 patches, so it's helpful to know a few more detailed aspects of
|
bos@558
|
512 how <command>patch</command> works, and about patches
|
bos@558
|
513 themselves.</para>
|
bos@558
|
514
|
bos@558
|
515 <sect2>
|
bos@558
|
516 <title>The strip count</title>
|
bos@558
|
517
|
bos@584
|
518 <para id="x_3e6">If you look at the file headers in a patch, you will
|
bos@558
|
519 notice that the pathnames usually have an extra component on
|
bos@558
|
520 the front that isn't present in the actual path name. This is
|
bos@558
|
521 a holdover from the way that people used to generate patches
|
bos@558
|
522 (people still do this, but it's somewhat rare with modern
|
bos@558
|
523 revision control tools).</para>
|
bos@558
|
524
|
bos@584
|
525 <para id="x_3e7">Alice would unpack a tarball, edit her files, then decide
|
bos@558
|
526 that she wanted to create a patch. So she'd rename her
|
bos@558
|
527 working directory, unpack the tarball again (hence the need
|
bos@558
|
528 for the rename), and use the <option
|
bos@558
|
529 role="cmd-opt-diff">-r</option> and <option
|
bos@558
|
530 role="cmd-opt-diff">-N</option> options to
|
bos@558
|
531 <command>diff</command> to recursively generate a patch
|
bos@558
|
532 between the unmodified directory and the modified one. The
|
bos@558
|
533 result would be that the name of the unmodified directory
|
bos@558
|
534 would be at the front of the left-hand path in every file
|
bos@558
|
535 header, and the name of the modified directory would be at the
|
bos@558
|
536 front of the right-hand path.</para>
|
bos@558
|
537
|
bos@584
|
538 <para id="x_3e8">Since someone receiving a patch from the Alices of the net
|
bos@558
|
539 would be unlikely to have unmodified and modified directories
|
bos@558
|
540 with exactly the same names, the <command>patch</command>
|
bos@558
|
541 command has a <option role="cmd-opt-patch">-p</option> option
|
bos@558
|
542 that indicates the number of leading path name components to
|
bos@558
|
543 strip when trying to apply a patch. This number is called the
|
bos@558
|
544 <emphasis>strip count</emphasis>.</para>
|
bos@558
|
545
|
bos@584
|
546 <para id="x_3e9">An option of <quote><literal>-p1</literal></quote> means
|
bos@558
|
547 <quote>use a strip count of one</quote>. If
|
bos@558
|
548 <command>patch</command> sees a file name
|
bos@558
|
549 <filename>foo/bar/baz</filename> in a file header, it will
|
bos@558
|
550 strip <filename>foo</filename> and try to patch a file named
|
bos@558
|
551 <filename>bar/baz</filename>. (Strictly speaking, the strip
|
bos@558
|
552 count refers to the number of <emphasis>path
|
bos@558
|
553 separators</emphasis> (and the components that go with them
|
bos@558
|
554 ) to strip. A strip count of one will turn
|
bos@558
|
555 <filename>foo/bar</filename> into <filename>bar</filename>,
|
bos@558
|
556 but <filename>/foo/bar</filename> (notice the extra leading
|
bos@558
|
557 slash) into <filename>foo/bar</filename>.)</para>
|
bos@558
|
558
|
bos@584
|
559 <para id="x_3ea">The <quote>standard</quote> strip count for patches is
|
bos@558
|
560 one; almost all patches contain one leading path name
|
bos@558
|
561 component that needs to be stripped. Mercurial's <command
|
bos@558
|
562 role="hg-cmd">hg diff</command> command generates path names
|
bos@558
|
563 in this form, and the <command role="hg-cmd">hg
|
bos@558
|
564 import</command> command and MQ expect patches to have a
|
bos@558
|
565 strip count of one.</para>
|
bos@558
|
566
|
bos@584
|
567 <para id="x_3eb">If you receive a patch from someone that you want to add
|
bos@558
|
568 to your patch queue, and the patch needs a strip count other
|
bos@558
|
569 than one, you cannot just <command
|
bos@559
|
570 role="hg-ext-mq">qimport</command> the patch, because
|
bos@559
|
571 <command role="hg-ext-mq">qimport</command> does not yet have
|
bos@558
|
572 a <literal>-p</literal> option (see <ulink role="hg-bug"
|
bos@558
|
573 url="http://www.selenic.com/mercurial/bts/issue311">issue
|
bos@558
|
574 311</ulink>). Your best bet is to <command
|
bos@559
|
575 role="hg-ext-mq">qnew</command> a patch of your own, then
|
bos@558
|
576 use <command>patch -pN</command> to apply their patch,
|
bos@558
|
577 followed by <command role="hg-cmd">hg addremove</command> to
|
bos@558
|
578 pick up any files added or removed by the patch, followed by
|
bos@559
|
579 <command role="hg-ext-mq">hg qrefresh</command>. This
|
bos@559
|
580 complexity may become unnecessary; see <ulink role="hg-bug"
|
bos@558
|
581 url="http://www.selenic.com/mercurial/bts/issue311">issue
|
bos@559
|
582 311</ulink> for details.
|
bos@559
|
583 </para>
|
bos@558
|
584 </sect2>
|
bos@682
|
585
|
bos@558
|
586 <sect2>
|
bos@558
|
587 <title>Strategies for applying a patch</title>
|
bos@558
|
588
|
bos@584
|
589 <para id="x_3ec">When <command>patch</command> applies a hunk, it tries a
|
bos@558
|
590 handful of successively less accurate strategies to try to
|
bos@558
|
591 make the hunk apply. This falling-back technique often makes
|
bos@558
|
592 it possible to take a patch that was generated against an old
|
bos@558
|
593 version of a file, and apply it against a newer version of
|
bos@558
|
594 that file.</para>
|
bos@558
|
595
|
bos@584
|
596 <para id="x_3ed">First, <command>patch</command> tries an exact match,
|
bos@558
|
597 where the line numbers, the context, and the text to be
|
bos@558
|
598 modified must apply exactly. If it cannot make an exact
|
bos@558
|
599 match, it tries to find an exact match for the context,
|
bos@558
|
600 without honouring the line numbering information. If this
|
bos@558
|
601 succeeds, it prints a line of output saying that the hunk was
|
bos@558
|
602 applied, but at some <emphasis>offset</emphasis> from the
|
bos@558
|
603 original line number.</para>
|
bos@558
|
604
|
bos@584
|
605 <para id="x_3ee">If a context-only match fails, <command>patch</command>
|
bos@558
|
606 removes the first and last lines of the context, and tries a
|
bos@558
|
607 <emphasis>reduced</emphasis> context-only match. If the hunk
|
bos@558
|
608 with reduced context succeeds, it prints a message saying that
|
bos@558
|
609 it applied the hunk with a <emphasis>fuzz factor</emphasis>
|
bos@558
|
610 (the number after the fuzz factor indicates how many lines of
|
bos@558
|
611 context <command>patch</command> had to trim before the patch
|
bos@558
|
612 applied).</para>
|
bos@558
|
613
|
bos@584
|
614 <para id="x_3ef">When neither of these techniques works,
|
bos@558
|
615 <command>patch</command> prints a message saying that the hunk
|
bos@558
|
616 in question was rejected. It saves rejected hunks (also
|
bos@558
|
617 simply called <quote>rejects</quote>) to a file with the same
|
bos@558
|
618 name, and an added <filename role="special">.rej</filename>
|
bos@558
|
619 extension. It also saves an unmodified copy of the file with
|
bos@558
|
620 a <filename role="special">.orig</filename> extension; the
|
bos@558
|
621 copy of the file without any extensions will contain any
|
bos@558
|
622 changes made by hunks that <emphasis>did</emphasis> apply
|
bos@558
|
623 cleanly. If you have a patch that modifies
|
bos@558
|
624 <filename>foo</filename> with six hunks, and one of them fails
|
bos@558
|
625 to apply, you will have: an unmodified
|
bos@558
|
626 <filename>foo.orig</filename>, a <filename>foo.rej</filename>
|
bos@558
|
627 containing one hunk, and <filename>foo</filename>, containing
|
bos@558
|
628 the changes made by the five successful hunks.</para>
|
bos@682
|
629 </sect2>
|
bos@682
|
630
|
bos@558
|
631 <sect2>
|
bos@558
|
632 <title>Some quirks of patch representation</title>
|
bos@558
|
633
|
bos@584
|
634 <para id="x_3f0">There are a few useful things to know about how
|
bos@558
|
635 <command>patch</command> works with files.</para>
|
bos@558
|
636 <itemizedlist>
|
bos@584
|
637 <listitem><para id="x_3f1">This should already be obvious, but
|
bos@558
|
638 <command>patch</command> cannot handle binary
|
bos@559
|
639 files.</para>
|
bos@559
|
640 </listitem>
|
bos@584
|
641 <listitem><para id="x_3f2">Neither does it care about the executable bit;
|
bos@558
|
642 it creates new files as readable, but not
|
bos@559
|
643 executable.</para>
|
bos@559
|
644 </listitem>
|
bos@584
|
645 <listitem><para id="x_3f3"><command>patch</command> treats the removal of
|
bos@558
|
646 a file as a diff between the file to be removed and the
|
bos@558
|
647 empty file. So your idea of <quote>I deleted this
|
bos@558
|
648 file</quote> looks like <quote>every line of this file
|
bos@559
|
649 was deleted</quote> in a patch.</para>
|
bos@559
|
650 </listitem>
|
bos@584
|
651 <listitem><para id="x_3f4">It treats the addition of a file as a diff
|
bos@558
|
652 between the empty file and the file to be added. So in a
|
bos@558
|
653 patch, your idea of <quote>I added this file</quote> looks
|
bos@558
|
654 like <quote>every line of this file was
|
bos@559
|
655 added</quote>.</para>
|
bos@559
|
656 </listitem>
|
bos@584
|
657 <listitem><para id="x_3f5">It treats a renamed file as the removal of the
|
bos@558
|
658 old name, and the addition of the new name. This means
|
bos@558
|
659 that renamed files have a big footprint in patches. (Note
|
bos@558
|
660 also that Mercurial does not currently try to infer when
|
bos@559
|
661 files have been renamed or copied in a patch.)</para>
|
bos@559
|
662 </listitem>
|
bos@584
|
663 <listitem><para id="x_3f6"><command>patch</command> cannot represent
|
bos@558
|
664 empty files, so you cannot use a patch to represent the
|
bos@558
|
665 notion <quote>I added this empty file to the
|
bos@559
|
666 tree</quote>.</para>
|
bos@559
|
667 </listitem></itemizedlist>
|
bos@559
|
668 </sect2>
|
bos@682
|
669
|
bos@558
|
670 <sect2>
|
bos@558
|
671 <title>Beware the fuzz</title>
|
bos@558
|
672
|
bos@584
|
673 <para id="x_3f7">While applying a hunk at an offset, or with a fuzz factor,
|
bos@558
|
674 will often be completely successful, these inexact techniques
|
bos@558
|
675 naturally leave open the possibility of corrupting the patched
|
bos@558
|
676 file. The most common cases typically involve applying a
|
bos@558
|
677 patch twice, or at an incorrect location in the file. If
|
bos@558
|
678 <command>patch</command> or <command
|
bos@559
|
679 role="hg-ext-mq">qpush</command> ever mentions an offset or
|
bos@558
|
680 fuzz factor, you should make sure that the modified files are
|
bos@558
|
681 correct afterwards.</para>
|
bos@558
|
682
|
bos@584
|
683 <para id="x_3f8">It's often a good idea to refresh a patch that has applied
|
bos@558
|
684 with an offset or fuzz factor; refreshing the patch generates
|
bos@558
|
685 new context information that will make it apply cleanly. I
|
bos@558
|
686 say <quote>often,</quote> not <quote>always,</quote> because
|
bos@558
|
687 sometimes refreshing a patch will make it fail to apply
|
bos@558
|
688 against a different revision of the underlying files. In some
|
bos@558
|
689 cases, such as when you're maintaining a patch that must sit
|
bos@558
|
690 on top of multiple versions of a source tree, it's acceptable
|
bos@558
|
691 to have a patch apply with some fuzz, provided you've verified
|
bos@558
|
692 the results of the patching process in such cases.</para>
|
bos@682
|
693 </sect2>
|
bos@682
|
694
|
bos@558
|
695 <sect2>
|
bos@558
|
696 <title>Handling rejection</title>
|
bos@558
|
697
|
bos@584
|
698 <para id="x_3f9">If <command role="hg-ext-mq">qpush</command> fails to
|
bos@558
|
699 apply a patch, it will print an error message and exit. If it
|
bos@558
|
700 has left <filename role="special">.rej</filename> files
|
bos@558
|
701 behind, it is usually best to fix up the rejected hunks before
|
bos@558
|
702 you push more patches or do any further work.</para>
|
bos@558
|
703
|
bos@584
|
704 <para id="x_3fa">If your patch <emphasis>used to</emphasis> apply cleanly,
|
bos@558
|
705 and no longer does because you've changed the underlying code
|
bos@558
|
706 that your patches are based on, Mercurial Queues can help; see
|
bos@592
|
707 <xref linkend="sec:mq:merge"/> for details.</para>
|
bos@558
|
708
|
bos@584
|
709 <para id="x_3fb">Unfortunately, there aren't any great techniques for
|
bos@558
|
710 dealing with rejected hunks. Most often, you'll need to view
|
bos@558
|
711 the <filename role="special">.rej</filename> file and edit the
|
bos@558
|
712 target file, applying the rejected hunks by hand.</para>
|
bos@558
|
713
|
bos@682
|
714 <para id="x_3fd">A Linux kernel hacker, Chris Mason (the author
|
bos@682
|
715 of Mercurial Queues), wrote a tool called
|
bos@682
|
716 <command>mpatch</command> (<ulink
|
bos@682
|
717 url="http://oss.oracle.com/~mason/mpatch/">http://oss.oracle.com/~mason/mpatch/</ulink>),
|
bos@558
|
718 which takes a simple approach to automating the application of
|
bos@558
|
719 hunks rejected by <command>patch</command>. The
|
bos@558
|
720 <command>mpatch</command> command can help with four common
|
bos@558
|
721 reasons that a hunk may be rejected:</para>
|
bos@558
|
722
|
bos@558
|
723 <itemizedlist>
|
bos@584
|
724 <listitem><para id="x_3fe">The context in the middle of a hunk has
|
bos@559
|
725 changed.</para>
|
bos@559
|
726 </listitem>
|
bos@584
|
727 <listitem><para id="x_3ff">A hunk is missing some context at the
|
bos@559
|
728 beginning or end.</para>
|
bos@559
|
729 </listitem>
|
bos@584
|
730 <listitem><para id="x_400">A large hunk might apply better&emdash;either
|
bos@559
|
731 entirely or in part&emdash;if it was broken up into
|
bos@559
|
732 smaller hunks.</para>
|
bos@559
|
733 </listitem>
|
bos@584
|
734 <listitem><para id="x_401">A hunk removes lines with slightly different
|
bos@559
|
735 content than those currently present in the file.</para>
|
bos@559
|
736 </listitem></itemizedlist>
|
bos@558
|
737
|
bos@682
|
738 <para id="x_402">If you use <command>mpatch</command>, you
|
bos@682
|
739 should be doubly careful to check your results when you're
|
bos@682
|
740 done. In fact, <command>mpatch</command> enforces this method
|
bos@682
|
741 of double-checking the tool's output, by automatically
|
bos@682
|
742 dropping you into a merge program when it has done its job, so
|
bos@682
|
743 that you can verify its work and finish off any remaining
|
bos@558
|
744 merges.</para>
|
bos@682
|
745 </sect2>
|
bos@682
|
746 </sect1>
|
bos@682
|
747
|
bos@682
|
748 <sect1>
|
bos@682
|
749 <title>More on patch management</title>
|
bos@682
|
750
|
bos@684
|
751 <para id="x_6db">As you grow familiar with MQ, you will find yourself wanting
|
bos@682
|
752 to perform other kinds of patch management operations.</para>
|
bos@682
|
753
|
bos@682
|
754 <sect2>
|
bos@682
|
755 <title>Deleting unwanted patches</title>
|
bos@682
|
756
|
bos@684
|
757 <para id="x_6dc">If you want to get rid of a patch, use the <command
|
bos@682
|
758 role="hg-ext-mq">hg qdelete</command> command to delete the
|
bos@682
|
759 patch file and remove its entry from the patch series. If you
|
bos@682
|
760 try to delete a patch that is still applied, <command
|
bos@682
|
761 role="hg-ext-mq">hg qdelete</command> will refuse.</para>
|
bos@682
|
762
|
bos@682
|
763 &interaction.ch11-qdelete.go;
|
bos@682
|
764 </sect2>
|
bos@682
|
765
|
bos@682
|
766 <sect2>
|
bos@682
|
767 <title>Converting to and from permanent revisions</title>
|
bos@682
|
768
|
bos@684
|
769 <para id="x_6dd">Once you're done working on a patch and want to turn it
|
bos@682
|
770 into a permanent changeset, use the <command
|
bos@682
|
771 role="hg-ext-mq">hg qdelete -r</command> command. Pass a
|
bos@682
|
772 revision to the <option>-r</option> option to identify the
|
bos@682
|
773 patch that you want to turn into a regular changeset; this
|
bos@682
|
774 patch must already be applied.</para>
|
bos@682
|
775
|
bos@682
|
776 &interaction.ch11-qdelete.convert;
|
bos@682
|
777
|
bos@684
|
778 <para id="x_6de">It is also possible to turn an existing changeset into a
|
bos@682
|
779 patch, by passing the <option>-r</option> option to <command
|
bos@682
|
780 role="hg-ext-mq">hg qimport</command>.</para>
|
bos@682
|
781
|
bos@682
|
782 &interaction.ch11-qdelete.import;
|
bos@682
|
783
|
bos@684
|
784 <para id="x_6df">Note that it only makes sense to convert a changeset into
|
bos@682
|
785 a patch if you have not propagated that changeset into any
|
bos@682
|
786 other repositories. The imported changeset's ID will change
|
bos@682
|
787 every time you refresh the patch, which will make Mercurial
|
bos@682
|
788 treat it as unrelated to the original changeset if you have
|
bos@682
|
789 pushed it somewhere else.</para>
|
bos@682
|
790 </sect2>
|
bos@682
|
791 </sect1>
|
bos@682
|
792
|
bos@558
|
793 <sect1 id="sec:mq:perf">
|
bos@558
|
794 <title>Getting the best performance out of MQ</title>
|
bos@558
|
795
|
bos@683
|
796 <para id="x_403">MQ is very efficient at handling a large number
|
bos@683
|
797 of patches. I ran some performance experiments in mid-2006 for a
|
bos@683
|
798 talk that I gave at the 2006 EuroPython conference (on modern
|
bos@683
|
799 hardware, you should expect better performance than you'll see
|
bos@683
|
800 below). I used as my data set the Linux 2.6.17-mm1 patch
|
bos@683
|
801 series, which consists of 1,738 patches. I applied these on top
|
bos@683
|
802 of a Linux kernel repository containing all 27,472 revisions
|
bos@683
|
803 between Linux 2.6.12-rc2 and Linux 2.6.17.</para>
|
bos@558
|
804
|
bos@584
|
805 <para id="x_404">On my old, slow laptop, I was able to <command
|
bos@558
|
806 role="hg-cmd">hg qpush <option
|
bos@559
|
807 role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> all
|
bos@558
|
808 1,738 patches in 3.5 minutes, and <command role="hg-cmd">hg qpop
|
bos@559
|
809 <option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command>
|
bos@558
|
810 them all in 30 seconds. (On a newer laptop, the time to push
|
bos@558
|
811 all patches dropped to two minutes.) I could <command
|
bos@559
|
812 role="hg-ext-mq">qrefresh</command> one of the biggest patches
|
bos@558
|
813 (which made 22,779 lines of changes to 287 files) in 6.6
|
bos@558
|
814 seconds.</para>
|
bos@558
|
815
|
bos@584
|
816 <para id="x_405">Clearly, MQ is well suited to working in large trees, but
|
bos@558
|
817 there are a few tricks you can use to get the best performance
|
bos@558
|
818 of it.</para>
|
bos@558
|
819
|
bos@584
|
820 <para id="x_406">First of all, try to <quote>batch</quote> operations
|
bos@558
|
821 together. Every time you run <command
|
bos@559
|
822 role="hg-ext-mq">qpush</command> or <command
|
bos@559
|
823 role="hg-ext-mq">qpop</command>, these commands scan the
|
bos@558
|
824 working directory once to make sure you haven't made some
|
bos@558
|
825 changes and then forgotten to run <command
|
bos@559
|
826 role="hg-ext-mq">qrefresh</command>. On a small tree, the
|
bos@558
|
827 time that this scan takes is unnoticeable. However, on a
|
bos@558
|
828 medium-sized tree (containing tens of thousands of files), it
|
bos@558
|
829 can take a second or more.</para>
|
bos@558
|
830
|
bos@584
|
831 <para id="x_407">The <command role="hg-ext-mq">qpush</command> and <command
|
bos@559
|
832 role="hg-ext-mq">qpop</command> commands allow you to push and
|
bos@558
|
833 pop multiple patches at a time. You can identify the
|
bos@558
|
834 <quote>destination patch</quote> that you want to end up at.
|
bos@559
|
835 When you <command role="hg-ext-mq">qpush</command> with a
|
bos@558
|
836 destination specified, it will push patches until that patch is
|
bos@558
|
837 at the top of the applied stack. When you <command
|
bos@559
|
838 role="hg-ext-mq">qpop</command> to a destination, MQ will pop
|
bos@558
|
839 patches until the destination patch is at the top.</para>
|
bos@558
|
840
|
bos@584
|
841 <para id="x_408">You can identify a destination patch using either the name
|
bos@558
|
842 of the patch, or by number. If you use numeric addressing,
|
bos@558
|
843 patches are counted from zero; this means that the first patch
|
bos@558
|
844 is zero, the second is one, and so on.</para>
|
bos@682
|
845 </sect1>
|
bos@682
|
846
|
bos@558
|
847 <sect1 id="sec:mq:merge">
|
bos@558
|
848 <title>Updating your patches when the underlying code
|
bos@558
|
849 changes</title>
|
bos@558
|
850
|
bos@584
|
851 <para id="x_409">It's common to have a stack of patches on top of an
|
bos@558
|
852 underlying repository that you don't modify directly. If you're
|
bos@558
|
853 working on changes to third-party code, or on a feature that is
|
bos@558
|
854 taking longer to develop than the rate of change of the code
|
bos@558
|
855 beneath, you will often need to sync up with the underlying
|
bos@558
|
856 code, and fix up any hunks in your patches that no longer apply.
|
bos@558
|
857 This is called <emphasis>rebasing</emphasis> your patch
|
bos@558
|
858 series.</para>
|
bos@558
|
859
|
bos@584
|
860 <para id="x_40a">The simplest way to do this is to <command role="hg-cmd">hg
|
bos@559
|
861 qpop <option role="hg-ext-mq-cmd-qpop-opt">hg
|
bos@559
|
862 -a</option></command> your patches, then <command
|
bos@559
|
863 role="hg-cmd">hg pull</command> changes into the underlying
|
bos@559
|
864 repository, and finally <command role="hg-cmd">hg qpush <option
|
bos@559
|
865 role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> your
|
bos@558
|
866 patches again. MQ will stop pushing any time it runs across a
|
bos@558
|
867 patch that fails to apply during conflicts, allowing you to fix
|
bos@559
|
868 your conflicts, <command role="hg-ext-mq">qrefresh</command> the
|
bos@558
|
869 affected patch, and continue pushing until you have fixed your
|
bos@558
|
870 entire stack.</para>
|
bos@558
|
871
|
bos@584
|
872 <para id="x_40b">This approach is easy to use and works well if you don't
|
bos@558
|
873 expect changes to the underlying code to affect how well your
|
bos@558
|
874 patches apply. If your patch stack touches code that is modified
|
bos@558
|
875 frequently or invasively in the underlying repository, however,
|
bos@558
|
876 fixing up rejected hunks by hand quickly becomes
|
bos@558
|
877 tiresome.</para>
|
bos@558
|
878
|
bos@584
|
879 <para id="x_40c">It's possible to partially automate the rebasing process.
|
bos@559
|
880 If your patches apply cleanly against some revision of the
|
bos@558
|
881 underlying repo, MQ can use this information to help you to
|
bos@558
|
882 resolve conflicts between your patches and a different
|
bos@558
|
883 revision.</para>
|
bos@558
|
884
|
bos@584
|
885 <para id="x_40d">The process is a little involved.</para>
|
bos@558
|
886 <orderedlist>
|
bos@584
|
887 <listitem><para id="x_40e">To begin, <command role="hg-cmd">hg qpush
|
bos@558
|
888 -a</command> all of your patches on top of the revision
|
bos@559
|
889 where you know that they apply cleanly.</para>
|
bos@559
|
890 </listitem>
|
bos@584
|
891 <listitem><para id="x_40f">Save a backup copy of your patch directory using
|
bos@558
|
892 <command role="hg-cmd">hg qsave <option
|
bos@559
|
893 role="hg-ext-mq-cmd-qsave-opt">hg -e</option> <option
|
bos@559
|
894 role="hg-ext-mq-cmd-qsave-opt">hg -c</option></command>.
|
bos@558
|
895 This prints the name of the directory that it has saved the
|
bos@558
|
896 patches in. It will save the patches to a directory called
|
bos@558
|
897 <filename role="special"
|
bos@558
|
898 class="directory">.hg/patches.N</filename>, where
|
bos@558
|
899 <literal>N</literal> is a small integer. It also commits a
|
bos@558
|
900 <quote>save changeset</quote> on top of your applied
|
bos@558
|
901 patches; this is for internal book-keeping, and records the
|
bos@558
|
902 states of the <filename role="special">series</filename> and
|
bos@559
|
903 <filename role="special">status</filename> files.</para>
|
bos@559
|
904 </listitem>
|
bos@584
|
905 <listitem><para id="x_410">Use <command role="hg-cmd">hg pull</command> to
|
bos@559
|
906 bring new changes into the underlying repository. (Don't
|
bos@559
|
907 run <command role="hg-cmd">hg pull -u</command>; see below
|
bos@559
|
908 for why.)</para>
|
bos@559
|
909 </listitem>
|
bos@584
|
910 <listitem><para id="x_411">Update to the new tip revision, using <command
|
bos@558
|
911 role="hg-cmd">hg update <option
|
bos@558
|
912 role="hg-opt-update">-C</option></command> to override
|
bos@559
|
913 the patches you have pushed.</para>
|
bos@559
|
914 </listitem>
|
bos@584
|
915 <listitem><para id="x_412">Merge all patches using <command>hg qpush -m
|
bos@580
|
916 -a</command>. The <option
|
bos@580
|
917 role="hg-ext-mq-cmd-qpush-opt">-m</option> option to
|
bos@559
|
918 <command role="hg-ext-mq">qpush</command> tells MQ to
|
bos@558
|
919 perform a three-way merge if the patch fails to
|
bos@559
|
920 apply.</para>
|
bos@559
|
921 </listitem></orderedlist>
|
bos@558
|
922
|
bos@584
|
923 <para id="x_413">During the <command role="hg-cmd">hg qpush <option
|
bos@559
|
924 role="hg-ext-mq-cmd-qpush-opt">hg -m</option></command>,
|
bos@559
|
925 each patch in the <filename role="special">series</filename>
|
bos@559
|
926 file is applied normally. If a patch applies with fuzz or
|
bos@559
|
927 rejects, MQ looks at the queue you <command
|
bos@559
|
928 role="hg-ext-mq">qsave</command>d, and performs a three-way
|
bos@558
|
929 merge with the corresponding changeset. This merge uses
|
bos@558
|
930 Mercurial's normal merge machinery, so it may pop up a GUI merge
|
bos@558
|
931 tool to help you to resolve problems.</para>
|
bos@558
|
932
|
bos@584
|
933 <para id="x_414">When you finish resolving the effects of a patch, MQ
|
bos@558
|
934 refreshes your patch based on the result of the merge.</para>
|
bos@558
|
935
|
bos@584
|
936 <para id="x_415">At the end of this process, your repository will have one
|
bos@558
|
937 extra head from the old patch queue, and a copy of the old patch
|
bos@558
|
938 queue will be in <filename role="special"
|
bos@558
|
939 class="directory">.hg/patches.N</filename>. You can remove the
|
bos@559
|
940 extra head using <command role="hg-cmd">hg qpop -a -n
|
bos@558
|
941 patches.N</command> or <command role="hg-cmd">hg
|
bos@558
|
942 strip</command>. You can delete <filename role="special"
|
bos@558
|
943 class="directory">.hg/patches.N</filename> once you are sure
|
bos@558
|
944 that you no longer need it as a backup.</para>
|
bos@682
|
945 </sect1>
|
bos@682
|
946
|
bos@558
|
947 <sect1>
|
bos@558
|
948 <title>Identifying patches</title>
|
bos@558
|
949
|
bos@584
|
950 <para id="x_416">MQ commands that work with patches let you refer to a patch
|
bos@558
|
951 either by using its name or by a number. By name is obvious
|
bos@558
|
952 enough; pass the name <filename>foo.patch</filename> to <command
|
bos@559
|
953 role="hg-ext-mq">qpush</command>, for example, and it will
|
bos@558
|
954 push patches until <filename>foo.patch</filename> is
|
bos@558
|
955 applied.</para>
|
bos@558
|
956
|
bos@584
|
957 <para id="x_417">As a shortcut, you can refer to a patch using both a name
|
bos@558
|
958 and a numeric offset; <literal>foo.patch-2</literal> means
|
bos@558
|
959 <quote>two patches before <literal>foo.patch</literal></quote>,
|
bos@558
|
960 while <literal>bar.patch+4</literal> means <quote>four patches
|
bos@558
|
961 after <literal>bar.patch</literal></quote>.</para>
|
bos@558
|
962
|
bos@584
|
963 <para id="x_418">Referring to a patch by index isn't much different. The
|
bos@558
|
964 first patch printed in the output of <command
|
bos@559
|
965 role="hg-ext-mq">qseries</command> is patch zero (yes, it's
|
bos@558
|
966 one of those start-at-zero counting systems); the second is
|
bos@558
|
967 patch one; and so on.</para>
|
bos@558
|
968
|
bos@584
|
969 <para id="x_419">MQ also makes it easy to work with patches when you are
|
bos@558
|
970 using normal Mercurial commands. Every command that accepts a
|
bos@558
|
971 changeset ID will also accept the name of an applied patch. MQ
|
bos@558
|
972 augments the tags normally in the repository with an eponymous
|
bos@558
|
973 one for each applied patch. In addition, the special tags
|
bos@580
|
974 <literal role="tag">qbase</literal> and
|
bos@580
|
975 <literal role="tag">qtip</literal> identify
|
bos@558
|
976 the <quote>bottom-most</quote> and topmost applied patches,
|
bos@558
|
977 respectively.</para>
|
bos@558
|
978
|
bos@584
|
979 <para id="x_41a">These additions to Mercurial's normal tagging capabilities
|
bos@558
|
980 make dealing with patches even more of a breeze.</para>
|
bos@558
|
981 <itemizedlist>
|
bos@584
|
982 <listitem><para id="x_41b">Want to patchbomb a mailing list with your
|
bos@558
|
983 latest series of changes?</para>
|
bos@580
|
984 <programlisting>hg email qbase:qtip</programlisting>
|
bos@584
|
985 <para id="x_41c"> (Don't know what <quote>patchbombing</quote> is? See
|
bos@592
|
986 <xref linkend="sec:hgext:patchbomb"/>.)</para>
|
bos@559
|
987 </listitem>
|
bos@584
|
988 <listitem><para id="x_41d">Need to see all of the patches since
|
bos@558
|
989 <literal>foo.patch</literal> that have touched files in a
|
bos@558
|
990 subdirectory of your tree?</para>
|
bos@580
|
991 <programlisting>hg log -r foo.patch:qtip subdir</programlisting>
|
bos@559
|
992 </listitem>
|
bos@558
|
993 </itemizedlist>
|
bos@558
|
994
|
bos@584
|
995 <para id="x_41e">Because MQ makes the names of patches available to the rest
|
bos@558
|
996 of Mercurial through its normal internal tag machinery, you
|
bos@558
|
997 don't need to type in the entire name of a patch when you want
|
bos@558
|
998 to identify it by name.</para>
|
bos@558
|
999
|
bos@584
|
1000 <para id="x_41f">Another nice consequence of representing patch names as tags
|
bos@558
|
1001 is that when you run the <command role="hg-cmd">hg log</command>
|
bos@558
|
1002 command, it will display a patch's name as a tag, simply as part
|
bos@558
|
1003 of its normal output. This makes it easy to visually
|
bos@558
|
1004 distinguish applied patches from underlying
|
bos@559
|
1005 <quote>normal</quote> revisions. The following example shows a
|
bos@559
|
1006 few normal Mercurial commands in use with applied
|
bos@559
|
1007 patches.</para>
|
bos@559
|
1008
|
bos@682
|
1009 &interaction.mq.id.output;
|
bos@682
|
1010 </sect1>
|
bos@682
|
1011
|
bos@558
|
1012 <sect1>
|
bos@558
|
1013 <title>Useful things to know about</title>
|
bos@558
|
1014
|
bos@584
|
1015 <para id="x_420">There are a number of aspects of MQ usage that don't fit
|
bos@558
|
1016 tidily into sections of their own, but that are good to know.
|
bos@558
|
1017 Here they are, in one place.</para>
|
bos@558
|
1018
|
bos@558
|
1019 <itemizedlist>
|
bos@584
|
1020 <listitem><para id="x_421">Normally, when you <command
|
bos@559
|
1021 role="hg-ext-mq">qpop</command> a patch and <command
|
bos@559
|
1022 role="hg-ext-mq">qpush</command> it again, the changeset
|
bos@558
|
1023 that represents the patch after the pop/push will have a
|
bos@558
|
1024 <emphasis>different identity</emphasis> than the changeset
|
bos@592
|
1025 that represented the hash beforehand. See <xref
|
bos@559
|
1026 linkend="sec:mqref:cmd:qpush"/> for
|
bos@559
|
1027 information as to why this is.</para>
|
bos@559
|
1028 </listitem>
|
bos@584
|
1029 <listitem><para id="x_422">It's not a good idea to <command
|
bos@558
|
1030 role="hg-cmd">hg merge</command> changes from another
|
bos@558
|
1031 branch with a patch changeset, at least if you want to
|
bos@558
|
1032 maintain the <quote>patchiness</quote> of that changeset and
|
bos@558
|
1033 changesets below it on the patch stack. If you try to do
|
bos@558
|
1034 this, it will appear to succeed, but MQ will become
|
bos@559
|
1035 confused.</para>
|
bos@559
|
1036 </listitem></itemizedlist>
|
bos@682
|
1037 </sect1>
|
bos@682
|
1038
|
bos@558
|
1039 <sect1 id="sec:mq:repo">
|
bos@558
|
1040 <title>Managing patches in a repository</title>
|
bos@558
|
1041
|
bos@584
|
1042 <para id="x_423">Because MQ's <filename role="special"
|
bos@558
|
1043 class="directory">.hg/patches</filename> directory resides
|
bos@558
|
1044 outside a Mercurial repository's working directory, the
|
bos@558
|
1045 <quote>underlying</quote> Mercurial repository knows nothing
|
bos@558
|
1046 about the management or presence of patches.</para>
|
bos@558
|
1047
|
bos@584
|
1048 <para id="x_424">This presents the interesting possibility of managing the
|
bos@558
|
1049 contents of the patch directory as a Mercurial repository in its
|
bos@558
|
1050 own right. This can be a useful way to work. For example, you
|
bos@558
|
1051 can work on a patch for a while, <command
|
bos@559
|
1052 role="hg-ext-mq">qrefresh</command> it, then <command
|
bos@558
|
1053 role="hg-cmd">hg commit</command> the current state of the
|
bos@558
|
1054 patch. This lets you <quote>roll back</quote> to that version
|
bos@558
|
1055 of the patch later on.</para>
|
bos@558
|
1056
|
bos@584
|
1057 <para id="x_425">You can then share different versions of the same patch
|
bos@558
|
1058 stack among multiple underlying repositories. I use this when I
|
bos@558
|
1059 am developing a Linux kernel feature. I have a pristine copy of
|
bos@558
|
1060 my kernel sources for each of several CPU architectures, and a
|
bos@558
|
1061 cloned repository under each that contains the patches I am
|
bos@558
|
1062 working on. When I want to test a change on a different
|
bos@558
|
1063 architecture, I push my current patches to the patch repository
|
bos@558
|
1064 associated with that kernel tree, pop and push all of my
|
bos@558
|
1065 patches, and build and test that kernel.</para>
|
bos@558
|
1066
|
bos@584
|
1067 <para id="x_426">Managing patches in a repository makes it possible for
|
bos@558
|
1068 multiple developers to work on the same patch series without
|
bos@558
|
1069 colliding with each other, all on top of an underlying source
|
bos@558
|
1070 base that they may or may not control.</para>
|
bos@558
|
1071
|
bos@558
|
1072 <sect2>
|
bos@558
|
1073 <title>MQ support for patch repositories</title>
|
bos@558
|
1074
|
bos@584
|
1075 <para id="x_427">MQ helps you to work with the <filename role="special"
|
bos@558
|
1076 class="directory">.hg/patches</filename> directory as a
|
bos@558
|
1077 repository; when you prepare a repository for working with
|
bos@559
|
1078 patches using <command role="hg-ext-mq">qinit</command>, you
|
bos@559
|
1079 can pass the <option role="hg-ext-mq-cmd-qinit-opt">hg
|
bos@559
|
1080 -c</option> option to create the <filename role="special"
|
bos@558
|
1081 class="directory">.hg/patches</filename> directory as a
|
bos@558
|
1082 Mercurial repository.</para>
|
bos@558
|
1083
|
bos@558
|
1084 <note>
|
bos@584
|
1085 <para id="x_428"> If you forget to use the <option
|
bos@559
|
1086 role="hg-ext-mq-cmd-qinit-opt">hg -c</option> option, you
|
bos@559
|
1087 can simply go into the <filename role="special"
|
bos@558
|
1088 class="directory">.hg/patches</filename> directory at any
|
bos@559
|
1089 time and run <command role="hg-cmd">hg init</command>.
|
bos@559
|
1090 Don't forget to add an entry for the <filename
|
bos@558
|
1091 role="special">status</filename> file to the <filename
|
bos@558
|
1092 role="special">.hgignore</filename> file, though</para>
|
bos@558
|
1093
|
bos@584
|
1094 <para id="x_429"> (<command role="hg-cmd">hg qinit <option
|
bos@559
|
1095 role="hg-ext-mq-cmd-qinit-opt">hg -c</option></command>
|
bos@558
|
1096 does this for you automatically); you
|
bos@558
|
1097 <emphasis>really</emphasis> don't want to manage the
|
bos@558
|
1098 <filename role="special">status</filename> file.</para>
|
bos@558
|
1099 </note>
|
bos@558
|
1100
|
bos@584
|
1101 <para id="x_42a">As a convenience, if MQ notices that the <filename
|
bos@558
|
1102 class="directory">.hg/patches</filename> directory is a
|
bos@558
|
1103 repository, it will automatically <command role="hg-cmd">hg
|
bos@558
|
1104 add</command> every patch that you create and import.</para>
|
bos@558
|
1105
|
bos@584
|
1106 <para id="x_42b">MQ provides a shortcut command, <command
|
bos@559
|
1107 role="hg-ext-mq">qcommit</command>, that runs <command
|
bos@558
|
1108 role="hg-cmd">hg commit</command> in the <filename
|
bos@558
|
1109 role="special" class="directory">.hg/patches</filename>
|
bos@558
|
1110 directory. This saves some bothersome typing.</para>
|
bos@558
|
1111
|
bos@584
|
1112 <para id="x_42c">Finally, as a convenience to manage the patch directory,
|
bos@558
|
1113 you can define the alias <command>mq</command> on Unix
|
bos@558
|
1114 systems. For example, on Linux systems using the
|
bos@558
|
1115 <command>bash</command> shell, you can include the following
|
bos@559
|
1116 snippet in your <filename
|
bos@559
|
1117 role="home">~/.bashrc</filename>.</para>
|
bos@559
|
1118
|
bos@580
|
1119 <programlisting>alias mq=`hg -R $(hg root)/.hg/patches'</programlisting>
|
bos@558
|
1120
|
bos@584
|
1121 <para id="x_42d">You can then issue commands of the form <command>mq
|
bos@558
|
1122 pull</command> from the main repository.</para>
|
bos@682
|
1123 </sect2>
|
bos@682
|
1124
|
bos@558
|
1125 <sect2>
|
bos@558
|
1126 <title>A few things to watch out for</title>
|
bos@558
|
1127
|
bos@584
|
1128 <para id="x_42e">MQ's support for working with a repository full of patches
|
bos@558
|
1129 is limited in a few small respects.</para>
|
bos@558
|
1130
|
bos@584
|
1131 <para id="x_42f">MQ cannot automatically detect changes that you make to
|
bos@558
|
1132 the patch directory. If you <command role="hg-cmd">hg
|
bos@558
|
1133 pull</command>, manually edit, or <command role="hg-cmd">hg
|
bos@558
|
1134 update</command> changes to patches or the <filename
|
bos@558
|
1135 role="special">series</filename> file, you will have to
|
bos@558
|
1136 <command role="hg-cmd">hg qpop <option
|
bos@559
|
1137 role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> and
|
bos@558
|
1138 then <command role="hg-cmd">hg qpush <option
|
bos@559
|
1139 role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> in
|
bos@558
|
1140 the underlying repository to see those changes show up there.
|
bos@558
|
1141 If you forget to do this, you can confuse MQ's idea of which
|
bos@558
|
1142 patches are applied.</para>
|
bos@558
|
1143
|
bos@558
|
1144 </sect2>
|
bos@558
|
1145 </sect1>
|
bos@558
|
1146 <sect1 id="sec:mq:tools">
|
bos@558
|
1147 <title>Third party tools for working with patches</title>
|
bos@558
|
1148
|
bos@584
|
1149 <para id="x_430">Once you've been working with patches for a while, you'll
|
bos@558
|
1150 find yourself hungry for tools that will help you to understand
|
bos@558
|
1151 and manipulate the patches you're dealing with.</para>
|
bos@558
|
1152
|
bos@584
|
1153 <para id="x_431">The <command>diffstat</command> command
|
bos@558
|
1154 <citation>web:diffstat</citation> generates a histogram of the
|
bos@558
|
1155 modifications made to each file in a patch. It provides a good
|
bos@559
|
1156 way to <quote>get a sense of</quote> a patch&emdash;which files
|
bos@559
|
1157 it affects, and how much change it introduces to each file and
|
bos@559
|
1158 as a whole. (I find that it's a good idea to use
|
bos@558
|
1159 <command>diffstat</command>'s <option
|
bos@558
|
1160 role="cmd-opt-diffstat">-p</option> option as a matter of
|
bos@558
|
1161 course, as otherwise it will try to do clever things with
|
bos@558
|
1162 prefixes of file names that inevitably confuse at least
|
bos@558
|
1163 me.)</para>
|
bos@558
|
1164
|
bos@567
|
1165 &interaction.mq.tools.tools;
|
bos@558
|
1166
|
bos@584
|
1167 <para id="x_432">The <literal role="package">patchutils</literal> package
|
bos@558
|
1168 <citation>web:patchutils</citation> is invaluable. It provides a
|
bos@558
|
1169 set of small utilities that follow the <quote>Unix
|
bos@558
|
1170 philosophy;</quote> each does one useful thing with a patch.
|
bos@558
|
1171 The <literal role="package">patchutils</literal> command I use
|
bos@558
|
1172 most is <command>filterdiff</command>, which extracts subsets
|
bos@558
|
1173 from a patch file. For example, given a patch that modifies
|
bos@558
|
1174 hundreds of files across dozens of directories, a single
|
bos@558
|
1175 invocation of <command>filterdiff</command> can generate a
|
bos@558
|
1176 smaller patch that only touches files whose names match a
|
bos@592
|
1177 particular glob pattern. See <xref
|
bos@558
|
1178 linkend="mq-collab:tips:interdiff"/> for another
|
bos@558
|
1179 example.</para>
|
bos@558
|
1180
|
bos@558
|
1181 </sect1>
|
bos@558
|
1182 <sect1>
|
bos@558
|
1183 <title>Good ways to work with patches</title>
|
bos@558
|
1184
|
bos@584
|
1185 <para id="x_433">Whether you are working on a patch series to submit to a
|
bos@558
|
1186 free software or open source project, or a series that you
|
bos@558
|
1187 intend to treat as a sequence of regular changesets when you're
|
bos@558
|
1188 done, you can use some simple techniques to keep your work well
|
bos@674
|
1189 organized.</para>
|
bos@558
|
1190
|
bos@584
|
1191 <para id="x_434">Give your patches descriptive names. A good name for a
|
bos@558
|
1192 patch might be <filename>rework-device-alloc.patch</filename>,
|
bos@558
|
1193 because it will immediately give you a hint what the purpose of
|
bos@558
|
1194 the patch is. Long names shouldn't be a problem; you won't be
|
bos@558
|
1195 typing the names often, but you <emphasis>will</emphasis> be
|
bos@558
|
1196 running commands like <command
|
bos@559
|
1197 role="hg-ext-mq">qapplied</command> and <command
|
bos@559
|
1198 role="hg-ext-mq">qtop</command> over and over. Good naming
|
bos@558
|
1199 becomes especially important when you have a number of patches
|
bos@558
|
1200 to work with, or if you are juggling a number of different tasks
|
bos@558
|
1201 and your patches only get a fraction of your attention.</para>
|
bos@558
|
1202
|
bos@584
|
1203 <para id="x_435">Be aware of what patch you're working on. Use the <command
|
bos@559
|
1204 role="hg-ext-mq">qtop</command> command and skim over the text
|
bos@558
|
1205 of your patches frequently&emdash;for example, using <command
|
bos@558
|
1206 role="hg-cmd">hg tip <option
|
bos@559
|
1207 role="hg-opt-tip">-p</option></command>)&emdash;to be sure
|
bos@559
|
1208 of where you stand. I have several times worked on and <command
|
bos@559
|
1209 role="hg-ext-mq">qrefresh</command>ed a patch other than the
|
bos@558
|
1210 one I intended, and it's often tricky to migrate changes into
|
bos@558
|
1211 the right patch after making them in the wrong one.</para>
|
bos@558
|
1212
|
bos@584
|
1213 <para id="x_436">For this reason, it is very much worth investing a little
|
bos@558
|
1214 time to learn how to use some of the third-party tools I
|
bos@592
|
1215 described in <xref linkend="sec:mq:tools"/>,
|
bos@559
|
1216 particularly
|
bos@559
|
1217 <command>diffstat</command> and <command>filterdiff</command>.
|
bos@559
|
1218 The former will give you a quick idea of what changes your patch
|
bos@559
|
1219 is making, while the latter makes it easy to splice hunks
|
bos@559
|
1220 selectively out of one patch and into another.</para>
|
bos@558
|
1221
|
bos@558
|
1222 </sect1>
|
bos@558
|
1223 <sect1>
|
bos@558
|
1224 <title>MQ cookbook</title>
|
bos@558
|
1225
|
bos@558
|
1226 <sect2>
|
bos@558
|
1227 <title>Manage <quote>trivial</quote> patches</title>
|
bos@558
|
1228
|
bos@584
|
1229 <para id="x_437">Because the overhead of dropping files into a new
|
bos@558
|
1230 Mercurial repository is so low, it makes a lot of sense to
|
bos@558
|
1231 manage patches this way even if you simply want to make a few
|
bos@558
|
1232 changes to a source tarball that you downloaded.</para>
|
bos@558
|
1233
|
bos@584
|
1234 <para id="x_438">Begin by downloading and unpacking the source tarball, and
|
bos@567
|
1235 turning it into a Mercurial repository.</para>
|
bos@567
|
1236
|
bos@567
|
1237 &interaction.mq.tarball.download;
|
bos@558
|
1238
|
bos@584
|
1239 <para id="x_439">Continue by creating a patch stack and making your
|
bos@567
|
1240 changes.</para>
|
bos@567
|
1241
|
bos@567
|
1242 &interaction.mq.tarball.qinit;
|
bos@558
|
1243
|
bos@584
|
1244 <para id="x_43a">Let's say a few weeks or months pass, and your package
|
bos@558
|
1245 author releases a new version. First, bring their changes
|
bos@567
|
1246 into the repository.</para>
|
bos@567
|
1247
|
bos@567
|
1248 &interaction.mq.tarball.newsource;
|
bos@567
|
1249
|
bos@584
|
1250 <para id="x_43b">The pipeline starting with <command role="hg-cmd">hg
|
bos@558
|
1251 locate</command> above deletes all files in the working
|
bos@558
|
1252 directory, so that <command role="hg-cmd">hg
|
bos@558
|
1253 commit</command>'s <option
|
bos@558
|
1254 role="hg-opt-commit">--addremove</option> option can
|
bos@558
|
1255 actually tell which files have really been removed in the
|
bos@558
|
1256 newer version of the source.</para>
|
bos@558
|
1257
|
bos@584
|
1258 <para id="x_43c">Finally, you can apply your patches on top of the new
|
bos@567
|
1259 tree.</para>
|
bos@567
|
1260
|
bos@567
|
1261 &interaction.mq.tarball.repush;
|
bos@682
|
1262 </sect2>
|
bos@682
|
1263
|
bos@558
|
1264 <sect2 id="sec:mq:combine">
|
bos@558
|
1265 <title>Combining entire patches</title>
|
bos@558
|
1266
|
bos@584
|
1267 <para id="x_43d">MQ provides a command, <command
|
bos@559
|
1268 role="hg-ext-mq">qfold</command> that lets you combine
|
bos@558
|
1269 entire patches. This <quote>folds</quote> the patches you
|
bos@558
|
1270 name, in the order you name them, into the topmost applied
|
bos@558
|
1271 patch, and concatenates their descriptions onto the end of its
|
bos@558
|
1272 description. The patches that you fold must be unapplied
|
bos@558
|
1273 before you fold them.</para>
|
bos@558
|
1274
|
bos@584
|
1275 <para id="x_43e">The order in which you fold patches matters. If your
|
bos@558
|
1276 topmost applied patch is <literal>foo</literal>, and you
|
bos@559
|
1277 <command role="hg-ext-mq">qfold</command>
|
bos@558
|
1278 <literal>bar</literal> and <literal>quux</literal> into it,
|
bos@558
|
1279 you will end up with a patch that has the same effect as if
|
bos@558
|
1280 you applied first <literal>foo</literal>, then
|
bos@558
|
1281 <literal>bar</literal>, followed by
|
bos@558
|
1282 <literal>quux</literal>.</para>
|
bos@682
|
1283 </sect2>
|
bos@682
|
1284
|
bos@558
|
1285 <sect2>
|
bos@558
|
1286 <title>Merging part of one patch into another</title>
|
bos@558
|
1287
|
bos@584
|
1288 <para id="x_43f">Merging <emphasis>part</emphasis> of one patch into
|
bos@558
|
1289 another is more difficult than combining entire
|
bos@558
|
1290 patches.</para>
|
bos@558
|
1291
|
bos@584
|
1292 <para id="x_440">If you want to move changes to entire files, you can use
|
bos@558
|
1293 <command>filterdiff</command>'s <option
|
bos@558
|
1294 role="cmd-opt-filterdiff">-i</option> and <option
|
bos@558
|
1295 role="cmd-opt-filterdiff">-x</option> options to choose the
|
bos@558
|
1296 modifications to snip out of one patch, concatenating its
|
bos@558
|
1297 output onto the end of the patch you want to merge into. You
|
bos@558
|
1298 usually won't need to modify the patch you've merged the
|
bos@558
|
1299 changes from. Instead, MQ will report some rejected hunks
|
bos@559
|
1300 when you <command role="hg-ext-mq">qpush</command> it (from
|
bos@558
|
1301 the hunks you moved into the other patch), and you can simply
|
bos@559
|
1302 <command role="hg-ext-mq">qrefresh</command> the patch to drop
|
bos@558
|
1303 the duplicate hunks.</para>
|
bos@558
|
1304
|
bos@584
|
1305 <para id="x_441">If you have a patch that has multiple hunks modifying a
|
bos@558
|
1306 file, and you only want to move a few of those hunks, the job
|
bos@558
|
1307 becomes more messy, but you can still partly automate it. Use
|
bos@558
|
1308 <command>lsdiff -nvv</command> to print some metadata about
|
bos@567
|
1309 the patch.</para>
|
bos@567
|
1310
|
bos@567
|
1311 &interaction.mq.tools.lsdiff;
|
bos@558
|
1312
|
bos@584
|
1313 <para id="x_442">This command prints three different kinds of
|
bos@558
|
1314 number:</para>
|
bos@558
|
1315 <itemizedlist>
|
bos@584
|
1316 <listitem><para id="x_443">(in the first column) a <emphasis>file
|
bos@558
|
1317 number</emphasis> to identify each file modified in the
|
bos@559
|
1318 patch;</para>
|
bos@559
|
1319 </listitem>
|
bos@584
|
1320 <listitem><para id="x_444">(on the next line, indented) the line number
|
bos@559
|
1321 within a modified file where a hunk starts; and</para>
|
bos@559
|
1322 </listitem>
|
bos@584
|
1323 <listitem><para id="x_445">(on the same line) a <emphasis>hunk
|
bos@559
|
1324 number</emphasis> to identify that hunk.</para>
|
bos@559
|
1325 </listitem></itemizedlist>
|
bos@558
|
1326
|
bos@584
|
1327 <para id="x_446">You'll have to use some visual inspection, and reading of
|
bos@558
|
1328 the patch, to identify the file and hunk numbers you'll want,
|
bos@558
|
1329 but you can then pass them to to
|
bos@558
|
1330 <command>filterdiff</command>'s <option
|
bos@558
|
1331 role="cmd-opt-filterdiff">--files</option> and <option
|
bos@558
|
1332 role="cmd-opt-filterdiff">--hunks</option> options, to
|
bos@558
|
1333 select exactly the file and hunk you want to extract.</para>
|
bos@558
|
1334
|
bos@584
|
1335 <para id="x_447">Once you have this hunk, you can concatenate it onto the
|
bos@558
|
1336 end of your destination patch and continue with the remainder
|
bos@592
|
1337 of <xref linkend="sec:mq:combine"/>.</para>
|
bos@558
|
1338
|
bos@558
|
1339 </sect2>
|
bos@558
|
1340 </sect1>
|
bos@558
|
1341 <sect1>
|
bos@558
|
1342 <title>Differences between quilt and MQ</title>
|
bos@558
|
1343
|
bos@584
|
1344 <para id="x_448">If you are already familiar with quilt, MQ provides a
|
bos@558
|
1345 similar command set. There are a few differences in the way
|
bos@558
|
1346 that it works.</para>
|
bos@558
|
1347
|
bos@584
|
1348 <para id="x_449">You will already have noticed that most quilt commands have
|
bos@558
|
1349 MQ counterparts that simply begin with a
|
bos@558
|
1350 <quote><literal>q</literal></quote>. The exceptions are quilt's
|
bos@558
|
1351 <literal>add</literal> and <literal>remove</literal> commands,
|
bos@558
|
1352 the counterparts for which are the normal Mercurial <command
|
bos@558
|
1353 role="hg-cmd">hg add</command> and <command role="hg-cmd">hg
|
bos@558
|
1354 remove</command> commands. There is no MQ equivalent of the
|
bos@558
|
1355 quilt <literal>edit</literal> command.</para>
|
bos@558
|
1356
|
bos@558
|
1357 </sect1>
|
bos@558
|
1358 </chapter>
|
bos@558
|
1359
|
bos@558
|
1360 <!--
|
bos@558
|
1361 local variables:
|
bos@558
|
1362 sgml-parent-document: ("00book.xml" "book" "chapter")
|
bos@558
|
1363 end:
|
bos@558
|
1364 -->
|