Mercurial > hgbook
view es/hgext.tex @ 553:6d4465f04bb7
Translated alias from extensions
author | Igor Támara <igor@tamarapatino.org> |
---|---|
date | Mon, 15 Dec 2008 23:37:01 -0500 |
parents | 3cb3f9b418ea |
children | b96d80be5a60 |
line wrap: on
line source
\chapter{Añadir funcionalidad con extensiones} \label{chap:hgext} A pesar de que el corazón de Mercurial es muy completo desde el punto de vista de funcionalidad, carece de características rimbombantes deliberadamente. Esta aproximación de preservar la simplicidad mantiene el programa sencillo tanto para mantenedores como para usuarios. Si embargo Mercurial no le cierra las posibilidades a un conjunto inflexible de órdenes: usted puede añadir características como \emph{extensiones} (aveces llamadas \emph{añadidos}\ndt{plugins}). Ya hemos discutido algunas de estas extensiones en capítulos anteriores: \begin{itemize} \item La sección~\ref{sec:tour-merge:fetch} cubre la extensión \hgext{fetch}; que combina jalar cambios y fusionarlos con los cambios locales en una sola orden: \hgxcmd{fetch}{fetch}. \item En el capítulo~\ref{chap:hook}, cubrimos muchas extensiones que son útiles en funcionalidades relacionadas con ganchos: Los \hgext{acl} añaden listas de control de acceso; \hgext{bugzilla} añade integración con el sistema de seguimiento de fallos Bugzilla; y \hgext{notify} envía notificaciones por correo de nuevos cambios. \item La extensión de administración de parches MQ es tan invaluable que amerita dos capítulos y un apéndice por sí misma. El capítulo~\ref{chap:mq} cubre lo básico; el capítulo~\ref{chap:mq-collab} discute temas avanzados; y el apéndice~\ref{chap:mqref} muestra en detalle cada orden. \end{itemize} En este capítulo cubriremos algunas extensiones adicionales disponibles para Mercurial, y daremos un vistazo a la maquinaria que necesita conocer en caso de que desee escribir una extensión. \begin{itemize} \item En la sección~\ref{sec:hgext:inotify}, discutiremos la posibilidad de mejorar el desempeño \emph{en gran medida} con la extensión \hgext{inotify}. \end{itemize} \section{Mejorar el desempeño con la extensión \hgext{inotify}} \label{sec:hgext:inotify} ¿Desea lograr que las operaciones más comunmente usadas de Mercurial se ejecuten centenas de veces más rápido? ¡A leer! Mercurial tiene gran desempeño bajo circunstancias normales. Por ejemplo, cuando ejecuta la orden \hgcmd{status}, Mercurial tiene que revisar casi todos los ficheros y directorios en su repositorio de forma que pueda desplegar el estado de los ficheros. Muchas otras órdenes tienen que hacer tal trabajo tras bambalinas; por ejemplo la orden \hgcmd{diff} usa la maquinaria de estado para evitar hacer operaciones de comparación costosas en ficheros que obviamente no han cambiado. Dado que obtener el estado de los ficheros es crucial para obtener buen desempeño, los autores de Mercurial han optimizado este código en la medida de lo posible. Sin embargo, no puede obviarse el hecho de que cuando ejecuta \hgcmd{status}, Mercurial tendrá que hacer por lo menos una costosa llamada al sistema por cada archivo administrado para determinar si ha cambiado desde la última vez que se consignó. Para un repositorio suficientemente grande, puede tardar bastante tiempo. Para mostrar en números la magnitud de este efect, creé un repositorio que contenía 150.000 archivos administrador. Tardó diez segundos para ejecutar \hgcmd{status}, a pesar de que \emph{ninguno} de los ficheros había sido modificado. Muchos sistemas operativos modernos contienen una facilidad de notificación de archivos. Si un programa se registra con un servicio apropiado, el sistema operativo le notificará siempre que un fichero de interés haya sido creado, modificado o borrado. En sistemas Linux, el componente del núcleo que lo hace se llama \texttt{inotify}. La extensión \hgext{inotify} habla con el componente \texttt{inotify} del núcleo para optimizar las órdenes de \hgcmd{status}. La extensión tiene dos componentes. Un daemonio está en el fondo recibiendo notificaciones del subsistema \texttt{inotify}. También escucha conexiones de una orden regular de Mercurial. La extensión modifica el comportamiento de Mercurial de tal forma que, en lugar de revisar el sistema de ficheros, le pregunta al daemonio. Dado que el daemonio tiene información perfecta acerca del estado del repositorio, puede responder instantáneamente con el resultado, evitando la necesidad de revisar cada directorio y fichero del repositorio. Retomando los diez segundos que medí al ejecutar la orden \hgcmd{status} de Mercurial sobre un repositorio de 150.000 ficheros. Con la extensión \hgext{inotify} habilitada, el tiempo se disipó a 0.1~seconds, un factor \emph{cien veces} más rápido. Antes de continuar, tenga en cuenta algunos detalles: \begin{itemize} \item La extensión \hgext{inotify} es específica de Linux. Porque se enlaza directamente con el subsistema \texttt{inotify} del núcleo Linux, no funciona en otros sistemas operativos. \item Debería funcionar en cualquier distribución Linux a partir de comienzos del 2005. Las distribuciones más antiguas deben tener un kernel sin \texttt{inotify}, o una versión de \texttt{glibc} que no tiene necesariamente el soporte para la interfaz. \item No todos los sistemas de ficheros pueden usarse con la extensión \hgext{inotify}. Los sistemas de ficheros tales como NFS no lo soportan, por ejemplo, si está corriendo Mercurial en vaios sistemas, montados todos sobre el mismo sistema de ficheros en red. El sistema \texttt{inotify} del kernel no tiene forma de saber acerca de los cambios hechos en otro sistema. La mayoría de sistemas de ficheros locales (p.e.~ext3, XFS, ReiserFS) deberían funcionar bien. \end{itemize} Hacia mayo de 2007 la extensión \hgext{inotify} no venía de forma predeterminada en Mercurial\ndt{Desde el 2008 para kernels 2.6 viene en Mercurial, pero no está activada de forma predeterminada}, y es un poco más compleja de activar que otras extensiones. Pero la mejora en el desempeño bien vale la pena! La extensión venía en dos partes: un conjunto de parches al código fuente de Mercurial, y una librería de interfaces de Python hacia el subsistema \texttt{inotify}. \begin{note} Hay \emph{dos} librerías de enlace de Python hacia \texttt{inotify}. Una de ellas se llama \texttt{pyinotify}, y en algunas distribuciones de Linux se encuentra como \texttt{python-inotify}. Esta es la que \emph{no} necesita, puesto que tiene muchos fallos, y es ineficiente para ser práctica. \end{note} Para comenzar, es mejor tener una copia de Mercurial funcional instalada: \begin{note} Si sigue las instrucciones a continuación, estará \emph{reemplazando} y sobreescribiendo cualquier instalación previa de Mercurial que pudiera tener, con el código de Mercurial ``más reciente y peligrosa''. No diga que no se le advirtio! \end{note} \begin{enumerate} \item Clone el repositorio de interfaz entre Python e \texttt{inotify}. Ármelo e instálelo: \begin{codesample4} hg clone http://hg.kublai.com/python/inotify cd inotify python setup.py build --force sudo python setup.py install --skip-build \end{codesample4} \item Clone el repositorio \dirname{crew} de Mercurial. Clone el repositorio de parches de \hgext{inotify} de forma tal que las colas de Mercurial puedan aplicar los parches sobre el repositorio \dirname{crew}. \begin{codesample4} hg clone http://hg.intevation.org/mercurial/crew hg clone crew inotify hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches \end{codesample4} \item Asegúrese de instalar la extensión Colas de Mercurial \hgext{mq} y que estén habilitadas. Si nunca ha usado MQ, lea la sección~\ref{sec:mq:start} para poder comenzar rápidamente. \item Vaya al repositorio de \dirname{inotify} y aplique todos los parches de \hgext{inotify} con la opción \hgxopt{mq}{qpush}{-a} de la orden \hgxcmd{mq}{qpush}. \begin{codesample4} cd inotify hg qpush -a \end{codesample4} Si obtiene un mensaje de error de \hgxcmd{mq}{qpush}, no debería continuar. Mejor pida ayuda. \item Arme e instale la versión parchada de Mercurial. \begin{codesample4} python setup.py build --force sudo python setup.py install --skip-build \end{codesample4} \end{enumerate} Una vez que haya armado una versión funcional parchada de Mercurial, todo lo que necesita es habilitar la extensión \hgext{inotify} colocando una entrada en su \hgrc. \begin{codesample2} [extensions] inotify = \end{codesample2} Cuando la extensión \hgext{inotify} esté habilitada, Mercurial iniciará transparente y automáticamente el daemonio de estado la primera vez que ejecute un comando que requiera estado del repositorio. Ejecuta un daemoniot de estado por repositorio. El daemonio de estado se inicia silenciosamente y se ejecuta en el fondo. Si mira a la lista de procesos en ejecución después de habilitar la extensión \hgext{inotify} y ejecuta unos pocos comandos en diferentes repositorios, verá que hay algunos procesos de \texttt{hg} por ahí, esperando actualizaciones del kernel y solicitudes de Mercurial. La primera vez que ejecuta un comando de Mercurial en un repositorio cuando tiene la extensión \hgext{inotify} habilitada, correrá casi con el mismo desempeño que una orden usual de Mercurial. Esto es debido a que el estado del daemonio necesita aplicar una búsqueda normal sobre el estado para poder tener una línea de partida frente a la cual aplicar posteriormente actualizaciones del núcleo. De todas formas, \emph{todo} comando posterior que haga cualquier clase de revisión del estado debería ser notablemente más rápido en repositorios con incluso un tamaño modesto. Aún mejor, a medida que su repositorio sea más grande, mejor desempeño verá. El daemonio \hgext{inotify} hace operaciones de estado de forma casi instantánea en repositorios de todos los tamaños! Si lo desea, puede iniciar manualmente un daemonio de estado con la orden \hgxcmd{inotify}{inserve}. Esto le da un control un poco más fino acerca de cómo debería ejecutarse el daemonio. Esta orden solamente estará disponible cuando haya habilitado la extensión \hgext{inotify}. Cuando esté usando la extensión \hgext{inotify}, \emph{no debería ver diferencia} en el comportamiento de Mercurial, con la única excepción de que los comandos relacionados con el estado deberían ejectuarse mucho más rápido que como solían hacerlo. Debería esperar específicamente que las órdenes no deberían ofrecer salidas distintas; ni ofrecer resultados diferentes. Si alguna de estas situaciones ocurre, por favor reporte el fallo. \section{Soporte flexible de diff con la extensión \hgext{extdiff}} \label{sec:hgext:extdiff} La orden predeterminada \hgcmd{diff} de Mercurial despliega diffs en texto plano unificadas. \interaction{extdiff.diff} Si dese emplear una herramienta externa para desplegar las modificaciones, querrá usar la extensión \hgext{extdiff}. Esta le permitirá usar por ejemplo una herramienta gráfica de diff. La extensión \hgext{extdiff} viene con Mercurial, y es fácil configurarl. En la sección \rcsection{extensions} de su \hgrc, basta con añadir una entrada de una línea para habilitar la extensión. \begin{codesample2} [extensions] extdiff = \end{codesample2} Esto introduce una orden llamada \hgxcmd{extdiff}{extdiff}, que de forma predeterminada usa su orden del sistema \command{diff} para generar un diff unificado de la misma forma que lo hace el comando predeterminado \hgcmd{diff}. \interaction{extdiff.extdiff} El resultado no será exactamente el mismo que con la orden interna \hgcmd{diff}, puesto que la salida de \command{diff} varía de un sistema a otro, incluso pasando las mismas opciones. Como lo indican las líneas``\texttt{making snapshot}'', la orden \hgxcmd{extdiff}{extdiff} funciona creando dos instantáneas de su árbol de fuentes. La primera instantánea es la revisión fuente; la segunda es la revisión objetivo del directorio de trabajo. La orden \hgxcmd{extdiff}{extdiff} genera estas instantáneas en un directorio temporal, pasa el nombre de cada directorio a un visor de diffs temporal y borra los directorios temporales. Por cuestiones de eficiencia solamente genera instantáneas de los directorios y ficheros que han cambiado entre dos revisiones. Los nombres de los directorios de instantáneas tienen los mismos nombres base de su repositorio. Si su repositorio tiene por ruta \dirname{/quux/bar/foo}, \dirname{foo} será el nombre de cada instantánea de directorio. Cada instantánea de directorio tiene sus identificadores de conjuntos de cambios al final del nombre en caso de que sea apropiado. Si una instantánea viene de la revisión \texttt{a631aca1083f}, el directorio se llamará \dirname{foo.a631aca1083f}. Una instantánea del directorio de trabajo no tendrá el identificador del conjunto de cambios, y por lo tanto será solamente \dirname{foo} en este ejemplo. Para ver cómo luce en la práctica, veamos de nuevo el ejemplo \hgxcmd{extdiff}{extdiff} antes mencionado. Tenga en cuenta que los diffs tienen los nombres de las instantáneas de directorio dentro de su encabezado. La orden \hgxcmd{extdiff}{extdiff} acepta dos opciones importantes. La opción \hgxopt{extdiff}{extdiff}{-p} le permite elegir un programa para ver las diferencias, en lugar de \command{diff}. Con la opción \hgxopt{extdiff}{extdiff}{-o} puede cambiar las opciones que \hgxcmd{extdiff}{extdiff} pasa a tal programa(de forma predeterminada las opciones son``\texttt{-Npru}'', que tienen sentido únicamente si está usando \command{diff}). En otros aspectos, la orden \hgxcmd{extdiff}{extdiff} actúa de forma similar a como lo hace la orden \hgcmd{diff} de Mercurial: usted usa los mismos nombres de opciones, sintaxis y argumentos para especificar las revisiones y los ficheros que quiere, y así sucesivamente. Por ejemplo, para ejecutar la orden usual del sistema \command{diff}, para lograr que se generen diferencias de contexto (con la opción \cmdopt{diff}{-c}) en lugar de diferencias unificadas, y cinco líneas de contexto en lugar de las tres predeterminadas(pasando \texttt{5} como argumento a la opción \cmdopt{diff}{-C}). \interaction{extdiff.extdiff-ctx} Es sencillo lanzar unas herramienta usual de diferencias. Para lanzar el visor \command{kdiff3}: \begin{codesample2} hg extdiff -p kdiff3 -o '' \end{codesample2} Si su orden para visualizar diferencias no puede tratar con directorios, puede usar un poco de scripting para lograrlo. Un ejemplo de un script con la extensión \hgext{mq} junto con la orden \command{interdiff} está en la sección~\ref{mq-collab:tips:interdiff}. \subsection{Definición de alias de comandos} Acordarse de todas las opciones de las órdenes \hgxcmd{extdiff}{extdiff} y el visor de diferencias de su preferencia puede ser dispendioso, y por lo tanto la extensión \hgext{extdiff} le permite definir \emph{nuevas} órdenes que invocarán su visor de diferencias con las opciones exactas. Basta con editar su fichero \hgrc, y añadir una sección llamada \rcsection{extdiff}. Dentro de esta sección puede definir varias órdenes. Mostraremos como añadir la orden \texttt{kdiff3}. Después de definido, puede teclear ``\texttt{hg kdiff3}'' y la extensión a \hgext{extdiff} ejecutará la orden \command{kdiff3}. \begin{codesample2} [extdiff] cmd.kdiff3 = \end{codesample2} Si deja vacía la porción derecha de la definición, como en el ejemplo, la extensión \hgext{extdiff} usa el nombre de la orden se definirá como el nombre del programa externo a ejecutar. Pero tales nombres no tienen por qué ser iguales. Definimos ahora la orden llamada ``\texttt{hg wibble}'', que ejecuta \command{kdiff3}. \begin{codesample2} [extdiff] cmd.wibble = kdiff3 \end{codesample2} También puede especificar las opciones predeterminadas con las cuales desea invocar el visor de diferencias. Se usa el prefijo ``\texttt{opts.}'', seguido por el nombre de la orden a la cual se aplican las opciones. En este ejemplos se define la orden ``\texttt{hg vimdiff}'' que ejecuta la extensión \texttt{DirDiff} del editor \command{vim}. \begin{codesample2} [extdiff] cmd.vimdiff = vim opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)' \end{codesample2} \section{Uso de la extensión \hgext{transplant} para seleccionar} \label{sec:hgext:transplant} Need to have a long chat with Brendan about this. \section{Enviar cambios vía correo electrónico con la extensión \hgext{patchbomb}} \label{sec:hgext:patchbomb} Varios proyectos tienen la cultura de ``revisión de cambios'', en la cual la gente envía sus modificaciones a una lista de correo para que otros las lean y comenten antes de consignar la versión final a un repositorio compartido. Algunos proyectos tienen personas que actúan como cancerberos; ellos aplican los cambios de otras personas a un repositorio para aquellos que no tienen acceso. Mercurial facilita enviar cambios por correo para revisión o aplicación gracias a su extensión \hgext{patchbomb}. La extensión es tan popular porque los cambios se formatean como parches y es usual que se envía un conjunto de cambios por cada correo. Enviar una gran cantidad de cambios por correos se llama por tanto ``bombardear'' el buzón de entrada del destinatario, de ahí su nombre ``bombardeo de parches''. As usual, the basic configuration of the \hgext{patchbomb} extension takes just one or two lines in your \hgrc. \begin{codesample2} [extensions] patchbomb = \end{codesample2} Once you've enabled the extension, you will have a new command available, named \hgxcmd{patchbomb}{email}. The safest and best way to invoke the \hgxcmd{patchbomb}{email} command is to \emph{always} run it first with the \hgxopt{patchbomb}{email}{-n} option. This will show you what the command \emph{would} send, without actually sending anything. Once you've had a quick glance over the changes and verified that you are sending the right ones, you can rerun the same command, with the \hgxopt{patchbomb}{email}{-n} option removed. The \hgxcmd{patchbomb}{email} command accepts the same kind of revision syntax as every other Mercurial command. For example, this command will send every revision between 7 and \texttt{tip}, inclusive. \begin{codesample2} hg email -n 7:tip \end{codesample2} You can also specify a \emph{repository} to compare with. If you provide a repository but no revisions, the \hgxcmd{patchbomb}{email} command will send all revisions in the local repository that are not present in the remote repository. If you additionally specify revisions or a branch name (the latter using the \hgxopt{patchbomb}{email}{-b} option), this will constrain the revisions sent. It's perfectly safe to run the \hgxcmd{patchbomb}{email} command without the names of the people you want to send to: if you do this, it will just prompt you for those values interactively. (If you're using a Linux or Unix-like system, you should have enhanced \texttt{readline}-style editing capabilities when entering those headers, too, which is useful.) When you are sending just one revision, the \hgxcmd{patchbomb}{email} command will by default use the first line of the changeset description as the subject of the single email message it sends. If you send multiple revisions, the \hgxcmd{patchbomb}{email} command will usually send one message per changeset. It will preface the series with an introductory message, in which you should describe the purpose of the series of changes you're sending. \subsection{Changing the behaviour of patchbombs} Not every project has exactly the same conventions for sending changes in email; the \hgext{patchbomb} extension tries to accommodate a number of variations through command line options. \begin{itemize} \item You can write a subject for the introductory message on the command line using the \hgxopt{patchbomb}{email}{-s} option. This takes one argument, the text of the subject to use. \item To change the email address from which the messages originate, use the \hgxopt{patchbomb}{email}{-f} option. This takes one argument, the email address to use. \item The default behaviour is to send unified diffs (see section~\ref{sec:mq:patch} for a description of the format), one per message. You can send a binary bundle instead with the \hgxopt{patchbomb}{email}{-b} option. \item Unified diffs are normally prefaced with a metadata header. You can omit this, and send unadorned diffs, with the \hgxopt{patchbomb}{email}{--plain} option. \item Diffs are normally sent ``inline'', in the same body part as the description of a patch. This makes it easiest for the largest number of readers to quote and respond to parts of a diff, as some mail clients will only quote the first MIME body part in a message. If you'd prefer to send the description and the diff in separate body parts, use the \hgxopt{patchbomb}{email}{-a} option. \item Instead of sending mail messages, you can write them to an \texttt{mbox}-format mail folder using the \hgxopt{patchbomb}{email}{-m} option. That option takes one argument, the name of the file to write to. \item If you would like to add a \command{diffstat}-format summary to each patch, and one to the introductory message, use the \hgxopt{patchbomb}{email}{-d} option. The \command{diffstat} command displays a table containing the name of each file patched, the number of lines affected, and a histogram showing how much each file is modified. This gives readers a qualitative glance at how complex a patch is. \end{itemize} %%% Local Variables: %%% mode: latex %%% TeX-master: "00book" %%% End: