hgbook

annotate fr/ch14-hgext.xml @ 964:6b680d569bb4

deleting a bunch of files not longer necessary to build the documentation.
Adding missing newly files needed to build the documentation
author Romain PELISSE <belaran@gmail.com>
date Sun Aug 16 04:58:01 2009 +0200 (2009-08-16)
parents
children 6f8c48362758
rev   line source
belaran@964 1 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
belaran@964 2
belaran@964 3 <chapter>
belaran@964 4 <title>Adding functionality with extensions</title>
belaran@964 5 <para>\label{chap:hgext}</para>
belaran@964 6
belaran@964 7 <para>While the core of Mercurial is quite complete from a functionality
belaran@964 8 standpoint, it's deliberately shorn of fancy features. This approach
belaran@964 9 of preserving simplicity keeps the software easy to deal with for both
belaran@964 10 maintainers and users.</para>
belaran@964 11
belaran@964 12 <para>However, Mercurial doesn't box you in with an inflexible command set:
belaran@964 13 you can add features to it as <emphasis>extensions</emphasis> (sometimes known as
belaran@964 14 <emphasis>plugins</emphasis>). We've already discussed a few of these extensions in
belaran@964 15 earlier chapters.</para>
belaran@964 16 <itemizedlist>
belaran@964 17 <listitem><para>Section <xref linkend="sec:tour-merge:fetch"/> covers the <literal role="hg-ext">fetch</literal>
belaran@964 18 extension; this combines pulling new changes and merging them with
belaran@964 19 local changes into a single command, <command role="hg-ext-fetch">fetch</command>.</para>
belaran@964 20 </listitem>
belaran@964 21 <listitem><para>In chapter <xref linkend="chap:hook"/>, we covered several extensions that
belaran@964 22 are useful for hook-related functionality: <literal role="hg-ext">acl</literal> adds access
belaran@964 23 control lists; <literal role="hg-ext">bugzilla</literal> adds integration with the Bugzilla
belaran@964 24 bug tracking system; and <literal role="hg-ext">notify</literal> sends notification emails on
belaran@964 25 new changes.</para>
belaran@964 26 </listitem>
belaran@964 27 <listitem><para>The Mercurial Queues patch management extension is so invaluable
belaran@964 28 that it merits two chapters and an appendix all to itself.
belaran@964 29 Chapter <xref linkend="chap:mq"/> covers the basics;
belaran@964 30 chapter <xref linkend="chap:mq-collab"/> discusses advanced topics; and
belaran@964 31 appendix <xref linkend="chap:mqref"/> goes into detail on each command.</para>
belaran@964 32 </listitem></itemizedlist>
belaran@964 33
belaran@964 34 <para>In this chapter, we'll cover some of the other extensions that are
belaran@964 35 available for Mercurial, and briefly touch on some of the machinery
belaran@964 36 you'll need to know about if you want to write an extension of your
belaran@964 37 own.</para>
belaran@964 38 <itemizedlist>
belaran@964 39 <listitem><para>In section <xref linkend="sec:hgext:inotify"/>, we'll discuss the
belaran@964 40 possibility of <emphasis>huge</emphasis> performance improvements using the
belaran@964 41 <literal role="hg-ext">inotify</literal> extension.</para>
belaran@964 42 </listitem></itemizedlist>
belaran@964 43
belaran@964 44 <sect1>
belaran@964 45 <title>Improve performance with the <literal role="hg-ext">inotify</literal> extension</title>
belaran@964 46 <para>\label{sec:hgext:inotify}
belaran@964 47 </para>
belaran@964 48
belaran@964 49 <para>Are you interested in having some of the most common Mercurial
belaran@964 50 operations run as much as a hundred times faster? Read on!
belaran@964 51 </para>
belaran@964 52
belaran@964 53 <para>Mercurial has great performance under normal circumstances. For
belaran@964 54 example, when you run the <command role="hg-cmd">hg status</command> command, Mercurial has to
belaran@964 55 scan almost every directory and file in your repository so that it can
belaran@964 56 display file status. Many other Mercurial commands need to do the
belaran@964 57 same work behind the scenes; for example, the <command role="hg-cmd">hg diff</command> command
belaran@964 58 uses the status machinery to avoid doing an expensive comparison
belaran@964 59 operation on files that obviously haven't changed.
belaran@964 60 </para>
belaran@964 61
belaran@964 62 <para>Because obtaining file status is crucial to good performance, the
belaran@964 63 authors of Mercurial have optimised this code to within an inch of its
belaran@964 64 life. However, there's no avoiding the fact that when you run
belaran@964 65 <command role="hg-cmd">hg status</command>, Mercurial is going to have to perform at least one
belaran@964 66 expensive system call for each managed file to determine whether it's
belaran@964 67 changed since the last time Mercurial checked. For a sufficiently
belaran@964 68 large repository, this can take a long time.
belaran@964 69 </para>
belaran@964 70
belaran@964 71 <para>To put a number on the magnitude of this effect, I created a
belaran@964 72 repository containing 150,000 managed files. I timed <command role="hg-cmd">hg status</command>
belaran@964 73 as taking ten seconds to run, even when <emphasis>none</emphasis> of those files had
belaran@964 74 been modified.
belaran@964 75 </para>
belaran@964 76
belaran@964 77 <para>Many modern operating systems contain a file notification facility.
belaran@964 78 If a program signs up to an appropriate service, the operating system
belaran@964 79 will notify it every time a file of interest is created, modified, or
belaran@964 80 deleted. On Linux systems, the kernel component that does this is
belaran@964 81 called <literal>inotify</literal>.
belaran@964 82 </para>
belaran@964 83
belaran@964 84 <para>Mercurial's <literal role="hg-ext">inotify</literal> extension talks to the kernel's
belaran@964 85 <literal>inotify</literal> component to optimise <command role="hg-cmd">hg status</command> commands. The
belaran@964 86 extension has two components. A daemon sits in the background and
belaran@964 87 receives notifications from the <literal>inotify</literal> subsystem. It also
belaran@964 88 listens for connections from a regular Mercurial command. The
belaran@964 89 extension modifies Mercurial's behaviour so that instead of scanning
belaran@964 90 the filesystem, it queries the daemon. Since the daemon has perfect
belaran@964 91 information about the state of the repository, it can respond with a
belaran@964 92 result instantaneously, avoiding the need to scan every directory and
belaran@964 93 file in the repository.
belaran@964 94 </para>
belaran@964 95
belaran@964 96 <para>Recall the ten seconds that I measured plain Mercurial as taking to
belaran@964 97 run <command role="hg-cmd">hg status</command> on a 150,000 file repository. With the
belaran@964 98 <literal role="hg-ext">inotify</literal> extension enabled, the time dropped to 0.1 seconds, a
belaran@964 99 factor of <emphasis>one hundred</emphasis> faster.
belaran@964 100 </para>
belaran@964 101
belaran@964 102 <para>Before we continue, please pay attention to some caveats.
belaran@964 103 </para>
belaran@964 104 <itemizedlist>
belaran@964 105 <listitem><para>The <literal role="hg-ext">inotify</literal> extension is Linux-specific. Because it
belaran@964 106 interfaces directly to the Linux kernel's <literal>inotify</literal>
belaran@964 107 subsystem, it does not work on other operating systems.
belaran@964 108 </para>
belaran@964 109 </listitem>
belaran@964 110 <listitem><para>It should work on any Linux distribution that was released after
belaran@964 111 early 2005. Older distributions are likely to have a kernel that
belaran@964 112 lacks <literal>inotify</literal>, or a version of <literal>glibc</literal> that does not
belaran@964 113 have the necessary interfacing support.
belaran@964 114 </para>
belaran@964 115 </listitem>
belaran@964 116 <listitem><para>Not all filesystems are suitable for use with the
belaran@964 117 <literal role="hg-ext">inotify</literal> extension. Network filesystems such as NFS are a
belaran@964 118 non-starter, for example, particularly if you're running Mercurial
belaran@964 119 on several systems, all mounting the same network filesystem. The
belaran@964 120 kernel's <literal>inotify</literal> system has no way of knowing about changes
belaran@964 121 made on another system. Most local filesystems (e.g. ext3, XFS,
belaran@964 122 ReiserFS) should work fine.
belaran@964 123 </para>
belaran@964 124 </listitem></itemizedlist>
belaran@964 125
belaran@964 126 <para>The <literal role="hg-ext">inotify</literal> extension is not yet shipped with Mercurial as of
belaran@964 127 May 2007, so it's a little more involved to set up than other
belaran@964 128 extensions. But the performance improvement is worth it!
belaran@964 129 </para>
belaran@964 130
belaran@964 131 <para>The extension currently comes in two parts: a set of patches to the
belaran@964 132 Mercurial source code, and a library of Python bindings to the
belaran@964 133 <literal>inotify</literal> subsystem.
belaran@964 134 </para>
belaran@964 135 <note>
belaran@964 136 <para> There are <emphasis>two</emphasis> Python <literal>inotify</literal> binding libraries. One
belaran@964 137 of them is called <literal>pyinotify</literal>, and is packaged by some Linux
belaran@964 138 distributions as <literal>python-inotify</literal>. This is <emphasis>not</emphasis> the
belaran@964 139 one you'll need, as it is too buggy and inefficient to be practical.
belaran@964 140 </para>
belaran@964 141 </note>
belaran@964 142 <para>To get going, it's best to already have a functioning copy of
belaran@964 143 Mercurial installed.
belaran@964 144 </para>
belaran@964 145 <note>
belaran@964 146 <para> If you follow the instructions below, you'll be <emphasis>replacing</emphasis> and
belaran@964 147 overwriting any existing installation of Mercurial that you might
belaran@964 148 already have, using the latest <quote>bleeding edge</quote> Mercurial code.
belaran@964 149 Don't say you weren't warned!
belaran@964 150 </para>
belaran@964 151 </note>
belaran@964 152 <orderedlist>
belaran@964 153 <listitem><para>Clone the Python <literal>inotify</literal> binding repository. Build and
belaran@964 154 install it.
belaran@964 155 </para>
belaran@964 156 </listitem><programlisting>
belaran@964 157 <listitem><para> hg clone http://hg.kublai.com/python/inotify
belaran@964 158 cd inotify
belaran@964 159 python setup.py build --force
belaran@964 160 sudo python setup.py install --skip-build
belaran@964 161 </para>
belaran@964 162 </listitem></programlisting>
belaran@964 163 </para>
belaran@964 164 </listitem>
belaran@964 165 <listitem><para>Clone the <filename class="directory">crew</filename> Mercurial repository. Clone the
belaran@964 166 <literal role="hg-ext">inotify</literal> patch repository so that Mercurial Queues will be
belaran@964 167 able to apply patches to your cope of the <filename class="directory">crew</filename> repository.
belaran@964 168 </para>
belaran@964 169 </listitem><programlisting>
belaran@964 170 <listitem><para> hg clone http://hg.intevation.org/mercurial/crew
belaran@964 171 hg clone crew inotify
belaran@964 172 hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches
belaran@964 173 </para>
belaran@964 174 </listitem></programlisting>
belaran@964 175 </para>
belaran@964 176 </listitem>
belaran@964 177 <listitem><para>Make sure that you have the Mercurial Queues extension,
belaran@964 178 <literal role="hg-ext">mq</literal>, enabled. If you've never used MQ, read
belaran@964 179 section <xref linkend="sec:mq:start"/> to get started quickly.
belaran@964 180 </para>
belaran@964 181 </listitem>
belaran@964 182 <listitem><para>Go into the <filename class="directory">inotify</filename> repo, and apply all of the
belaran@964 183 <literal role="hg-ext">inotify</literal> patches using the <option role="hg-ext-mq-cmd-qpush-opt">-a</option> option to
belaran@964 184 the <command role="hg-ext-mq">qpush</command> command.
belaran@964 185 </para>
belaran@964 186 </listitem><programlisting>
belaran@964 187 <listitem><para> cd inotify
belaran@964 188 hg qpush -a
belaran@964 189 </para>
belaran@964 190 </listitem></programlisting>
belaran@964 191 <listitem><para> If you get an error message from <command role="hg-ext-mq">qpush</command>, you should not
belaran@964 192 continue. Instead, ask for help.
belaran@964 193 </para>
belaran@964 194 </listitem>
belaran@964 195 <listitem><para>Build and install the patched version of Mercurial.
belaran@964 196 </para>
belaran@964 197 </listitem><programlisting>
belaran@964 198 <listitem><para> python setup.py build --force
belaran@964 199 sudo python setup.py install --skip-build
belaran@964 200 </para>
belaran@964 201 </listitem></programlisting>
belaran@964 202 </orderedlist>
belaran@964 203 <para>Once you've build a suitably patched version of Mercurial, all you
belaran@964 204 need to do to enable the <literal role="hg-ext">inotify</literal> extension is add an entry to
belaran@964 205 your <filename role="special"> /.hgrc</filename>.
belaran@964 206 </para>
belaran@964 207 <programlisting>
belaran@964 208 <para> [extensions]
belaran@964 209 inotify =
belaran@964 210 </para>
belaran@964 211 </programlisting>
belaran@964 212 <para>When the <literal role="hg-ext">inotify</literal> extension is enabled, Mercurial will
belaran@964 213 automatically and transparently start the status daemon the first time
belaran@964 214 you run a command that needs status in a repository. It runs one
belaran@964 215 status daemon per repository.
belaran@964 216 </para>
belaran@964 217
belaran@964 218 <para>The status daemon is started silently, and runs in the background. If
belaran@964 219 you look at a list of running processes after you've enabled the
belaran@964 220 <literal role="hg-ext">inotify</literal> extension and run a few commands in different
belaran@964 221 repositories, you'll thus see a few <literal>hg</literal> processes sitting
belaran@964 222 around, waiting for updates from the kernel and queries from
belaran@964 223 Mercurial.
belaran@964 224 </para>
belaran@964 225
belaran@964 226 <para>The first time you run a Mercurial command in a repository when you
belaran@964 227 have the <literal role="hg-ext">inotify</literal> extension enabled, it will run with about the
belaran@964 228 same performance as a normal Mercurial command. This is because the
belaran@964 229 status daemon needs to perform a normal status scan so that it has a
belaran@964 230 baseline against which to apply later updates from the kernel.
belaran@964 231 However, <emphasis>every</emphasis> subsequent command that does any kind of status
belaran@964 232 check should be noticeably faster on repositories of even fairly
belaran@964 233 modest size. Better yet, the bigger your repository is, the greater a
belaran@964 234 performance advantage you'll see. The <literal role="hg-ext">inotify</literal> daemon makes
belaran@964 235 status operations almost instantaneous on repositories of all sizes!
belaran@964 236 </para>
belaran@964 237
belaran@964 238 <para>If you like, you can manually start a status daemon using the
belaran@964 239 <command role="hg-ext-inotify">inserve</command> command. This gives you slightly finer
belaran@964 240 control over how the daemon ought to run. This command will of course
belaran@964 241 only be available when the <literal role="hg-ext">inotify</literal> extension is enabled.
belaran@964 242 </para>
belaran@964 243
belaran@964 244 <para>When you're using the <literal role="hg-ext">inotify</literal> extension, you should notice
belaran@964 245 <emphasis>no difference at all</emphasis> in Mercurial's behaviour, with the sole
belaran@964 246 exception of status-related commands running a whole lot faster than
belaran@964 247 they used to. You should specifically expect that commands will not
belaran@964 248 print different output; neither should they give different results.
belaran@964 249 If either of these situations occurs, please report a bug.
belaran@964 250 </para>
belaran@964 251
belaran@964 252 </sect1>
belaran@964 253 <sect1>
belaran@964 254 <title>Flexible diff support with the <literal role="hg-ext">extdiff</literal> extension</title>
belaran@964 255 <para>\label{sec:hgext:extdiff}
belaran@964 256 </para>
belaran@964 257
belaran@964 258 <para>Mercurial's built-in <command role="hg-cmd">hg diff</command> command outputs plaintext unified
belaran@964 259 diffs.
belaran@964 260 <!-- &interaction.extdiff.diff; -->
belaran@964 261 If you would like to use an external tool to display modifications,
belaran@964 262 you'll want to use the <literal role="hg-ext">extdiff</literal> extension. This will let you
belaran@964 263 use, for example, a graphical diff tool.
belaran@964 264 </para>
belaran@964 265
belaran@964 266 <para>The <literal role="hg-ext">extdiff</literal> extension is bundled with Mercurial, so it's easy
belaran@964 267 to set up. In the <literal role="rc-extensions">extensions</literal> section of your <filename role="special"> /.hgrc</filename>,
belaran@964 268 simply add a one-line entry to enable the extension.
belaran@964 269 </para>
belaran@964 270 <programlisting>
belaran@964 271 <para> [extensions]
belaran@964 272 extdiff =
belaran@964 273 </para>
belaran@964 274 </programlisting>
belaran@964 275 <para>This introduces a command named <command role="hg-ext-extdiff">extdiff</command>, which by
belaran@964 276 default uses your system's <command>diff</command> command to generate a
belaran@964 277 unified diff in the same form as the built-in <command role="hg-cmd">hg diff</command> command.
belaran@964 278 <!-- &interaction.extdiff.extdiff; -->
belaran@964 279 The result won't be exactly the same as with the built-in <command role="hg-cmd">hg diff</command>
belaran@964 280 variations, because the output of <command>diff</command> varies from one
belaran@964 281 system to another, even when passed the same options.
belaran@964 282 </para>
belaran@964 283
belaran@964 284 <para>As the <quote><literal>making snapshot</literal></quote> lines of output above imply, the
belaran@964 285 <command role="hg-ext-extdiff">extdiff</command> command works by creating two snapshots of
belaran@964 286 your source tree. The first snapshot is of the source revision; the
belaran@964 287 second, of the target revision or working directory. The
belaran@964 288 <command role="hg-ext-extdiff">extdiff</command> command generates these snapshots in a
belaran@964 289 temporary directory, passes the name of each directory to an external
belaran@964 290 diff viewer, then deletes the temporary directory. For efficiency, it
belaran@964 291 only snapshots the directories and files that have changed between the
belaran@964 292 two revisions.
belaran@964 293 </para>
belaran@964 294
belaran@964 295 <para>Snapshot directory names have the same base name as your repository.
belaran@964 296 If your repository path is <filename class="directory">/quux/bar/foo</filename>, then <filename class="directory">foo</filename>
belaran@964 297 will be the name of each snapshot directory. Each snapshot directory
belaran@964 298 name has its changeset ID appended, if appropriate. If a snapshot is
belaran@964 299 of revision <literal>a631aca1083f</literal>, the directory will be named
belaran@964 300 <filename class="directory">foo.a631aca1083f</filename>. A snapshot of the working directory won't
belaran@964 301 have a changeset ID appended, so it would just be <filename class="directory">foo</filename> in
belaran@964 302 this example. To see what this looks like in practice, look again at
belaran@964 303 the <command role="hg-ext-extdiff">extdiff</command> example above. Notice that the diff has
belaran@964 304 the snapshot directory names embedded in its header.
belaran@964 305 </para>
belaran@964 306
belaran@964 307 <para>The <command role="hg-ext-extdiff">extdiff</command> command accepts two important options.
belaran@964 308 The <option role="hg-ext-extdiff-cmd-extdiff-opt">-p</option> option lets you choose a program to
belaran@964 309 view differences with, instead of <command>diff</command>. With the
belaran@964 310 <option role="hg-ext-extdiff-cmd-extdiff-opt">-o</option> option, you can change the options that
belaran@964 311 <command role="hg-ext-extdiff">extdiff</command> passes to the program (by default, these
belaran@964 312 options are <quote><literal>-Npru</literal></quote>, which only make sense if you're
belaran@964 313 running <command>diff</command>). In other respects, the
belaran@964 314 <command role="hg-ext-extdiff">extdiff</command> command acts similarly to the built-in
belaran@964 315 <command role="hg-cmd">hg diff</command> command: you use the same option names, syntax, and
belaran@964 316 arguments to specify the revisions you want, the files you want, and
belaran@964 317 so on.
belaran@964 318 </para>
belaran@964 319
belaran@964 320 <para>As an example, here's how to run the normal system <command>diff</command>
belaran@964 321 command, getting it to generate context diffs (using the
belaran@964 322 <option role="cmd-opt-diff">-c</option> option) instead of unified diffs, and five lines of
belaran@964 323 context instead of the default three (passing <literal>5</literal> as the
belaran@964 324 argument to the <option role="cmd-opt-diff">-C</option> option).
belaran@964 325 <!-- &interaction.extdiff.extdiff-ctx; -->
belaran@964 326 </para>
belaran@964 327
belaran@964 328 <para>Launching a visual diff tool is just as easy. Here's how to launch
belaran@964 329 the <command>kdiff3</command> viewer.
belaran@964 330 </para>
belaran@964 331 <programlisting>
belaran@964 332 <para> hg extdiff -p kdiff3 -o </quote>
belaran@964 333 </para>
belaran@964 334 </programlisting>
belaran@964 335
belaran@964 336 <para>If your diff viewing command can't deal with directories, you can
belaran@964 337 easily work around this with a little scripting. For an example of
belaran@964 338 such scripting in action with the <literal role="hg-ext">mq</literal> extension and the
belaran@964 339 <command>interdiff</command> command, see
belaran@964 340 section <xref linkend="mq-collab:tips:interdiff"/>.
belaran@964 341 </para>
belaran@964 342
belaran@964 343 <sect2>
belaran@964 344 <title>Defining command aliases</title>
belaran@964 345
belaran@964 346 <para>It can be cumbersome to remember the options to both the
belaran@964 347 <command role="hg-ext-extdiff">extdiff</command> command and the diff viewer you want to use,
belaran@964 348 so the <literal role="hg-ext">extdiff</literal> extension lets you define <emphasis>new</emphasis> commands
belaran@964 349 that will invoke your diff viewer with exactly the right options.
belaran@964 350 </para>
belaran@964 351
belaran@964 352 <para>All you need to do is edit your <filename role="special"> /.hgrc</filename>, and add a section named
belaran@964 353 <literal role="rc-extdiff">extdiff</literal>. Inside this section, you can define multiple
belaran@964 354 commands. Here's how to add a <literal>kdiff3</literal> command. Once you've
belaran@964 355 defined this, you can type <quote><literal>hg kdiff3</literal></quote> and the
belaran@964 356 <literal role="hg-ext">extdiff</literal> extension will run <command>kdiff3</command> for you.
belaran@964 357 </para>
belaran@964 358 <programlisting>
belaran@964 359 <para> [extdiff]
belaran@964 360 cmd.kdiff3 =
belaran@964 361 </para>
belaran@964 362 </programlisting>
belaran@964 363 <para>If you leave the right hand side of the definition empty, as above,
belaran@964 364 the <literal role="hg-ext">extdiff</literal> extension uses the name of the command you defined
belaran@964 365 as the name of the external program to run. But these names don't
belaran@964 366 have to be the same. Here, we define a command named <quote>\texttt{hg
belaran@964 367 wibble}</quote>, which runs <command>kdiff3</command>.
belaran@964 368 </para>
belaran@964 369 <programlisting>
belaran@964 370 <para> [extdiff]
belaran@964 371 cmd.wibble = kdiff3
belaran@964 372 </para>
belaran@964 373 </programlisting>
belaran@964 374
belaran@964 375 <para>You can also specify the default options that you want to invoke your
belaran@964 376 diff viewing program with. The prefix to use is <quote><literal>opts.</literal></quote>,
belaran@964 377 followed by the name of the command to which the options apply. This
belaran@964 378 example defines a <quote><literal>hg vimdiff</literal></quote> command that runs the
belaran@964 379 <command>vim</command> editor's <literal>DirDiff</literal> extension.
belaran@964 380 </para>
belaran@964 381 <programlisting>
belaran@964 382 <para> [extdiff]
belaran@964 383 cmd.vimdiff = vim
belaran@964 384 opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)'
belaran@964 385 </para>
belaran@964 386 </programlisting>
belaran@964 387
belaran@964 388 </sect2>
belaran@964 389 </sect1>
belaran@964 390 <sect1>
belaran@964 391 <title>Cherrypicking changes with the <literal role="hg-ext">transplant</literal> extension</title>
belaran@964 392 <para>\label{sec:hgext:transplant}
belaran@964 393 </para>
belaran@964 394
belaran@964 395 <para>Need to have a long chat with Brendan about this.
belaran@964 396 </para>
belaran@964 397
belaran@964 398 </sect1>
belaran@964 399 <sect1>
belaran@964 400 <title>Send changes via email with the <literal role="hg-ext">patchbomb</literal> extension</title>
belaran@964 401 <para>\label{sec:hgext:patchbomb}
belaran@964 402 </para>
belaran@964 403
belaran@964 404 <para>Many projects have a culture of <quote>change review</quote>, in which people
belaran@964 405 send their modifications to a mailing list for others to read and
belaran@964 406 comment on before they commit the final version to a shared
belaran@964 407 repository. Some projects have people who act as gatekeepers; they
belaran@964 408 apply changes from other people to a repository to which those others
belaran@964 409 don't have access.
belaran@964 410 </para>
belaran@964 411
belaran@964 412 <para>Mercurial makes it easy to send changes over email for review or
belaran@964 413 application, via its <literal role="hg-ext">patchbomb</literal> extension. The extension is so
belaran@964 414 namd because changes are formatted as patches, and it's usual to send
belaran@964 415 one changeset per email message. Sending a long series of changes by
belaran@964 416 email is thus much like <quote>bombing</quote> the recipient's inbox, hence
belaran@964 417 <quote>patchbomb</quote>.
belaran@964 418 </para>
belaran@964 419
belaran@964 420 <para>As usual, the basic configuration of the <literal role="hg-ext">patchbomb</literal> extension
belaran@964 421 takes just one or two lines in your <filename role="special"> /.hgrc</filename>.
belaran@964 422 </para>
belaran@964 423 <programlisting>
belaran@964 424 <para> [extensions]
belaran@964 425 patchbomb =
belaran@964 426 </para>
belaran@964 427 </programlisting>
belaran@964 428 <para>Once you've enabled the extension, you will have a new command
belaran@964 429 available, named <command role="hg-ext-patchbomb">email</command>.
belaran@964 430 </para>
belaran@964 431
belaran@964 432 <para>The safest and best way to invoke the <command role="hg-ext-patchbomb">email</command>
belaran@964 433 command is to <emphasis>always</emphasis> run it first with the
belaran@964 434 <option role="hg-ext-patchbomb-cmd-email-opt">-n</option> option. This will show you what the
belaran@964 435 command <emphasis>would</emphasis> send, without actually sending anything. Once
belaran@964 436 you've had a quick glance over the changes and verified that you are
belaran@964 437 sending the right ones, you can rerun the same command, with the
belaran@964 438 <option role="hg-ext-patchbomb-cmd-email-opt">-n</option> option removed.
belaran@964 439 </para>
belaran@964 440
belaran@964 441 <para>The <command role="hg-ext-patchbomb">email</command> command accepts the same kind of
belaran@964 442 revision syntax as every other Mercurial command. For example, this
belaran@964 443 command will send every revision between 7 and <literal>tip</literal>,
belaran@964 444 inclusive.
belaran@964 445 </para>
belaran@964 446 <programlisting>
belaran@964 447 <para> hg email -n 7:tip
belaran@964 448 </para>
belaran@964 449 </programlisting>
belaran@964 450 <para>You can also specify a <emphasis>repository</emphasis> to compare with. If you
belaran@964 451 provide a repository but no revisions, the <command role="hg-ext-patchbomb">email</command>
belaran@964 452 command will send all revisions in the local repository that are not
belaran@964 453 present in the remote repository. If you additionally specify
belaran@964 454 revisions or a branch name (the latter using the
belaran@964 455 <option role="hg-ext-patchbomb-cmd-email-opt">-b</option> option), this will constrain the
belaran@964 456 revisions sent.
belaran@964 457 </para>
belaran@964 458
belaran@964 459 <para>It's perfectly safe to run the <command role="hg-ext-patchbomb">email</command> command
belaran@964 460 without the names of the people you want to send to: if you do this,
belaran@964 461 it will just prompt you for those values interactively. (If you're
belaran@964 462 using a Linux or Unix-like system, you should have enhanced
belaran@964 463 <literal>readline</literal>-style editing capabilities when entering those
belaran@964 464 headers, too, which is useful.)
belaran@964 465 </para>
belaran@964 466
belaran@964 467 <para>When you are sending just one revision, the <command role="hg-ext-patchbomb">email</command>
belaran@964 468 command will by default use the first line of the changeset
belaran@964 469 description as the subject of the single email message it sends.
belaran@964 470 </para>
belaran@964 471
belaran@964 472 <para>If you send multiple revisions, the <command role="hg-ext-patchbomb">email</command> command
belaran@964 473 will usually send one message per changeset. It will preface the
belaran@964 474 series with an introductory message, in which you should describe the
belaran@964 475 purpose of the series of changes you're sending.
belaran@964 476 </para>
belaran@964 477
belaran@964 478 <sect2>
belaran@964 479 <title>Changing the behaviour of patchbombs</title>
belaran@964 480
belaran@964 481 <para>Not every project has exactly the same conventions for sending changes
belaran@964 482 in email; the <literal role="hg-ext">patchbomb</literal> extension tries to accommodate a
belaran@964 483 number of variations through command line options.
belaran@964 484 </para>
belaran@964 485 <itemizedlist>
belaran@964 486 <listitem><para>You can write a subject for the introductory message on the
belaran@964 487 command line using the <option role="hg-ext-patchbomb-cmd-email-opt">-s</option> option. This
belaran@964 488 takes one argument, the text of the subject to use.
belaran@964 489 </para>
belaran@964 490 </listitem>
belaran@964 491 <listitem><para>To change the email address from which the messages originate,
belaran@964 492 use the <option role="hg-ext-patchbomb-cmd-email-opt">-f</option> option. This takes one
belaran@964 493 argument, the email address to use.
belaran@964 494 </para>
belaran@964 495 </listitem>
belaran@964 496 <listitem><para>The default behaviour is to send unified diffs (see
belaran@964 497 section <xref linkend="sec:mq:patch"/> for a description of the format), one per
belaran@964 498 message. You can send a binary bundle instead with the
belaran@964 499 <option role="hg-ext-patchbomb-cmd-email-opt">-b</option> option.
belaran@964 500 </para>
belaran@964 501 </listitem>
belaran@964 502 <listitem><para>Unified diffs are normally prefaced with a metadata header. You
belaran@964 503 can omit this, and send unadorned diffs, with the
belaran@964 504 <option role="hg-ext-patchbomb-cmd-email-opt">--plain</option> option.
belaran@964 505 </para>
belaran@964 506 </listitem>
belaran@964 507 <listitem><para>Diffs are normally sent <quote>inline</quote>, in the same body part as the
belaran@964 508 description of a patch. This makes it easiest for the largest
belaran@964 509 number of readers to quote and respond to parts of a diff, as some
belaran@964 510 mail clients will only quote the first MIME body part in a message.
belaran@964 511 If you'd prefer to send the description and the diff in separate
belaran@964 512 body parts, use the <option role="hg-ext-patchbomb-cmd-email-opt">-a</option> option.
belaran@964 513 </para>
belaran@964 514 </listitem>
belaran@964 515 <listitem><para>Instead of sending mail messages, you can write them to an
belaran@964 516 <literal>mbox</literal>-format mail folder using the
belaran@964 517 <option role="hg-ext-patchbomb-cmd-email-opt">-m</option> option. That option takes one
belaran@964 518 argument, the name of the file to write to.
belaran@964 519 </para>
belaran@964 520 </listitem>
belaran@964 521 <listitem><para>If you would like to add a <command>diffstat</command>-format summary to
belaran@964 522 each patch, and one to the introductory message, use the
belaran@964 523 <option role="hg-ext-patchbomb-cmd-email-opt">-d</option> option. The <command>diffstat</command>
belaran@964 524 command displays a table containing the name of each file patched,
belaran@964 525 the number of lines affected, and a histogram showing how much each
belaran@964 526 file is modified. This gives readers a qualitative glance at how
belaran@964 527 complex a patch is.
belaran@964 528 </para>
belaran@964 529 </listitem></itemizedlist>
belaran@964 530
belaran@964 531 </sect2>
belaran@964 532 </sect1>
belaran@964 533 </chapter>
belaran@964 534
belaran@964 535 <!--
belaran@964 536 local variables:
belaran@964 537 sgml-parent-document: ("00book.xml" "book" "chapter")
belaran@964 538 end:
belaran@964 539 -->