hgbook

diff en/ch14-hgext.xml @ 559:b90b024729f1

WIP DocBook snapshot that all compiles. Mirabile dictu!
author Bryan O'Sullivan <bos@serpentine.com>
date Wed Feb 18 00:22:09 2009 -0800 (2009-02-18)
parents en/ch14-hgext.tex@f72b7e6cbe90
children 21c62e09b99f
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/en/ch14-hgext.xml	Wed Feb 18 00:22:09 2009 -0800
     1.3 @@ -0,0 +1,549 @@
     1.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
     1.5 +
     1.6 +<chapter id="chap:hgext">
     1.7 +  <title>Adding functionality with extensions</title>
     1.8 +
     1.9 +  <para>While the core of Mercurial is quite complete from a
    1.10 +    functionality standpoint, it's deliberately shorn of fancy
    1.11 +    features.  This approach of preserving simplicity keeps the
    1.12 +    software easy to deal with for both maintainers and users.</para>
    1.13 +
    1.14 +  <para>However, Mercurial doesn't box you in with an inflexible
    1.15 +    command set: you can add features to it as
    1.16 +    <emphasis>extensions</emphasis> (sometimes known as
    1.17 +    <emphasis>plugins</emphasis>).  We've already discussed a few of
    1.18 +    these extensions in earlier chapters.</para>
    1.19 +  <itemizedlist>
    1.20 +    <listitem><para>Section <xref linkend="sec:tour-merge:fetch"/>
    1.21 +	covers the <literal role="hg-ext">fetch</literal> extension;
    1.22 +	this combines pulling new changes and merging them with local
    1.23 +	changes into a single command, <command
    1.24 +	  role="hg-ext-fetch">fetch</command>.</para>
    1.25 +    </listitem>
    1.26 +    <listitem><para>In chapter <xref linkend="chap:hook"/>, we covered
    1.27 +	several extensions that are useful for hook-related
    1.28 +	functionality: <literal role="hg-ext">acl</literal> adds
    1.29 +	access control lists; <literal
    1.30 +	  role="hg-ext">bugzilla</literal> adds integration with the
    1.31 +	Bugzilla bug tracking system; and <literal
    1.32 +	  role="hg-ext">notify</literal> sends notification emails on
    1.33 +	new changes.</para>
    1.34 +    </listitem>
    1.35 +    <listitem><para>The Mercurial Queues patch management extension is
    1.36 +	so invaluable that it merits two chapters and an appendix all
    1.37 +	to itself. Chapter <xref linkend="chap:mq"/> covers the
    1.38 +	basics; chapter <xref
    1.39 +	  linkend="chap:mq-collab"/> discusses advanced topics;
    1.40 +	and appendix <xref linkend="chap:mqref"/> goes into detail on
    1.41 +	each
    1.42 +	command.</para>
    1.43 +    </listitem></itemizedlist>
    1.44 +
    1.45 +  <para>In this chapter, we'll cover some of the other extensions that
    1.46 +    are available for Mercurial, and briefly touch on some of the
    1.47 +    machinery you'll need to know about if you want to write an
    1.48 +    extension of your own.</para>
    1.49 +  <itemizedlist>
    1.50 +    <listitem><para>In section <xref linkend="sec:hgext:inotify"/>,
    1.51 +	we'll discuss the possibility of <emphasis>huge</emphasis>
    1.52 +	performance improvements using the <literal
    1.53 +	  role="hg-ext">inotify</literal> extension.</para>
    1.54 +    </listitem></itemizedlist>
    1.55 +
    1.56 +  <sect1 id="sec:hgext:inotify">
    1.57 +    <title>Improve performance with the <literal
    1.58 +	role="hg-ext">inotify</literal> extension</title>
    1.59 +
    1.60 +    <para>Are you interested in having some of the most common
    1.61 +      Mercurial operations run as much as a hundred times faster?
    1.62 +      Read on!</para>
    1.63 +
    1.64 +    <para>Mercurial has great performance under normal circumstances.
    1.65 +      For example, when you run the <command role="hg-cmd">hg
    1.66 +	status</command> command, Mercurial has to scan almost every
    1.67 +      directory and file in your repository so that it can display
    1.68 +      file status.  Many other Mercurial commands need to do the same
    1.69 +      work behind the scenes; for example, the <command
    1.70 +	role="hg-cmd">hg diff</command> command uses the status
    1.71 +      machinery to avoid doing an expensive comparison operation on
    1.72 +      files that obviously haven't changed.</para>
    1.73 +
    1.74 +    <para>Because obtaining file status is crucial to good
    1.75 +      performance, the authors of Mercurial have optimised this code
    1.76 +      to within an inch of its life.  However, there's no avoiding the
    1.77 +      fact that when you run <command role="hg-cmd">hg
    1.78 +	status</command>, Mercurial is going to have to perform at
    1.79 +      least one expensive system call for each managed file to
    1.80 +      determine whether it's changed since the last time Mercurial
    1.81 +      checked.  For a sufficiently large repository, this can take a
    1.82 +      long time.</para>
    1.83 +
    1.84 +    <para>To put a number on the magnitude of this effect, I created a
    1.85 +      repository containing 150,000 managed files.  I timed <command
    1.86 +	role="hg-cmd">hg status</command> as taking ten seconds to
    1.87 +      run, even when <emphasis>none</emphasis> of those files had been
    1.88 +      modified.</para>
    1.89 +
    1.90 +    <para>Many modern operating systems contain a file notification
    1.91 +      facility. If a program signs up to an appropriate service, the
    1.92 +      operating system will notify it every time a file of interest is
    1.93 +      created, modified, or deleted.  On Linux systems, the kernel
    1.94 +      component that does this is called
    1.95 +      <literal>inotify</literal>.</para>
    1.96 +
    1.97 +    <para>Mercurial's <literal role="hg-ext">inotify</literal>
    1.98 +      extension talks to the kernel's <literal>inotify</literal>
    1.99 +      component to optimise <command role="hg-cmd">hg status</command>
   1.100 +      commands.  The extension has two components.  A daemon sits in
   1.101 +      the background and receives notifications from the
   1.102 +      <literal>inotify</literal> subsystem.  It also listens for
   1.103 +      connections from a regular Mercurial command.  The extension
   1.104 +      modifies Mercurial's behaviour so that instead of scanning the
   1.105 +      filesystem, it queries the daemon.  Since the daemon has perfect
   1.106 +      information about the state of the repository, it can respond
   1.107 +      with a result instantaneously, avoiding the need to scan every
   1.108 +      directory and file in the repository.</para>
   1.109 +
   1.110 +    <para>Recall the ten seconds that I measured plain Mercurial as
   1.111 +      taking to run <command role="hg-cmd">hg status</command> on a
   1.112 +      150,000 file repository.  With the <literal
   1.113 +	role="hg-ext">inotify</literal> extension enabled, the time
   1.114 +      dropped to 0.1 seconds, a factor of <emphasis>one
   1.115 +	hundred</emphasis> faster.</para>
   1.116 +
   1.117 +    <para>Before we continue, please pay attention to some
   1.118 +      caveats.</para>
   1.119 +    <itemizedlist>
   1.120 +      <listitem><para>The <literal role="hg-ext">inotify</literal>
   1.121 +	  extension is Linux-specific.  Because it interfaces directly
   1.122 +	  to the Linux kernel's <literal>inotify</literal> subsystem,
   1.123 +	  it does not work on other operating systems.</para>
   1.124 +      </listitem>
   1.125 +      <listitem><para>It should work on any Linux distribution that
   1.126 +	  was released after early 2005.  Older distributions are
   1.127 +	  likely to have a kernel that lacks
   1.128 +	  <literal>inotify</literal>, or a version of
   1.129 +	  <literal>glibc</literal> that does not have the necessary
   1.130 +	  interfacing support.</para>
   1.131 +      </listitem>
   1.132 +      <listitem><para>Not all filesystems are suitable for use with
   1.133 +	  the <literal role="hg-ext">inotify</literal> extension.
   1.134 +	  Network filesystems such as NFS are a non-starter, for
   1.135 +	  example, particularly if you're running Mercurial on several
   1.136 +	  systems, all mounting the same network filesystem.  The
   1.137 +	  kernel's <literal>inotify</literal> system has no way of
   1.138 +	  knowing about changes made on another system.  Most local
   1.139 +	  filesystems (e.g. ext3, XFS, ReiserFS) should work
   1.140 +	  fine.</para>
   1.141 +      </listitem></itemizedlist>
   1.142 +
   1.143 +    <para>The <literal role="hg-ext">inotify</literal> extension is
   1.144 +      not yet shipped with Mercurial as of May 2007, so it's a little
   1.145 +      more involved to set up than other extensions.  But the
   1.146 +      performance improvement is worth it!</para>
   1.147 +
   1.148 +    <para>The extension currently comes in two parts: a set of patches
   1.149 +      to the Mercurial source code, and a library of Python bindings
   1.150 +      to the <literal>inotify</literal> subsystem.</para>
   1.151 +    <note>
   1.152 +      <para>  There are <emphasis>two</emphasis> Python
   1.153 +	<literal>inotify</literal> binding libraries.  One of them is
   1.154 +	called <literal>pyinotify</literal>, and is packaged by some
   1.155 +	Linux distributions as <literal>python-inotify</literal>.
   1.156 +	This is <emphasis>not</emphasis> the one you'll need, as it is
   1.157 +	too buggy and inefficient to be practical.</para>
   1.158 +    </note>
   1.159 +    <para>To get going, it's best to already have a functioning copy
   1.160 +      of Mercurial installed.</para>
   1.161 +    <note>
   1.162 +      <para>  If you follow the instructions below, you'll be
   1.163 +	<emphasis>replacing</emphasis> and overwriting any existing
   1.164 +	installation of Mercurial that you might already have, using
   1.165 +	the latest <quote>bleeding edge</quote> Mercurial code. Don't
   1.166 +	say you weren't warned!</para>
   1.167 +    </note>
   1.168 +    <orderedlist>
   1.169 +      <listitem><para>Clone the Python <literal>inotify</literal>
   1.170 +	  binding repository.  Build and install it.</para>
   1.171 +	<programlisting>
   1.172 +	  hg clone http://hg.kublai.com/python/inotify cd inotify
   1.173 +	  python setup.py build --force sudo python setup.py install
   1.174 +	  --skip-build
   1.175 +	</programlisting>
   1.176 +      </listitem>
   1.177 +      <listitem><para>Clone the <filename
   1.178 +	    class="directory">crew</filename> Mercurial repository.
   1.179 +	  Clone the <literal role="hg-ext">inotify</literal> patch
   1.180 +	  repository so that Mercurial Queues will be able to apply
   1.181 +	  patches to your cope of the <filename
   1.182 +	    class="directory">crew</filename> repository.</para>
   1.183 +	<programlisting>
   1.184 +	  hg clone http://hg.intevation.org/mercurial/crew hg clone
   1.185 +	  crew inotify hg clone
   1.186 +	  http://hg.kublai.com/mercurial/patches/inotify
   1.187 +	  inotify/.hg/patches
   1.188 +	</programlisting>
   1.189 +      </listitem>
   1.190 +      <listitem><para>Make sure that you have the Mercurial Queues
   1.191 +	  extension, <literal role="hg-ext">mq</literal>, enabled.  If
   1.192 +	  you've never used MQ, read section <xref
   1.193 +	    linkend="sec:mq:start"/> to get started
   1.194 +	  quickly.</para>
   1.195 +      </listitem>
   1.196 +      <listitem><para>Go into the <filename
   1.197 +	    class="directory">inotify</filename> repo, and apply all
   1.198 +	  of the <literal role="hg-ext">inotify</literal> patches
   1.199 +	  using the <option role="hg-ext-mq-cmd-qpush-opt">hg
   1.200 +	    -a</option> option to the <command
   1.201 +	    role="hg-ext-mq">qpush</command> command.</para>
   1.202 +	<programlisting>
   1.203 +	  cd inotify hg qpush -a
   1.204 +	</programlisting>
   1.205 +      </listitem>
   1.206 +      <listitem><para>  If you get an error message from <command
   1.207 +	    role="hg-ext-mq">qpush</command>, you should not continue.
   1.208 +	  Instead, ask for help.</para>
   1.209 +      </listitem>
   1.210 +      <listitem><para>Build and install the patched version of
   1.211 +	  Mercurial.</para>
   1.212 +	<programlisting>
   1.213 +	  python setup.py build --force sudo python setup.py install
   1.214 +	  --skip-build
   1.215 +	</programlisting>
   1.216 +      </listitem>
   1.217 +    </orderedlist>
   1.218 +    <para>Once you've build a suitably patched version of Mercurial,
   1.219 +      all you need to do to enable the <literal
   1.220 +	role="hg-ext">inotify</literal> extension is add an entry to
   1.221 +      your <filename role="special"> /.hgrc</filename>.</para>
   1.222 +    <programlisting>[extensions] inotify =</programlisting>
   1.223 +    <para>When the <literal role="hg-ext">inotify</literal> extension
   1.224 +      is enabled, Mercurial will automatically and transparently start
   1.225 +      the status daemon the first time you run a command that needs
   1.226 +      status in a repository.  It runs one status daemon per
   1.227 +      repository.</para>
   1.228 +
   1.229 +    <para>The status daemon is started silently, and runs in the
   1.230 +      background.  If you look at a list of running processes after
   1.231 +      you've enabled the <literal role="hg-ext">inotify</literal>
   1.232 +      extension and run a few commands in different repositories,
   1.233 +      you'll thus see a few <literal>hg</literal> processes sitting
   1.234 +      around, waiting for updates from the kernel and queries from
   1.235 +      Mercurial.</para>
   1.236 +
   1.237 +    <para>The first time you run a Mercurial command in a repository
   1.238 +      when you have the <literal role="hg-ext">inotify</literal>
   1.239 +      extension enabled, it will run with about the same performance
   1.240 +      as a normal Mercurial command.  This is because the status
   1.241 +      daemon needs to perform a normal status scan so that it has a
   1.242 +      baseline against which to apply later updates from the kernel.
   1.243 +      However, <emphasis>every</emphasis> subsequent command that does
   1.244 +      any kind of status check should be noticeably faster on
   1.245 +      repositories of even fairly modest size.  Better yet, the bigger
   1.246 +      your repository is, the greater a performance advantage you'll
   1.247 +      see.  The <literal role="hg-ext">inotify</literal> daemon makes
   1.248 +      status operations almost instantaneous on repositories of all
   1.249 +      sizes!</para>
   1.250 +
   1.251 +    <para>If you like, you can manually start a status daemon using
   1.252 +      the <command role="hg-ext-inotify">inserve</command> command.
   1.253 +      This gives you slightly finer control over how the daemon ought
   1.254 +      to run.  This command will of course only be available when the
   1.255 +      <literal role="hg-ext">inotify</literal> extension is
   1.256 +      enabled.</para>
   1.257 +
   1.258 +    <para>When you're using the <literal
   1.259 +	role="hg-ext">inotify</literal> extension, you should notice
   1.260 +      <emphasis>no difference at all</emphasis> in Mercurial's
   1.261 +      behaviour, with the sole exception of status-related commands
   1.262 +      running a whole lot faster than they used to.  You should
   1.263 +      specifically expect that commands will not print different
   1.264 +      output; neither should they give different results. If either of
   1.265 +      these situations occurs, please report a bug.</para>
   1.266 +
   1.267 +  </sect1>
   1.268 +  <sect1 id="sec:hgext:extdiff">
   1.269 +    <title>Flexible diff support with the <literal
   1.270 +	role="hg-ext">extdiff</literal> extension</title>
   1.271 +
   1.272 +    <para>Mercurial's built-in <command role="hg-cmd">hg
   1.273 +	diff</command> command outputs plaintext unified diffs. <!--
   1.274 +      &interaction.extdiff.diff; --> If you would like to use an
   1.275 +      external tool to display modifications, you'll want to use the
   1.276 +      <literal role="hg-ext">extdiff</literal> extension.  This will
   1.277 +      let you use, for example, a graphical diff tool.</para>
   1.278 +
   1.279 +    <para>The <literal role="hg-ext">extdiff</literal> extension is
   1.280 +      bundled with Mercurial, so it's easy to set up.  In the <literal
   1.281 +	role="rc-extensions">extensions</literal> section of your
   1.282 +      <filename role="special"> /.hgrc</filename>, simply add a
   1.283 +      one-line entry to enable the extension.</para>
   1.284 +    <programlisting>[extensions] extdiff =</programlisting>
   1.285 +    <para>This introduces a command named <command
   1.286 +	role="hg-ext-extdiff">extdiff</command>, which by default uses
   1.287 +      your system's <command>diff</command> command to generate a
   1.288 +      unified diff in the same form as the built-in <command
   1.289 +	role="hg-cmd">hg diff</command> command. <!--
   1.290 +      &interaction.extdiff.extdiff; --> The result won't be exactly
   1.291 +      the same as with the built-in <command role="hg-cmd">hg
   1.292 +	diff</command> variations, because the output of
   1.293 +      <command>diff</command> varies from one system to another, even
   1.294 +      when passed the same options.</para>
   1.295 +
   1.296 +    <para>As the <quote><literal>making snapshot</literal></quote>
   1.297 +      lines of output above imply, the <command
   1.298 +	role="hg-ext-extdiff">extdiff</command> command works by
   1.299 +      creating two snapshots of your source tree.  The first snapshot
   1.300 +      is of the source revision; the second, of the target revision or
   1.301 +      working directory.  The <command
   1.302 +	role="hg-ext-extdiff">extdiff</command> command generates
   1.303 +      these snapshots in a temporary directory, passes the name of
   1.304 +      each directory to an external diff viewer, then deletes the
   1.305 +      temporary directory.  For efficiency, it only snapshots the
   1.306 +      directories and files that have changed between the two
   1.307 +      revisions.</para>
   1.308 +
   1.309 +    <para>Snapshot directory names have the same base name as your
   1.310 +      repository. If your repository path is <filename
   1.311 +	class="directory">/quux/bar/foo</filename>, then <filename
   1.312 +	class="directory">foo</filename> will be the name of each
   1.313 +      snapshot directory.  Each snapshot directory name has its
   1.314 +      changeset ID appended, if appropriate.  If a snapshot is of
   1.315 +      revision <literal>a631aca1083f</literal>, the directory will be
   1.316 +      named <filename class="directory">foo.a631aca1083f</filename>.
   1.317 +      A snapshot of the working directory won't have a changeset ID
   1.318 +      appended, so it would just be <filename
   1.319 +	class="directory">foo</filename> in this example.  To see what
   1.320 +      this looks like in practice, look again at the <command
   1.321 +	role="hg-ext-extdiff">extdiff</command> example above.  Notice
   1.322 +      that the diff has the snapshot directory names embedded in its
   1.323 +      header.</para>
   1.324 +
   1.325 +    <para>The <command role="hg-ext-extdiff">extdiff</command> command
   1.326 +      accepts two important options. The <option
   1.327 +	role="hg-ext-extdiff-cmd-extdiff-opt">hg -p</option> option
   1.328 +      lets you choose a program to view differences with, instead of
   1.329 +      <command>diff</command>.  With the <option
   1.330 +	role="hg-ext-extdiff-cmd-extdiff-opt">hg -o</option> option,
   1.331 +      you can change the options that <command
   1.332 +	role="hg-ext-extdiff">extdiff</command> passes to the program
   1.333 +      (by default, these options are
   1.334 +      <quote><literal>-Npru</literal></quote>, which only make sense
   1.335 +      if you're running <command>diff</command>).  In other respects,
   1.336 +      the <command role="hg-ext-extdiff">extdiff</command> command
   1.337 +      acts similarly to the built-in <command role="hg-cmd">hg
   1.338 +	diff</command> command: you use the same option names, syntax,
   1.339 +      and arguments to specify the revisions you want, the files you
   1.340 +      want, and so on.</para>
   1.341 +
   1.342 +    <para>As an example, here's how to run the normal system
   1.343 +      <command>diff</command> command, getting it to generate context
   1.344 +      diffs (using the <option role="cmd-opt-diff">-c</option> option)
   1.345 +      instead of unified diffs, and five lines of context instead of
   1.346 +      the default three (passing <literal>5</literal> as the argument
   1.347 +      to the <option role="cmd-opt-diff">-C</option> option). <!--
   1.348 +      &interaction.extdiff.extdiff-ctx; --></para>
   1.349 +
   1.350 +    <para>Launching a visual diff tool is just as easy.  Here's how to
   1.351 +      launch the <command>kdiff3</command> viewer.</para>
   1.352 +    <programlisting>hg extdiff -p kdiff3 -o</programlisting>
   1.353 +
   1.354 +    <para>If your diff viewing command can't deal with directories,
   1.355 +      you can easily work around this with a little scripting.  For an
   1.356 +      example of such scripting in action with the <literal
   1.357 +	role="hg-ext">mq</literal> extension and the
   1.358 +      <command>interdiff</command> command, see section <xref
   1.359 +	linkend="mq-collab:tips:interdiff"/>.</para>
   1.360 +
   1.361 +    <sect2>
   1.362 +      <title>Defining command aliases</title>
   1.363 +
   1.364 +      <para>It can be cumbersome to remember the options to both the
   1.365 +	<command role="hg-ext-extdiff">extdiff</command> command and
   1.366 +	the diff viewer you want to use, so the <literal
   1.367 +	  role="hg-ext">extdiff</literal> extension lets you define
   1.368 +	<emphasis>new</emphasis> commands that will invoke your diff
   1.369 +	viewer with exactly the right options.</para>
   1.370 +
   1.371 +      <para>All you need to do is edit your <filename role="special">
   1.372 +	  /.hgrc</filename>, and add a section named <literal
   1.373 +	  role="rc-extdiff">extdiff</literal>.  Inside this section,
   1.374 +	you can define multiple commands.  Here's how to add a
   1.375 +	<literal>kdiff3</literal> command.  Once you've defined this,
   1.376 +	you can type <quote><literal>hg kdiff3</literal></quote> and
   1.377 +	the <literal role="hg-ext">extdiff</literal> extension will
   1.378 +	run <command>kdiff3</command> for you.</para>
   1.379 +      <programlisting>[extdiff] cmd.kdiff3 =</programlisting>
   1.380 +      <para>If you leave the right hand side of the definition empty,
   1.381 +	as above, the <literal role="hg-ext">extdiff</literal>
   1.382 +	extension uses the name of the command you defined as the name
   1.383 +	of the external program to run.  But these names don't have to
   1.384 +	be the same.  Here, we define a command named
   1.385 +	<quote><literal>hg wibble</literal></quote>, which runs
   1.386 +	<command>kdiff3</command>.</para>
   1.387 +      <programlisting>[extdiff] cmd.wibble = kdiff3</programlisting>
   1.388 +
   1.389 +      <para>You can also specify the default options that you want to
   1.390 +	invoke your diff viewing program with.  The prefix to use is
   1.391 +	<quote><literal>opts.</literal></quote>, followed by the name
   1.392 +	of the command to which the options apply.  This example
   1.393 +	defines a <quote><literal>hg vimdiff</literal></quote> command
   1.394 +	that runs the <command>vim</command> editor's
   1.395 +	<literal>DirDiff</literal> extension.</para>
   1.396 +      <programlisting>[extdiff] cmd.vimdiff = vim opts.vimdiff = -f
   1.397 +	'+next' '+execute "DirDiff" argv(0) argv(1)'</programlisting>
   1.398 +
   1.399 +    </sect2>
   1.400 +  </sect1>
   1.401 +  <sect1 id="sec:hgext:transplant">
   1.402 +    <title>Cherrypicking changes with the <literal
   1.403 +	role="hg-ext">transplant</literal> extension</title>
   1.404 +
   1.405 +    <para>Need to have a long chat with Brendan about this.</para>
   1.406 +
   1.407 +  </sect1>
   1.408 +  <sect1 id="sec:hgext:patchbomb">
   1.409 +    <title>Send changes via email with the <literal
   1.410 +	role="hg-ext">patchbomb</literal> extension</title>
   1.411 +
   1.412 +    <para>Many projects have a culture of <quote>change
   1.413 +	review</quote>, in which people send their modifications to a
   1.414 +      mailing list for others to read and comment on before they
   1.415 +      commit the final version to a shared repository.  Some projects
   1.416 +      have people who act as gatekeepers; they apply changes from
   1.417 +      other people to a repository to which those others don't have
   1.418 +      access.</para>
   1.419 +
   1.420 +    <para>Mercurial makes it easy to send changes over email for
   1.421 +      review or application, via its <literal
   1.422 +	role="hg-ext">patchbomb</literal> extension.  The extension is
   1.423 +      so namd because changes are formatted as patches, and it's usual
   1.424 +      to send one changeset per email message.  Sending a long series
   1.425 +      of changes by email is thus much like <quote>bombing</quote> the
   1.426 +      recipient's inbox, hence <quote>patchbomb</quote>.</para>
   1.427 +
   1.428 +    <para>As usual, the basic configuration of the <literal
   1.429 +	role="hg-ext">patchbomb</literal> extension takes just one or
   1.430 +      two lines in your <filename role="special">
   1.431 +	/.hgrc</filename>.</para>
   1.432 +    <programlisting>[extensions] patchbomb =</programlisting>
   1.433 +    <para>Once you've enabled the extension, you will have a new
   1.434 +      command available, named <command
   1.435 +	role="hg-ext-patchbomb">email</command>.</para>
   1.436 +
   1.437 +    <para>The safest and best way to invoke the <command
   1.438 +	role="hg-ext-patchbomb">email</command> command is to
   1.439 +      <emphasis>always</emphasis> run it first with the <option
   1.440 +	role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option.
   1.441 +      This will show you what the command <emphasis>would</emphasis>
   1.442 +      send, without actually sending anything.  Once you've had a
   1.443 +      quick glance over the changes and verified that you are sending
   1.444 +      the right ones, you can rerun the same command, with the <option
   1.445 +	role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option
   1.446 +      removed.</para>
   1.447 +
   1.448 +    <para>The <command role="hg-ext-patchbomb">email</command> command
   1.449 +      accepts the same kind of revision syntax as every other
   1.450 +      Mercurial command.  For example, this command will send every
   1.451 +      revision between 7 and <literal>tip</literal>, inclusive.</para>
   1.452 +    <programlisting>hg email -n 7:tip</programlisting>
   1.453 +    <para>You can also specify a <emphasis>repository</emphasis> to
   1.454 +      compare with.  If you provide a repository but no revisions, the
   1.455 +      <command role="hg-ext-patchbomb">email</command> command will
   1.456 +      send all revisions in the local repository that are not present
   1.457 +      in the remote repository.  If you additionally specify revisions
   1.458 +      or a branch name (the latter using the <option
   1.459 +	role="hg-ext-patchbomb-cmd-email-opt">hg -b</option> option),
   1.460 +      this will constrain the revisions sent.</para>
   1.461 +
   1.462 +    <para>It's perfectly safe to run the <command
   1.463 +	role="hg-ext-patchbomb">email</command> command without the
   1.464 +      names of the people you want to send to: if you do this, it will
   1.465 +      just prompt you for those values interactively.  (If you're
   1.466 +      using a Linux or Unix-like system, you should have enhanced
   1.467 +      <literal>readline</literal>-style editing capabilities when
   1.468 +      entering those headers, too, which is useful.)</para>
   1.469 +
   1.470 +    <para>When you are sending just one revision, the <command
   1.471 +	role="hg-ext-patchbomb">email</command> command will by
   1.472 +      default use the first line of the changeset description as the
   1.473 +      subject of the single email message it sends.</para>
   1.474 +
   1.475 +    <para>If you send multiple revisions, the <command
   1.476 +	role="hg-ext-patchbomb">email</command> command will usually
   1.477 +      send one message per changeset.  It will preface the series with
   1.478 +      an introductory message, in which you should describe the
   1.479 +      purpose of the series of changes you're sending.</para>
   1.480 +
   1.481 +    <sect2>
   1.482 +      <title>Changing the behaviour of patchbombs</title>
   1.483 +
   1.484 +      <para>Not every project has exactly the same conventions for
   1.485 +	sending changes in email; the <literal
   1.486 +	  role="hg-ext">patchbomb</literal> extension tries to
   1.487 +	accommodate a number of variations through command line
   1.488 +	options.</para>
   1.489 +      <itemizedlist>
   1.490 +	<listitem><para>You can write a subject for the introductory
   1.491 +	    message on the command line using the <option
   1.492 +	      role="hg-ext-patchbomb-cmd-email-opt">hg -s</option>
   1.493 +	    option.  This takes one argument, the text of the subject
   1.494 +	    to use.</para>
   1.495 +	</listitem>
   1.496 +	<listitem><para>To change the email address from which the
   1.497 +	    messages originate, use the <option
   1.498 +	      role="hg-ext-patchbomb-cmd-email-opt">hg -f</option>
   1.499 +	    option.  This takes one argument, the email address to
   1.500 +	    use.</para>
   1.501 +	</listitem>
   1.502 +	<listitem><para>The default behaviour is to send unified diffs
   1.503 +	    (see section <xref linkend="sec:mq:patch"/> for a
   1.504 +	    description of the
   1.505 +	    format), one per message.  You can send a binary bundle
   1.506 +	    instead with the <option
   1.507 +	      role="hg-ext-patchbomb-cmd-email-opt">hg -b</option>
   1.508 +	    option.</para>
   1.509 +	</listitem>
   1.510 +	<listitem><para>Unified diffs are normally prefaced with a
   1.511 +	    metadata header.  You can omit this, and send unadorned
   1.512 +	    diffs, with the <option
   1.513 +	      role="hg-ext-patchbomb-cmd-email-opt">hg
   1.514 +	      --plain</option> option.</para>
   1.515 +	</listitem>
   1.516 +	<listitem><para>Diffs are normally sent <quote>inline</quote>,
   1.517 +	    in the same body part as the description of a patch.  This
   1.518 +	    makes it easiest for the largest number of readers to
   1.519 +	    quote and respond to parts of a diff, as some mail clients
   1.520 +	    will only quote the first MIME body part in a message. If
   1.521 +	    you'd prefer to send the description and the diff in
   1.522 +	    separate body parts, use the <option
   1.523 +	      role="hg-ext-patchbomb-cmd-email-opt">hg -a</option>
   1.524 +	    option.</para>
   1.525 +	</listitem>
   1.526 +	<listitem><para>Instead of sending mail messages, you can
   1.527 +	    write them to an <literal>mbox</literal>-format mail
   1.528 +	    folder using the <option
   1.529 +	      role="hg-ext-patchbomb-cmd-email-opt">hg -m</option>
   1.530 +	    option.  That option takes one argument, the name of the
   1.531 +	    file to write to.</para>
   1.532 +	</listitem>
   1.533 +	<listitem><para>If you would like to add a
   1.534 +	    <command>diffstat</command>-format summary to each patch,
   1.535 +	    and one to the introductory message, use the <option
   1.536 +	      role="hg-ext-patchbomb-cmd-email-opt">hg -d</option>
   1.537 +	    option.  The <command>diffstat</command> command displays
   1.538 +	    a table containing the name of each file patched, the
   1.539 +	    number of lines affected, and a histogram showing how much
   1.540 +	    each file is modified.  This gives readers a qualitative
   1.541 +	    glance at how complex a patch is.</para>
   1.542 +	</listitem></itemizedlist>
   1.543 +
   1.544 +    </sect2>
   1.545 +  </sect1>
   1.546 +</chapter>
   1.547 +
   1.548 +<!--
   1.549 +local variables: 
   1.550 +sgml-parent-document: ("00book.xml" "book" "chapter")
   1.551 +end:
   1.552 +-->