hgbook

diff en/ch14-hgext.xml @ 729:1819dd65d5f6

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