hgbook
annotate en/ch12-mq.xml @ 1114:527b86d55d4a
inotify: update installation information
inotify is shipped in Mercurial since 1.0, which greatly simplifies the installation process
inotify is shipped in Mercurial since 1.0, which greatly simplifies the installation process
author | Nicolas Dumazet <nicdumz.commits@gmail.com> |
---|---|
date | Sun Dec 13 16:35:56 2009 +0900 (2009-12-13) |
parents | acf9dc5f088d |
children |
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@689 | 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 |
steve@872 | 441 role="hg-ext-mq-cmd-qpush-opt">-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 |
steve@872 | 472 role="hg-ext-mq-cmd-qnew-opt">-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 |
steve@872 | 475 role="hg-ext-mq-cmd-qpop-opt">-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@689 | 769 <para id="x_6dd">Once you're done working on a patch and want to |
bos@689 | 770 turn it into a permanent changeset, use the <command |
bos@689 | 771 role="hg-ext-mq">hg qfinish</command> command. Pass a revision |
bos@689 | 772 to the command to identify the patch that you want to turn into |
bos@689 | 773 a regular changeset; this patch must already be applied.</para> |
bos@682 | 774 |
bos@682 | 775 &interaction.ch11-qdelete.convert; |
bos@682 | 776 |
bos@689 | 777 <para id="x_6e0">The <command role="hg-ext-mq">hg qfinish</command> command |
bos@689 | 778 accepts an <option>--all</option> or <option>-a</option> |
bos@689 | 779 option, which turns all applied patches into regular |
bos@689 | 780 changesets.</para> |
bos@689 | 781 |
bos@684 | 782 <para id="x_6de">It is also possible to turn an existing changeset into a |
bos@682 | 783 patch, by passing the <option>-r</option> option to <command |
bos@682 | 784 role="hg-ext-mq">hg qimport</command>.</para> |
bos@682 | 785 |
bos@682 | 786 &interaction.ch11-qdelete.import; |
bos@682 | 787 |
bos@684 | 788 <para id="x_6df">Note that it only makes sense to convert a changeset into |
bos@682 | 789 a patch if you have not propagated that changeset into any |
bos@682 | 790 other repositories. The imported changeset's ID will change |
bos@682 | 791 every time you refresh the patch, which will make Mercurial |
bos@682 | 792 treat it as unrelated to the original changeset if you have |
bos@682 | 793 pushed it somewhere else.</para> |
bos@682 | 794 </sect2> |
bos@682 | 795 </sect1> |
bos@682 | 796 |
bos@558 | 797 <sect1 id="sec:mq:perf"> |
bos@558 | 798 <title>Getting the best performance out of MQ</title> |
bos@558 | 799 |
bos@683 | 800 <para id="x_403">MQ is very efficient at handling a large number |
bos@683 | 801 of patches. I ran some performance experiments in mid-2006 for a |
bos@683 | 802 talk that I gave at the 2006 EuroPython conference (on modern |
bos@683 | 803 hardware, you should expect better performance than you'll see |
bos@683 | 804 below). I used as my data set the Linux 2.6.17-mm1 patch |
bos@683 | 805 series, which consists of 1,738 patches. I applied these on top |
bos@683 | 806 of a Linux kernel repository containing all 27,472 revisions |
bos@683 | 807 between Linux 2.6.12-rc2 and Linux 2.6.17.</para> |
bos@558 | 808 |
bos@584 | 809 <para id="x_404">On my old, slow laptop, I was able to <command |
bos@558 | 810 role="hg-cmd">hg qpush <option |
steve@872 | 811 role="hg-ext-mq-cmd-qpush-opt">-a</option></command> all |
bos@558 | 812 1,738 patches in 3.5 minutes, and <command role="hg-cmd">hg qpop |
steve@872 | 813 <option role="hg-ext-mq-cmd-qpop-opt">-a</option></command> |
bos@558 | 814 them all in 30 seconds. (On a newer laptop, the time to push |
bos@558 | 815 all patches dropped to two minutes.) I could <command |
bos@559 | 816 role="hg-ext-mq">qrefresh</command> one of the biggest patches |
bos@558 | 817 (which made 22,779 lines of changes to 287 files) in 6.6 |
bos@558 | 818 seconds.</para> |
bos@558 | 819 |
bos@584 | 820 <para id="x_405">Clearly, MQ is well suited to working in large trees, but |
bos@558 | 821 there are a few tricks you can use to get the best performance |
bos@558 | 822 of it.</para> |
bos@558 | 823 |
bos@584 | 824 <para id="x_406">First of all, try to <quote>batch</quote> operations |
bos@558 | 825 together. Every time you run <command |
bos@559 | 826 role="hg-ext-mq">qpush</command> or <command |
bos@559 | 827 role="hg-ext-mq">qpop</command>, these commands scan the |
bos@558 | 828 working directory once to make sure you haven't made some |
bos@558 | 829 changes and then forgotten to run <command |
bos@559 | 830 role="hg-ext-mq">qrefresh</command>. On a small tree, the |
bos@558 | 831 time that this scan takes is unnoticeable. However, on a |
bos@558 | 832 medium-sized tree (containing tens of thousands of files), it |
bos@558 | 833 can take a second or more.</para> |
bos@558 | 834 |
bos@584 | 835 <para id="x_407">The <command role="hg-ext-mq">qpush</command> and <command |
bos@559 | 836 role="hg-ext-mq">qpop</command> commands allow you to push and |
bos@558 | 837 pop multiple patches at a time. You can identify the |
bos@558 | 838 <quote>destination patch</quote> that you want to end up at. |
bos@559 | 839 When you <command role="hg-ext-mq">qpush</command> with a |
bos@558 | 840 destination specified, it will push patches until that patch is |
bos@558 | 841 at the top of the applied stack. When you <command |
bos@559 | 842 role="hg-ext-mq">qpop</command> to a destination, MQ will pop |
bos@558 | 843 patches until the destination patch is at the top.</para> |
bos@558 | 844 |
bos@584 | 845 <para id="x_408">You can identify a destination patch using either the name |
bos@558 | 846 of the patch, or by number. If you use numeric addressing, |
bos@558 | 847 patches are counted from zero; this means that the first patch |
bos@558 | 848 is zero, the second is one, and so on.</para> |
bos@682 | 849 </sect1> |
bos@682 | 850 |
bos@558 | 851 <sect1 id="sec:mq:merge"> |
bos@558 | 852 <title>Updating your patches when the underlying code |
bos@558 | 853 changes</title> |
bos@558 | 854 |
bos@584 | 855 <para id="x_409">It's common to have a stack of patches on top of an |
bos@558 | 856 underlying repository that you don't modify directly. If you're |
bos@558 | 857 working on changes to third-party code, or on a feature that is |
bos@558 | 858 taking longer to develop than the rate of change of the code |
bos@558 | 859 beneath, you will often need to sync up with the underlying |
bos@558 | 860 code, and fix up any hunks in your patches that no longer apply. |
bos@558 | 861 This is called <emphasis>rebasing</emphasis> your patch |
bos@558 | 862 series.</para> |
bos@558 | 863 |
bos@584 | 864 <para id="x_40a">The simplest way to do this is to <command role="hg-cmd">hg |
bos@559 | 865 qpop <option role="hg-ext-mq-cmd-qpop-opt">hg |
bos@559 | 866 -a</option></command> your patches, then <command |
bos@559 | 867 role="hg-cmd">hg pull</command> changes into the underlying |
bos@559 | 868 repository, and finally <command role="hg-cmd">hg qpush <option |
steve@872 | 869 role="hg-ext-mq-cmd-qpop-opt">-a</option></command> your |
bos@558 | 870 patches again. MQ will stop pushing any time it runs across a |
bos@558 | 871 patch that fails to apply during conflicts, allowing you to fix |
bos@559 | 872 your conflicts, <command role="hg-ext-mq">qrefresh</command> the |
bos@558 | 873 affected patch, and continue pushing until you have fixed your |
bos@558 | 874 entire stack.</para> |
bos@558 | 875 |
bos@584 | 876 <para id="x_40b">This approach is easy to use and works well if you don't |
bos@558 | 877 expect changes to the underlying code to affect how well your |
bos@558 | 878 patches apply. If your patch stack touches code that is modified |
bos@558 | 879 frequently or invasively in the underlying repository, however, |
bos@558 | 880 fixing up rejected hunks by hand quickly becomes |
bos@558 | 881 tiresome.</para> |
bos@558 | 882 |
bos@584 | 883 <para id="x_40c">It's possible to partially automate the rebasing process. |
bos@559 | 884 If your patches apply cleanly against some revision of the |
bos@558 | 885 underlying repo, MQ can use this information to help you to |
bos@558 | 886 resolve conflicts between your patches and a different |
bos@558 | 887 revision.</para> |
bos@558 | 888 |
bos@584 | 889 <para id="x_40d">The process is a little involved.</para> |
bos@558 | 890 <orderedlist> |
bos@584 | 891 <listitem><para id="x_40e">To begin, <command role="hg-cmd">hg qpush |
bos@558 | 892 -a</command> all of your patches on top of the revision |
bos@559 | 893 where you know that they apply cleanly.</para> |
bos@559 | 894 </listitem> |
bos@584 | 895 <listitem><para id="x_40f">Save a backup copy of your patch directory using |
bos@558 | 896 <command role="hg-cmd">hg qsave <option |
bos@559 | 897 role="hg-ext-mq-cmd-qsave-opt">hg -e</option> <option |
bos@559 | 898 role="hg-ext-mq-cmd-qsave-opt">hg -c</option></command>. |
bos@558 | 899 This prints the name of the directory that it has saved the |
bos@558 | 900 patches in. It will save the patches to a directory called |
bos@558 | 901 <filename role="special" |
bos@558 | 902 class="directory">.hg/patches.N</filename>, where |
bos@558 | 903 <literal>N</literal> is a small integer. It also commits a |
bos@558 | 904 <quote>save changeset</quote> on top of your applied |
bos@558 | 905 patches; this is for internal book-keeping, and records the |
bos@558 | 906 states of the <filename role="special">series</filename> and |
bos@559 | 907 <filename role="special">status</filename> files.</para> |
bos@559 | 908 </listitem> |
bos@584 | 909 <listitem><para id="x_410">Use <command role="hg-cmd">hg pull</command> to |
bos@559 | 910 bring new changes into the underlying repository. (Don't |
bos@559 | 911 run <command role="hg-cmd">hg pull -u</command>; see below |
bos@559 | 912 for why.)</para> |
bos@559 | 913 </listitem> |
bos@584 | 914 <listitem><para id="x_411">Update to the new tip revision, using <command |
bos@558 | 915 role="hg-cmd">hg update <option |
bos@558 | 916 role="hg-opt-update">-C</option></command> to override |
bos@559 | 917 the patches you have pushed.</para> |
bos@559 | 918 </listitem> |
bos@584 | 919 <listitem><para id="x_412">Merge all patches using <command>hg qpush -m |
bos@580 | 920 -a</command>. The <option |
bos@580 | 921 role="hg-ext-mq-cmd-qpush-opt">-m</option> option to |
bos@559 | 922 <command role="hg-ext-mq">qpush</command> tells MQ to |
bos@558 | 923 perform a three-way merge if the patch fails to |
bos@559 | 924 apply.</para> |
bos@559 | 925 </listitem></orderedlist> |
bos@558 | 926 |
bos@584 | 927 <para id="x_413">During the <command role="hg-cmd">hg qpush <option |
bos@559 | 928 role="hg-ext-mq-cmd-qpush-opt">hg -m</option></command>, |
bos@559 | 929 each patch in the <filename role="special">series</filename> |
bos@559 | 930 file is applied normally. If a patch applies with fuzz or |
bos@559 | 931 rejects, MQ looks at the queue you <command |
bos@559 | 932 role="hg-ext-mq">qsave</command>d, and performs a three-way |
bos@558 | 933 merge with the corresponding changeset. This merge uses |
bos@558 | 934 Mercurial's normal merge machinery, so it may pop up a GUI merge |
bos@558 | 935 tool to help you to resolve problems.</para> |
bos@558 | 936 |
bos@584 | 937 <para id="x_414">When you finish resolving the effects of a patch, MQ |
bos@558 | 938 refreshes your patch based on the result of the merge.</para> |
bos@558 | 939 |
bos@584 | 940 <para id="x_415">At the end of this process, your repository will have one |
bos@558 | 941 extra head from the old patch queue, and a copy of the old patch |
bos@558 | 942 queue will be in <filename role="special" |
bos@558 | 943 class="directory">.hg/patches.N</filename>. You can remove the |
bos@559 | 944 extra head using <command role="hg-cmd">hg qpop -a -n |
bos@558 | 945 patches.N</command> or <command role="hg-cmd">hg |
bos@558 | 946 strip</command>. You can delete <filename role="special" |
bos@558 | 947 class="directory">.hg/patches.N</filename> once you are sure |
bos@558 | 948 that you no longer need it as a backup.</para> |
bos@682 | 949 </sect1> |
bos@682 | 950 |
bos@558 | 951 <sect1> |
bos@558 | 952 <title>Identifying patches</title> |
bos@558 | 953 |
bos@584 | 954 <para id="x_416">MQ commands that work with patches let you refer to a patch |
bos@558 | 955 either by using its name or by a number. By name is obvious |
bos@558 | 956 enough; pass the name <filename>foo.patch</filename> to <command |
bos@559 | 957 role="hg-ext-mq">qpush</command>, for example, and it will |
bos@558 | 958 push patches until <filename>foo.patch</filename> is |
bos@558 | 959 applied.</para> |
bos@558 | 960 |
bos@584 | 961 <para id="x_417">As a shortcut, you can refer to a patch using both a name |
bos@558 | 962 and a numeric offset; <literal>foo.patch-2</literal> means |
bos@558 | 963 <quote>two patches before <literal>foo.patch</literal></quote>, |
bos@558 | 964 while <literal>bar.patch+4</literal> means <quote>four patches |
bos@558 | 965 after <literal>bar.patch</literal></quote>.</para> |
bos@558 | 966 |
bos@584 | 967 <para id="x_418">Referring to a patch by index isn't much different. The |
bos@558 | 968 first patch printed in the output of <command |
bos@559 | 969 role="hg-ext-mq">qseries</command> is patch zero (yes, it's |
bos@558 | 970 one of those start-at-zero counting systems); the second is |
bos@558 | 971 patch one; and so on.</para> |
bos@558 | 972 |
bos@584 | 973 <para id="x_419">MQ also makes it easy to work with patches when you are |
bos@558 | 974 using normal Mercurial commands. Every command that accepts a |
bos@558 | 975 changeset ID will also accept the name of an applied patch. MQ |
bos@558 | 976 augments the tags normally in the repository with an eponymous |
bos@558 | 977 one for each applied patch. In addition, the special tags |
bos@580 | 978 <literal role="tag">qbase</literal> and |
bos@580 | 979 <literal role="tag">qtip</literal> identify |
bos@558 | 980 the <quote>bottom-most</quote> and topmost applied patches, |
bos@558 | 981 respectively.</para> |
bos@558 | 982 |
bos@584 | 983 <para id="x_41a">These additions to Mercurial's normal tagging capabilities |
bos@558 | 984 make dealing with patches even more of a breeze.</para> |
bos@558 | 985 <itemizedlist> |
bos@584 | 986 <listitem><para id="x_41b">Want to patchbomb a mailing list with your |
bos@558 | 987 latest series of changes?</para> |
bos@580 | 988 <programlisting>hg email qbase:qtip</programlisting> |
bos@584 | 989 <para id="x_41c"> (Don't know what <quote>patchbombing</quote> is? See |
bos@592 | 990 <xref linkend="sec:hgext:patchbomb"/>.)</para> |
bos@559 | 991 </listitem> |
bos@584 | 992 <listitem><para id="x_41d">Need to see all of the patches since |
bos@558 | 993 <literal>foo.patch</literal> that have touched files in a |
bos@558 | 994 subdirectory of your tree?</para> |
bos@580 | 995 <programlisting>hg log -r foo.patch:qtip subdir</programlisting> |
bos@559 | 996 </listitem> |
bos@558 | 997 </itemizedlist> |
bos@558 | 998 |
bos@584 | 999 <para id="x_41e">Because MQ makes the names of patches available to the rest |
bos@558 | 1000 of Mercurial through its normal internal tag machinery, you |
bos@558 | 1001 don't need to type in the entire name of a patch when you want |
bos@558 | 1002 to identify it by name.</para> |
bos@558 | 1003 |
bos@584 | 1004 <para id="x_41f">Another nice consequence of representing patch names as tags |
bos@558 | 1005 is that when you run the <command role="hg-cmd">hg log</command> |
bos@558 | 1006 command, it will display a patch's name as a tag, simply as part |
bos@558 | 1007 of its normal output. This makes it easy to visually |
bos@558 | 1008 distinguish applied patches from underlying |
bos@559 | 1009 <quote>normal</quote> revisions. The following example shows a |
bos@559 | 1010 few normal Mercurial commands in use with applied |
bos@559 | 1011 patches.</para> |
bos@559 | 1012 |
bos@682 | 1013 &interaction.mq.id.output; |
bos@682 | 1014 </sect1> |
bos@682 | 1015 |
bos@558 | 1016 <sect1> |
bos@558 | 1017 <title>Useful things to know about</title> |
bos@558 | 1018 |
bos@584 | 1019 <para id="x_420">There are a number of aspects of MQ usage that don't fit |
bos@558 | 1020 tidily into sections of their own, but that are good to know. |
bos@558 | 1021 Here they are, in one place.</para> |
bos@558 | 1022 |
bos@558 | 1023 <itemizedlist> |
bos@584 | 1024 <listitem><para id="x_421">Normally, when you <command |
bos@559 | 1025 role="hg-ext-mq">qpop</command> a patch and <command |
bos@559 | 1026 role="hg-ext-mq">qpush</command> it again, the changeset |
bos@558 | 1027 that represents the patch after the pop/push will have a |
bos@558 | 1028 <emphasis>different identity</emphasis> than the changeset |
bos@592 | 1029 that represented the hash beforehand. See <xref |
bos@559 | 1030 linkend="sec:mqref:cmd:qpush"/> for |
bos@559 | 1031 information as to why this is.</para> |
bos@559 | 1032 </listitem> |
bos@584 | 1033 <listitem><para id="x_422">It's not a good idea to <command |
bos@558 | 1034 role="hg-cmd">hg merge</command> changes from another |
bos@558 | 1035 branch with a patch changeset, at least if you want to |
bos@558 | 1036 maintain the <quote>patchiness</quote> of that changeset and |
bos@558 | 1037 changesets below it on the patch stack. If you try to do |
bos@558 | 1038 this, it will appear to succeed, but MQ will become |
bos@559 | 1039 confused.</para> |
bos@559 | 1040 </listitem></itemizedlist> |
bos@682 | 1041 </sect1> |
bos@682 | 1042 |
bos@558 | 1043 <sect1 id="sec:mq:repo"> |
bos@558 | 1044 <title>Managing patches in a repository</title> |
bos@558 | 1045 |
bos@584 | 1046 <para id="x_423">Because MQ's <filename role="special" |
bos@558 | 1047 class="directory">.hg/patches</filename> directory resides |
bos@558 | 1048 outside a Mercurial repository's working directory, the |
bos@558 | 1049 <quote>underlying</quote> Mercurial repository knows nothing |
bos@558 | 1050 about the management or presence of patches.</para> |
bos@558 | 1051 |
bos@584 | 1052 <para id="x_424">This presents the interesting possibility of managing the |
bos@558 | 1053 contents of the patch directory as a Mercurial repository in its |
bos@558 | 1054 own right. This can be a useful way to work. For example, you |
bos@558 | 1055 can work on a patch for a while, <command |
bos@559 | 1056 role="hg-ext-mq">qrefresh</command> it, then <command |
bos@558 | 1057 role="hg-cmd">hg commit</command> the current state of the |
bos@558 | 1058 patch. This lets you <quote>roll back</quote> to that version |
bos@558 | 1059 of the patch later on.</para> |
bos@558 | 1060 |
bos@584 | 1061 <para id="x_425">You can then share different versions of the same patch |
bos@558 | 1062 stack among multiple underlying repositories. I use this when I |
bos@558 | 1063 am developing a Linux kernel feature. I have a pristine copy of |
bos@558 | 1064 my kernel sources for each of several CPU architectures, and a |
bos@558 | 1065 cloned repository under each that contains the patches I am |
bos@558 | 1066 working on. When I want to test a change on a different |
bos@558 | 1067 architecture, I push my current patches to the patch repository |
bos@558 | 1068 associated with that kernel tree, pop and push all of my |
bos@558 | 1069 patches, and build and test that kernel.</para> |
bos@558 | 1070 |
bos@584 | 1071 <para id="x_426">Managing patches in a repository makes it possible for |
bos@558 | 1072 multiple developers to work on the same patch series without |
bos@558 | 1073 colliding with each other, all on top of an underlying source |
bos@558 | 1074 base that they may or may not control.</para> |
bos@558 | 1075 |
bos@558 | 1076 <sect2> |
bos@558 | 1077 <title>MQ support for patch repositories</title> |
bos@558 | 1078 |
bos@584 | 1079 <para id="x_427">MQ helps you to work with the <filename role="special" |
bos@558 | 1080 class="directory">.hg/patches</filename> directory as a |
bos@558 | 1081 repository; when you prepare a repository for working with |
bos@559 | 1082 patches using <command role="hg-ext-mq">qinit</command>, you |
bos@559 | 1083 can pass the <option role="hg-ext-mq-cmd-qinit-opt">hg |
bos@559 | 1084 -c</option> option to create the <filename role="special" |
bos@558 | 1085 class="directory">.hg/patches</filename> directory as a |
bos@558 | 1086 Mercurial repository.</para> |
bos@558 | 1087 |
bos@558 | 1088 <note> |
bos@584 | 1089 <para id="x_428"> If you forget to use the <option |
bos@559 | 1090 role="hg-ext-mq-cmd-qinit-opt">hg -c</option> option, you |
bos@559 | 1091 can simply go into the <filename role="special" |
bos@558 | 1092 class="directory">.hg/patches</filename> directory at any |
bos@559 | 1093 time and run <command role="hg-cmd">hg init</command>. |
bos@559 | 1094 Don't forget to add an entry for the <filename |
bos@558 | 1095 role="special">status</filename> file to the <filename |
bos@558 | 1096 role="special">.hgignore</filename> file, though</para> |
bos@558 | 1097 |
bos@584 | 1098 <para id="x_429"> (<command role="hg-cmd">hg qinit <option |
bos@559 | 1099 role="hg-ext-mq-cmd-qinit-opt">hg -c</option></command> |
bos@558 | 1100 does this for you automatically); you |
bos@558 | 1101 <emphasis>really</emphasis> don't want to manage the |
bos@558 | 1102 <filename role="special">status</filename> file.</para> |
bos@558 | 1103 </note> |
bos@558 | 1104 |
bos@584 | 1105 <para id="x_42a">As a convenience, if MQ notices that the <filename |
bos@558 | 1106 class="directory">.hg/patches</filename> directory is a |
bos@558 | 1107 repository, it will automatically <command role="hg-cmd">hg |
bos@558 | 1108 add</command> every patch that you create and import.</para> |
bos@558 | 1109 |
bos@584 | 1110 <para id="x_42b">MQ provides a shortcut command, <command |
bos@559 | 1111 role="hg-ext-mq">qcommit</command>, that runs <command |
bos@558 | 1112 role="hg-cmd">hg commit</command> in the <filename |
bos@558 | 1113 role="special" class="directory">.hg/patches</filename> |
bos@558 | 1114 directory. This saves some bothersome typing.</para> |
bos@558 | 1115 |
bos@584 | 1116 <para id="x_42c">Finally, as a convenience to manage the patch directory, |
bos@558 | 1117 you can define the alias <command>mq</command> on Unix |
bos@558 | 1118 systems. For example, on Linux systems using the |
bos@558 | 1119 <command>bash</command> shell, you can include the following |
bos@559 | 1120 snippet in your <filename |
bos@559 | 1121 role="home">~/.bashrc</filename>.</para> |
bos@559 | 1122 |
bos@580 | 1123 <programlisting>alias mq=`hg -R $(hg root)/.hg/patches'</programlisting> |
bos@558 | 1124 |
bos@584 | 1125 <para id="x_42d">You can then issue commands of the form <command>mq |
bos@558 | 1126 pull</command> from the main repository.</para> |
bos@682 | 1127 </sect2> |
bos@682 | 1128 |
bos@558 | 1129 <sect2> |
bos@558 | 1130 <title>A few things to watch out for</title> |
bos@558 | 1131 |
bos@584 | 1132 <para id="x_42e">MQ's support for working with a repository full of patches |
bos@558 | 1133 is limited in a few small respects.</para> |
bos@558 | 1134 |
bos@584 | 1135 <para id="x_42f">MQ cannot automatically detect changes that you make to |
bos@558 | 1136 the patch directory. If you <command role="hg-cmd">hg |
bos@558 | 1137 pull</command>, manually edit, or <command role="hg-cmd">hg |
bos@558 | 1138 update</command> changes to patches or the <filename |
bos@558 | 1139 role="special">series</filename> file, you will have to |
bos@558 | 1140 <command role="hg-cmd">hg qpop <option |
steve@872 | 1141 role="hg-ext-mq-cmd-qpop-opt">-a</option></command> and |
bos@558 | 1142 then <command role="hg-cmd">hg qpush <option |
steve@872 | 1143 role="hg-ext-mq-cmd-qpush-opt">-a</option></command> in |
bos@558 | 1144 the underlying repository to see those changes show up there. |
bos@558 | 1145 If you forget to do this, you can confuse MQ's idea of which |
bos@558 | 1146 patches are applied.</para> |
bos@558 | 1147 |
bos@558 | 1148 </sect2> |
bos@558 | 1149 </sect1> |
bos@558 | 1150 <sect1 id="sec:mq:tools"> |
bos@558 | 1151 <title>Third party tools for working with patches</title> |
bos@558 | 1152 |
bos@584 | 1153 <para id="x_430">Once you've been working with patches for a while, you'll |
bos@558 | 1154 find yourself hungry for tools that will help you to understand |
bos@558 | 1155 and manipulate the patches you're dealing with.</para> |
bos@558 | 1156 |
bos@584 | 1157 <para id="x_431">The <command>diffstat</command> command |
bos@558 | 1158 <citation>web:diffstat</citation> generates a histogram of the |
bos@558 | 1159 modifications made to each file in a patch. It provides a good |
bos@559 | 1160 way to <quote>get a sense of</quote> a patch&emdash;which files |
bos@559 | 1161 it affects, and how much change it introduces to each file and |
bos@559 | 1162 as a whole. (I find that it's a good idea to use |
bos@558 | 1163 <command>diffstat</command>'s <option |
bos@558 | 1164 role="cmd-opt-diffstat">-p</option> option as a matter of |
bos@558 | 1165 course, as otherwise it will try to do clever things with |
bos@558 | 1166 prefixes of file names that inevitably confuse at least |
bos@558 | 1167 me.)</para> |
bos@558 | 1168 |
bos@567 | 1169 &interaction.mq.tools.tools; |
bos@558 | 1170 |
bos@584 | 1171 <para id="x_432">The <literal role="package">patchutils</literal> package |
bos@558 | 1172 <citation>web:patchutils</citation> is invaluable. It provides a |
bos@558 | 1173 set of small utilities that follow the <quote>Unix |
bos@558 | 1174 philosophy;</quote> each does one useful thing with a patch. |
bos@558 | 1175 The <literal role="package">patchutils</literal> command I use |
bos@558 | 1176 most is <command>filterdiff</command>, which extracts subsets |
bos@558 | 1177 from a patch file. For example, given a patch that modifies |
bos@558 | 1178 hundreds of files across dozens of directories, a single |
bos@558 | 1179 invocation of <command>filterdiff</command> can generate a |
bos@558 | 1180 smaller patch that only touches files whose names match a |
bos@592 | 1181 particular glob pattern. See <xref |
bos@558 | 1182 linkend="mq-collab:tips:interdiff"/> for another |
bos@558 | 1183 example.</para> |
bos@558 | 1184 |
bos@558 | 1185 </sect1> |
bos@558 | 1186 <sect1> |
bos@558 | 1187 <title>Good ways to work with patches</title> |
bos@558 | 1188 |
bos@584 | 1189 <para id="x_433">Whether you are working on a patch series to submit to a |
bos@558 | 1190 free software or open source project, or a series that you |
bos@558 | 1191 intend to treat as a sequence of regular changesets when you're |
bos@558 | 1192 done, you can use some simple techniques to keep your work well |
bos@674 | 1193 organized.</para> |
bos@558 | 1194 |
bos@584 | 1195 <para id="x_434">Give your patches descriptive names. A good name for a |
bos@558 | 1196 patch might be <filename>rework-device-alloc.patch</filename>, |
bos@558 | 1197 because it will immediately give you a hint what the purpose of |
bos@558 | 1198 the patch is. Long names shouldn't be a problem; you won't be |
bos@558 | 1199 typing the names often, but you <emphasis>will</emphasis> be |
bos@558 | 1200 running commands like <command |
bos@559 | 1201 role="hg-ext-mq">qapplied</command> and <command |
bos@559 | 1202 role="hg-ext-mq">qtop</command> over and over. Good naming |
bos@558 | 1203 becomes especially important when you have a number of patches |
bos@558 | 1204 to work with, or if you are juggling a number of different tasks |
bos@558 | 1205 and your patches only get a fraction of your attention.</para> |
bos@558 | 1206 |
bos@584 | 1207 <para id="x_435">Be aware of what patch you're working on. Use the <command |
bos@559 | 1208 role="hg-ext-mq">qtop</command> command and skim over the text |
bos@558 | 1209 of your patches frequently&emdash;for example, using <command |
bos@558 | 1210 role="hg-cmd">hg tip <option |
bos@559 | 1211 role="hg-opt-tip">-p</option></command>)&emdash;to be sure |
bos@559 | 1212 of where you stand. I have several times worked on and <command |
bos@559 | 1213 role="hg-ext-mq">qrefresh</command>ed a patch other than the |
bos@558 | 1214 one I intended, and it's often tricky to migrate changes into |
bos@558 | 1215 the right patch after making them in the wrong one.</para> |
bos@558 | 1216 |
bos@584 | 1217 <para id="x_436">For this reason, it is very much worth investing a little |
bos@558 | 1218 time to learn how to use some of the third-party tools I |
bos@592 | 1219 described in <xref linkend="sec:mq:tools"/>, |
bos@559 | 1220 particularly |
bos@559 | 1221 <command>diffstat</command> and <command>filterdiff</command>. |
bos@559 | 1222 The former will give you a quick idea of what changes your patch |
bos@559 | 1223 is making, while the latter makes it easy to splice hunks |
bos@559 | 1224 selectively out of one patch and into another.</para> |
bos@558 | 1225 |
bos@558 | 1226 </sect1> |
bos@558 | 1227 <sect1> |
bos@558 | 1228 <title>MQ cookbook</title> |
bos@558 | 1229 |
bos@558 | 1230 <sect2> |
bos@558 | 1231 <title>Manage <quote>trivial</quote> patches</title> |
bos@558 | 1232 |
bos@584 | 1233 <para id="x_437">Because the overhead of dropping files into a new |
bos@558 | 1234 Mercurial repository is so low, it makes a lot of sense to |
bos@558 | 1235 manage patches this way even if you simply want to make a few |
bos@558 | 1236 changes to a source tarball that you downloaded.</para> |
bos@558 | 1237 |
bos@584 | 1238 <para id="x_438">Begin by downloading and unpacking the source tarball, and |
bos@567 | 1239 turning it into a Mercurial repository.</para> |
bos@567 | 1240 |
bos@567 | 1241 &interaction.mq.tarball.download; |
bos@558 | 1242 |
bos@584 | 1243 <para id="x_439">Continue by creating a patch stack and making your |
bos@567 | 1244 changes.</para> |
bos@567 | 1245 |
bos@567 | 1246 &interaction.mq.tarball.qinit; |
bos@558 | 1247 |
bos@584 | 1248 <para id="x_43a">Let's say a few weeks or months pass, and your package |
bos@558 | 1249 author releases a new version. First, bring their changes |
bos@567 | 1250 into the repository.</para> |
bos@567 | 1251 |
bos@567 | 1252 &interaction.mq.tarball.newsource; |
bos@567 | 1253 |
bos@584 | 1254 <para id="x_43b">The pipeline starting with <command role="hg-cmd">hg |
bos@558 | 1255 locate</command> above deletes all files in the working |
bos@558 | 1256 directory, so that <command role="hg-cmd">hg |
bos@558 | 1257 commit</command>'s <option |
bos@558 | 1258 role="hg-opt-commit">--addremove</option> option can |
bos@558 | 1259 actually tell which files have really been removed in the |
bos@558 | 1260 newer version of the source.</para> |
bos@558 | 1261 |
bos@584 | 1262 <para id="x_43c">Finally, you can apply your patches on top of the new |
bos@567 | 1263 tree.</para> |
bos@567 | 1264 |
bos@567 | 1265 &interaction.mq.tarball.repush; |
bos@682 | 1266 </sect2> |
bos@682 | 1267 |
bos@558 | 1268 <sect2 id="sec:mq:combine"> |
bos@558 | 1269 <title>Combining entire patches</title> |
bos@558 | 1270 |
bos@584 | 1271 <para id="x_43d">MQ provides a command, <command |
bos@559 | 1272 role="hg-ext-mq">qfold</command> that lets you combine |
bos@558 | 1273 entire patches. This <quote>folds</quote> the patches you |
bos@558 | 1274 name, in the order you name them, into the topmost applied |
bos@558 | 1275 patch, and concatenates their descriptions onto the end of its |
bos@558 | 1276 description. The patches that you fold must be unapplied |
bos@558 | 1277 before you fold them.</para> |
bos@558 | 1278 |
bos@584 | 1279 <para id="x_43e">The order in which you fold patches matters. If your |
bos@558 | 1280 topmost applied patch is <literal>foo</literal>, and you |
bos@559 | 1281 <command role="hg-ext-mq">qfold</command> |
bos@558 | 1282 <literal>bar</literal> and <literal>quux</literal> into it, |
bos@558 | 1283 you will end up with a patch that has the same effect as if |
bos@558 | 1284 you applied first <literal>foo</literal>, then |
bos@558 | 1285 <literal>bar</literal>, followed by |
bos@558 | 1286 <literal>quux</literal>.</para> |
bos@682 | 1287 </sect2> |
bos@682 | 1288 |
bos@558 | 1289 <sect2> |
bos@558 | 1290 <title>Merging part of one patch into another</title> |
bos@558 | 1291 |
bos@584 | 1292 <para id="x_43f">Merging <emphasis>part</emphasis> of one patch into |
bos@558 | 1293 another is more difficult than combining entire |
bos@558 | 1294 patches.</para> |
bos@558 | 1295 |
bos@584 | 1296 <para id="x_440">If you want to move changes to entire files, you can use |
bos@558 | 1297 <command>filterdiff</command>'s <option |
bos@558 | 1298 role="cmd-opt-filterdiff">-i</option> and <option |
bos@558 | 1299 role="cmd-opt-filterdiff">-x</option> options to choose the |
bos@558 | 1300 modifications to snip out of one patch, concatenating its |
bos@558 | 1301 output onto the end of the patch you want to merge into. You |
bos@558 | 1302 usually won't need to modify the patch you've merged the |
bos@558 | 1303 changes from. Instead, MQ will report some rejected hunks |
bos@559 | 1304 when you <command role="hg-ext-mq">qpush</command> it (from |
bos@558 | 1305 the hunks you moved into the other patch), and you can simply |
bos@559 | 1306 <command role="hg-ext-mq">qrefresh</command> the patch to drop |
bos@558 | 1307 the duplicate hunks.</para> |
bos@558 | 1308 |
bos@584 | 1309 <para id="x_441">If you have a patch that has multiple hunks modifying a |
bos@558 | 1310 file, and you only want to move a few of those hunks, the job |
bos@558 | 1311 becomes more messy, but you can still partly automate it. Use |
bos@558 | 1312 <command>lsdiff -nvv</command> to print some metadata about |
bos@567 | 1313 the patch.</para> |
bos@567 | 1314 |
bos@567 | 1315 &interaction.mq.tools.lsdiff; |
bos@558 | 1316 |
bos@584 | 1317 <para id="x_442">This command prints three different kinds of |
bos@558 | 1318 number:</para> |
bos@558 | 1319 <itemizedlist> |
bos@584 | 1320 <listitem><para id="x_443">(in the first column) a <emphasis>file |
bos@558 | 1321 number</emphasis> to identify each file modified in the |
bos@559 | 1322 patch;</para> |
bos@559 | 1323 </listitem> |
bos@584 | 1324 <listitem><para id="x_444">(on the next line, indented) the line number |
bos@559 | 1325 within a modified file where a hunk starts; and</para> |
bos@559 | 1326 </listitem> |
bos@584 | 1327 <listitem><para id="x_445">(on the same line) a <emphasis>hunk |
bos@559 | 1328 number</emphasis> to identify that hunk.</para> |
bos@559 | 1329 </listitem></itemizedlist> |
bos@558 | 1330 |
bos@584 | 1331 <para id="x_446">You'll have to use some visual inspection, and reading of |
bos@558 | 1332 the patch, to identify the file and hunk numbers you'll want, |
bos@558 | 1333 but you can then pass them to to |
bos@558 | 1334 <command>filterdiff</command>'s <option |
bos@558 | 1335 role="cmd-opt-filterdiff">--files</option> and <option |
bos@558 | 1336 role="cmd-opt-filterdiff">--hunks</option> options, to |
bos@558 | 1337 select exactly the file and hunk you want to extract.</para> |
bos@558 | 1338 |
bos@584 | 1339 <para id="x_447">Once you have this hunk, you can concatenate it onto the |
bos@558 | 1340 end of your destination patch and continue with the remainder |
bos@592 | 1341 of <xref linkend="sec:mq:combine"/>.</para> |
bos@558 | 1342 |
bos@558 | 1343 </sect2> |
bos@558 | 1344 </sect1> |
bos@558 | 1345 <sect1> |
bos@558 | 1346 <title>Differences between quilt and MQ</title> |
bos@558 | 1347 |
bos@584 | 1348 <para id="x_448">If you are already familiar with quilt, MQ provides a |
bos@558 | 1349 similar command set. There are a few differences in the way |
bos@558 | 1350 that it works.</para> |
bos@558 | 1351 |
bos@584 | 1352 <para id="x_449">You will already have noticed that most quilt commands have |
bos@558 | 1353 MQ counterparts that simply begin with a |
bos@558 | 1354 <quote><literal>q</literal></quote>. The exceptions are quilt's |
bos@558 | 1355 <literal>add</literal> and <literal>remove</literal> commands, |
bos@558 | 1356 the counterparts for which are the normal Mercurial <command |
bos@558 | 1357 role="hg-cmd">hg add</command> and <command role="hg-cmd">hg |
bos@558 | 1358 remove</command> commands. There is no MQ equivalent of the |
bos@558 | 1359 quilt <literal>edit</literal> command.</para> |
bos@558 | 1360 |
bos@558 | 1361 </sect1> |
bos@558 | 1362 </chapter> |
bos@558 | 1363 |
bos@558 | 1364 <!-- |
bos@558 | 1365 local variables: |
bos@558 | 1366 sgml-parent-document: ("00book.xml" "book" "chapter") |
bos@558 | 1367 end: |
bos@558 | 1368 --> |