hgbook

diff es/hgext.tex @ 415:0eda2936ef77

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