hgbook

view es/hgext.tex @ 451:f4904a9b4fdb

Started translating hgext
author Igor TAmara <igor@tamarapatino.org>
date Sat Dec 13 23:55:07 2008 -0500 (2008-12-13)
parents aeda195f54a6
children 3cb3f9b418ea
line source
1 \chapter{Añadir funcionalidad con extensiones}
2 \label{chap:hgext}
4 A pesar de que el corazón de Mercurial es muy completo desde el punto
5 de vista de funcionalidad, carece de características rimbombantes
6 deliberadamente. Esta aproximación de preservar la simplicidad
7 mantiene el programa sencillo tanto para mantenedores como para
8 usuarios.
10 Si embargo Mercurial no le cierra las posibilidades a un conjunto
11 inflexible de órdenes: usted puede añadir características como
12 \emph{extensiones} (aveces llamadas \emph{añadidos}\ndt{plugins}). Ya
13 hemos discutido algunas de estas extensiones en capítulos anteriores:
14 \begin{itemize}
15 \item La sección~\ref{sec:tour-merge:fetch} cubre la extensión
16 \hgext{fetch}; que combina jalar cambios y fusionarlos con los
17 cambios locales en una sola orden: \hgxcmd{fetch}{fetch}.
18 \item En el capítulo~\ref{chap:hook}, cubrimos muchas extensiones que
19 son útiles en funcionalidades relacionadas con ganchos: Los
20 \hgext{acl} añaden listas de control de acceso; \hgext{bugzilla}
21 añade integración con el sistema de seguimiento de fallos Bugzilla; y
22 \hgext{notify} envía notificaciones por correo de nuevos cambios.
23 \item La extensión de administración de parches MQ es tan invaluable
24 que amerita dos capítulos y un apéndice por sí misma.
25 El capítulo~\ref{chap:mq} cubre lo básico; el
26 capítulo~\ref{chap:mq-collab} discute temas avanzados; y el
27 apéndice~\ref{chap:mqref} muestra en detalle cada orden.
28 \end{itemize}
30 En este capítulo cubriremos algunas extensiones adicionales
31 disponibles para Mercurial, y daremos un vistazo a la maquinaria que
32 necesita conocer en caso de que desee escribir una extensión.
33 \begin{itemize}
34 \item En la sección~\ref{sec:hgext:inotify}, discutiremos la
35 posibilidad de mejorar el desempeño \emph{en gran medida} con la extensión
36 \hgext{inotify}.
37 \end{itemize}
39 \section{Mejorar el desempeño con la extensión \hgext{inotify}}
40 \label{sec:hgext:inotify}
42 ¿Desea lograr que las operaciones más comunmente usadas de Mercurial se
43 ejecuten centenas de veces más rápido? ¡A leer!
45 Mercurial tiene gran desempeño bajo circunstancias normales. Por
46 ejemplo, cuando ejecuta la orden \hgcmd{status}, Mercurial tiene que
47 revisar casi todos los ficheros y directorios en su repositorio de
48 forma que pueda desplegar el estado de los ficheros. Muchas otras
49 órdenes tienen que hacer tal trabajo tras bambalinas; por ejemplo la
50 orden \hgcmd{diff} usa la maquinaria de estado para evitar hacer
51 operaciones de comparación costosas en ficheros que obviamente no han
52 cambiado.
54 Dado que obtener el estado de los ficheros es crucial para obtener
55 buen desempeño, los autores de Mercurial han optimizado este código en
56 la medida de lo posible. Sin embargo, no puede obviarse el hecho de
57 que cuando ejecuta \hgcmd{status}, Mercurial tendrá que hacer por lo
58 menos una costosa llamada al sistema por cada archivo administrado
59 para determinar si ha cambiado desde la última vez que se consignó.
60 Para un repositorio suficientemente grande, puede tardar bastante
61 tiempo.
63 Para mostrar en números la magnitud de este efect, creé un repositorio
64 que contenía 150.000 archivos administrador. Tardó diez segundos para
65 ejecutar \hgcmd{status}, a pesar de que \emph{ninguno} de los ficheros
66 había sido modificado.
68 Muchos sistemas operativos modernos contienen una facilidad de
69 notificación de archivos. Si un programa se registra con un servicio
70 apropiado, el sistema operativo le notificará siempre que un fichero
71 de interés haya sido creado, modificado o borrado. En sistemas Linux,
72 el componente del núcleo que lo hace se llama \texttt{inotify}.
74 La extensión \hgext{inotify} habla con el componente \texttt{inotify}
75 del núcleo para optimizar las órdenes de \hgcmd{status}. La extensión
76 tiene dos componentes. Un daemonio está en el fondo recibiendo
77 notificaciones del subsistema \texttt{inotify}. También escucha
78 conexiones de una orden regular de Mercurial. La extensión modifica
79 el comportamiento de Mercurial de tal forma que, en lugar de revisar
80 el sistema de ficheros, le pregunta al daemonio. Dado que el daemonio
81 tiene información perfecta acerca del estado del repositorio, puede
82 responder instantáneamente con el resultado, evitando la necesidad de
83 revisar cada directorio y fichero del repositorio.
85 Retomando los diez segundos que medí al ejecutar la orden
86 \hgcmd{status} de Mercurial sobre un repositorio de 150.000
87 ficheros. Con la extensión \hgext{inotify} habilitada, el tiempo se
88 disipó a 0.1~seconds, un factor \emph{cien veces} más rápido.
90 Antes de continuar, tenga en cuenta algunos detalles:
91 \begin{itemize}
92 \item La extensión \hgext{inotify} es específica de Linux. Porque se
93 enlaza directamente con el subsistema \texttt{inotify} del núcleo
94 Linux, no funciona en otros sistemas operativos.
95 \item Debería funcionar en cualquier distribución Linux a partir de
96 comienzos del 2005. Las distribuciones más antiguas deben tener un
97 kernel sin \texttt{inotify}, o una versión de \texttt{glibc} que no
98 tiene necesariamente el soporte para la interfaz.
99 \item No todos los sistemas de ficheros pueden usarse con la extensión
100 \hgext{inotify}. Los sistemas de ficheros tales como NFS no lo
101 soportan, por ejemplo, si está corriendo Mercurial en vaios
102 sistemas, montados todos sobre el mismo sistema de ficheros en red.
103 El sistema \texttt{inotify} del kernel no tiene forma de saber
104 acerca de los cambios hechos en otro sistema. La mayoría de
105 sistemas de ficheros locales (p.e.~ext3, XFS, ReiserFS) deberían
106 funcionar bien.
107 \end{itemize}
109 Hacia mayo de 2007 la extensión \hgext{inotify} no venía de forma
110 predeterminada en Mercurial\ndt{Desde el 2008 para kernels 2.6 viene
111 en Mercurial, pero no está activada de forma predeterminada}, y es
112 un poco más compleja de activar que otras extensiones. Pero la mejora
113 en el desempeño bien vale la pena!
115 La extensión venía en dos partes: un conjunto de parches al código
116 fuente de Mercurial, y una librería de interfaces de Python hacia el
117 subsistema \texttt{inotify}.
118 \begin{note}
119 Hay \emph{dos} librerías de enlace de Python hacia \texttt{inotify}.
120 Una de ellas se llama \texttt{pyinotify}, y en algunas
121 distribuciones de Linux se encuentra como \texttt{python-inotify}.
122 Esta es la que \emph{no} necesita, puesto que tiene muchos fallos,
123 y es ineficiente para ser práctica.
124 \end{note}
125 Para comenzar, es mejor tener una copia de Mercurial funcional
126 instalada:
127 \begin{note}
128 Si sigue las instrucciones a continuación, estará
129 \emph{reemplazando} y sobreescribiendo cualquier instalación previa
130 de Mercurial que pudiera tener, con el código de Mercurial ``más
131 reciente y peligrosa''. No diga que no se le advirtio!
132 \end{note}
133 \begin{enumerate}
134 \item Clone el repositorio de interfaz entre Python e
135 \texttt{inotify}. Ármelo e instálelo:
136 \begin{codesample4}
137 hg clone http://hg.kublai.com/python/inotify
138 cd inotify
139 python setup.py build --force
140 sudo python setup.py install --skip-build
141 \end{codesample4}
142 \item Clone el repositorio \dirname{crew} de Mercurial. Clone el
143 repositorio de parches de \hgext{inotify} de forma tal que las colas
144 de Mercurial puedan aplicar los parches sobre el repositorio \dirname{crew}.
145 \begin{codesample4}
146 hg clone http://hg.intevation.org/mercurial/crew
147 hg clone crew inotify
148 hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches
149 \end{codesample4}
150 \item Asegúrese de instalar la extensión Colas de Mercurial
151 \hgext{mq} y que estén habilitadas. Si nunca ha usado MQ, lea la
152 sección~\ref{sec:mq:start} para poder comenzar rápidamente.
153 \item Vaya al repositorio de \dirname{inotify} y aplique todos los
154 parches de \hgext{inotify} con la opción \hgxopt{mq}{qpush}{-a} de
155 la orden \hgxcmd{mq}{qpush}.
156 \begin{codesample4}
157 cd inotify
158 hg qpush -a
159 \end{codesample4}
160 Si obtiene un mensaje de error de \hgxcmd{mq}{qpush}, no debería
161 continuar. Mejor pida ayuda.
162 \item Arme e instale la versión parchada de Mercurial.
163 \begin{codesample4}
164 python setup.py build --force
165 sudo python setup.py install --skip-build
166 \end{codesample4}
167 \end{enumerate}
168 Una vez que haya armado una versión funcional parchada de Mercurial,
169 todo lo que necesita es habilitar la extensión \hgext{inotify}
170 colocando una entrada en su \hgrc.
171 \begin{codesample2}
172 [extensions]
173 inotify =
174 \end{codesample2}
175 Cuando la extensión \hgext{inotify} esté habilitada, Mercurial
176 iniciará transparente y automáticamente el daemonio de estado la
177 primera vez que ejecute un comando que requiera estado del
178 repositorio. Ejecuta un daemoniot de estado por repositorio.
180 El daemonio de estado se inicia silenciosamente y se ejecuta en el
181 fondo. Si mira a la lista de procesos en ejecución después de
182 habilitar la extensión \hgext{inotify} y ejecuta unos pocos comandos
183 en diferentes repositorios, verá que hay algunos procesos de
184 \texttt{hg} por ahí, esperando actualizaciones del kernel y
185 solicitudes de Mercurial.
187 La primera vez que ejecuta un comando de Mercurial en un repositorio
188 cuando tiene la extensión \hgext{inotify} habilitada, correrá casi con
189 el mismo desempeño que una orden usual de Mercurial. Esto es debido a
190 que el estado del daemonio necesita aplicar una búsqueda normal sobre
191 el estado para poder tener una línea de partida frente a la cual
192 aplicar posteriormente actualizaciones del núcleo. De todas formas,
193 \emph{todo} comando posterior que haga cualquier clase de revisión del
194 estado debería ser notablemente más rápido en repositorios con incluso
195 un tamaño modesto. Aún mejor, a medida que su repositorio sea más
196 grande, mejor desempeño verá. El daemonio \hgext{inotify} hace
197 operaciones de estado de forma casi instantánea en repositorios de
198 todos los tamaños!
200 Si lo desea, puede iniciar manualmente un daemonio de estado con la orden
201 \hgxcmd{inotify}{inserve}. Esto le da un control un poco más fino
202 acerca de cómo debería ejecutarse el daemonio. Esta orden solamente
203 estará disponible cuando haya habilitado la extensión \hgext{inotify}.
205 Cuando esté usando la extensión \hgext{inotify},
206 \emph{no debería ver diferencia} en el comportamiento de Mercurial,
207 con la única excepción de que los comandos relacionados con el estado
208 deberían ejectuarse mucho más rápido que como solían hacerlo. Debería
209 esperar específicamente que las órdenes no deberían ofrecer salidas
210 distintas; ni ofrecer resultados diferentes. Si alguna de estas
211 situaciones ocurre, por favor reporte el fallo.
213 \section{Soporte flexible de diff con la extensión \hgext{extdiff}}
214 \label{sec:hgext:extdiff}
216 La orden predeterminada \hgcmd{diff} de Mercurial despliega diffs en
217 texto plano unificadas.
218 \interaction{extdiff.diff}
219 Si dese emplear una herramienta externa para desplegar las
220 modificaciones, querrá usar la extensión \hgext{extdiff}. Esta le
221 permitirá usar por ejemplo una herramienta gráfica de diff.
223 La extensión \hgext{extdiff} viene con Mercurial, y es fácil
224 configurarl. En la sección \rcsection{extensions} de su \hgrc,
225 basta con añadir una entrada de una línea para habilitar la extensión.
226 \begin{codesample2}
227 [extensions]
228 extdiff =
229 \end{codesample2}
230 Esto introduce una orden llamada \hgxcmd{extdiff}{extdiff}, que de
231 forma predeterminada usa su orden del sistema \command{diff} para
232 generar un diff unificado de la misma forma que lo hace el comando
233 predeterminado \hgcmd{diff}.
234 \interaction{extdiff.extdiff}
235 El resultado no será exactamente el mismo que con la orden interna
236 \hgcmd{diff}, puesto que la salida de \command{diff} varía de un
237 sistema a otro, incluso pasando las mismas opciones.
239 As the ``\texttt{making snapshot}'' lines of output above imply, the
240 \hgxcmd{extdiff}{extdiff} command works by creating two snapshots of
241 your source tree. The first snapshot is of the source revision; the
242 second, of the target revision or working directory. The
243 \hgxcmd{extdiff}{extdiff} command generates these snapshots in a
244 temporary directory, passes the name of each directory to an external
245 diff viewer, then deletes the temporary directory. For efficiency, it
246 only snapshots the directories and files that have changed between the
247 two revisions.
249 Snapshot directory names have the same base name as your repository.
250 If your repository path is \dirname{/quux/bar/foo}, then \dirname{foo}
251 will be the name of each snapshot directory. Each snapshot directory
252 name has its changeset ID appended, if appropriate. If a snapshot is
253 of revision \texttt{a631aca1083f}, the directory will be named
254 \dirname{foo.a631aca1083f}. A snapshot of the working directory won't
255 have a changeset ID appended, so it would just be \dirname{foo} in
256 this example. To see what this looks like in practice, look again at
257 the \hgxcmd{extdiff}{extdiff} example above. Notice that the diff has
258 the snapshot directory names embedded in its header.
260 The \hgxcmd{extdiff}{extdiff} command accepts two important options.
261 The \hgxopt{extdiff}{extdiff}{-p} option lets you choose a program to
262 view differences with, instead of \command{diff}. With the
263 \hgxopt{extdiff}{extdiff}{-o} option, you can change the options that
264 \hgxcmd{extdiff}{extdiff} passes to the program (by default, these
265 options are ``\texttt{-Npru}'', which only make sense if you're
266 running \command{diff}). In other respects, the
267 \hgxcmd{extdiff}{extdiff} command acts similarly to the built-in
268 \hgcmd{diff} command: you use the same option names, syntax, and
269 arguments to specify the revisions you want, the files you want, and
270 so on.
272 As an example, here's how to run the normal system \command{diff}
273 command, getting it to generate context diffs (using the
274 \cmdopt{diff}{-c} option) instead of unified diffs, and five lines of
275 context instead of the default three (passing \texttt{5} as the
276 argument to the \cmdopt{diff}{-C} option).
277 \interaction{extdiff.extdiff-ctx}
279 Launching a visual diff tool is just as easy. Here's how to launch
280 the \command{kdiff3} viewer.
281 \begin{codesample2}
282 hg extdiff -p kdiff3 -o ''
283 \end{codesample2}
285 If your diff viewing command can't deal with directories, you can
286 easily work around this with a little scripting. For an example of
287 such scripting in action with the \hgext{mq} extension and the
288 \command{interdiff} command, see
289 section~\ref{mq-collab:tips:interdiff}.
291 \subsection{Defining command aliases}
293 It can be cumbersome to remember the options to both the
294 \hgxcmd{extdiff}{extdiff} command and the diff viewer you want to use,
295 so the \hgext{extdiff} extension lets you define \emph{new} commands
296 that will invoke your diff viewer with exactly the right options.
298 All you need to do is edit your \hgrc, and add a section named
299 \rcsection{extdiff}. Inside this section, you can define multiple
300 commands. Here's how to add a \texttt{kdiff3} command. Once you've
301 defined this, you can type ``\texttt{hg kdiff3}'' and the
302 \hgext{extdiff} extension will run \command{kdiff3} for you.
303 \begin{codesample2}
304 [extdiff]
305 cmd.kdiff3 =
306 \end{codesample2}
307 If you leave the right hand side of the definition empty, as above,
308 the \hgext{extdiff} extension uses the name of the command you defined
309 as the name of the external program to run. But these names don't
310 have to be the same. Here, we define a command named ``\texttt{hg
311 wibble}'', which runs \command{kdiff3}.
312 \begin{codesample2}
313 [extdiff]
314 cmd.wibble = kdiff3
315 \end{codesample2}
317 You can also specify the default options that you want to invoke your
318 diff viewing program with. The prefix to use is ``\texttt{opts.}'',
319 followed by the name of the command to which the options apply. This
320 example defines a ``\texttt{hg vimdiff}'' command that runs the
321 \command{vim} editor's \texttt{DirDiff} extension.
322 \begin{codesample2}
323 [extdiff]
324 cmd.vimdiff = vim
325 opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)'
326 \end{codesample2}
328 \section{Cherrypicking changes with the \hgext{transplant} extension}
329 \label{sec:hgext:transplant}
331 Need to have a long chat with Brendan about this.
333 \section{Send changes via email with the \hgext{patchbomb} extension}
334 \label{sec:hgext:patchbomb}
336 Many projects have a culture of ``change review'', in which people
337 send their modifications to a mailing list for others to read and
338 comment on before they commit the final version to a shared
339 repository. Some projects have people who act as gatekeepers; they
340 apply changes from other people to a repository to which those others
341 don't have access.
343 Mercurial makes it easy to send changes over email for review or
344 application, via its \hgext{patchbomb} extension. The extension is so
345 namd because changes are formatted as patches, and it's usual to send
346 one changeset per email message. Sending a long series of changes by
347 email is thus much like ``bombing'' the recipient's inbox, hence
348 ``patchbomb''.
350 As usual, the basic configuration of the \hgext{patchbomb} extension
351 takes just one or two lines in your \hgrc.
352 \begin{codesample2}
353 [extensions]
354 patchbomb =
355 \end{codesample2}
356 Once you've enabled the extension, you will have a new command
357 available, named \hgxcmd{patchbomb}{email}.
359 The safest and best way to invoke the \hgxcmd{patchbomb}{email}
360 command is to \emph{always} run it first with the
361 \hgxopt{patchbomb}{email}{-n} option. This will show you what the
362 command \emph{would} send, without actually sending anything. Once
363 you've had a quick glance over the changes and verified that you are
364 sending the right ones, you can rerun the same command, with the
365 \hgxopt{patchbomb}{email}{-n} option removed.
367 The \hgxcmd{patchbomb}{email} command accepts the same kind of
368 revision syntax as every other Mercurial command. For example, this
369 command will send every revision between 7 and \texttt{tip},
370 inclusive.
371 \begin{codesample2}
372 hg email -n 7:tip
373 \end{codesample2}
374 You can also specify a \emph{repository} to compare with. If you
375 provide a repository but no revisions, the \hgxcmd{patchbomb}{email}
376 command will send all revisions in the local repository that are not
377 present in the remote repository. If you additionally specify
378 revisions or a branch name (the latter using the
379 \hgxopt{patchbomb}{email}{-b} option), this will constrain the
380 revisions sent.
382 It's perfectly safe to run the \hgxcmd{patchbomb}{email} command
383 without the names of the people you want to send to: if you do this,
384 it will just prompt you for those values interactively. (If you're
385 using a Linux or Unix-like system, you should have enhanced
386 \texttt{readline}-style editing capabilities when entering those
387 headers, too, which is useful.)
389 When you are sending just one revision, the \hgxcmd{patchbomb}{email}
390 command will by default use the first line of the changeset
391 description as the subject of the single email message it sends.
393 If you send multiple revisions, the \hgxcmd{patchbomb}{email} command
394 will usually send one message per changeset. It will preface the
395 series with an introductory message, in which you should describe the
396 purpose of the series of changes you're sending.
398 \subsection{Changing the behaviour of patchbombs}
400 Not every project has exactly the same conventions for sending changes
401 in email; the \hgext{patchbomb} extension tries to accommodate a
402 number of variations through command line options.
403 \begin{itemize}
404 \item You can write a subject for the introductory message on the
405 command line using the \hgxopt{patchbomb}{email}{-s} option. This
406 takes one argument, the text of the subject to use.
407 \item To change the email address from which the messages originate,
408 use the \hgxopt{patchbomb}{email}{-f} option. This takes one
409 argument, the email address to use.
410 \item The default behaviour is to send unified diffs (see
411 section~\ref{sec:mq:patch} for a description of the format), one per
412 message. You can send a binary bundle instead with the
413 \hgxopt{patchbomb}{email}{-b} option.
414 \item Unified diffs are normally prefaced with a metadata header. You
415 can omit this, and send unadorned diffs, with the
416 \hgxopt{patchbomb}{email}{--plain} option.
417 \item Diffs are normally sent ``inline'', in the same body part as the
418 description of a patch. This makes it easiest for the largest
419 number of readers to quote and respond to parts of a diff, as some
420 mail clients will only quote the first MIME body part in a message.
421 If you'd prefer to send the description and the diff in separate
422 body parts, use the \hgxopt{patchbomb}{email}{-a} option.
423 \item Instead of sending mail messages, you can write them to an
424 \texttt{mbox}-format mail folder using the
425 \hgxopt{patchbomb}{email}{-m} option. That option takes one
426 argument, the name of the file to write to.
427 \item If you would like to add a \command{diffstat}-format summary to
428 each patch, and one to the introductory message, use the
429 \hgxopt{patchbomb}{email}{-d} option. The \command{diffstat}
430 command displays a table containing the name of each file patched,
431 the number of lines affected, and a histogram showing how much each
432 file is modified. This gives readers a qualitative glance at how
433 complex a patch is.
434 \end{itemize}
436 %%% Local Variables:
437 %%% mode: latex
438 %%% TeX-master: "00book"
439 %%% End: