hgbook
diff es/hgext.tex @ 358:15a6b61335aa
translated a couple of paragraphs, and updated the table of works in progress
author | Javier Rojas <jerojasro@devnull.li> |
---|---|
date | Thu Oct 23 23:18:59 2008 -0500 (2008-10-23) |
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 Thu Oct 23 23:18:59 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: