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