view es/mq.tex @ 545:40ba5d8583c7

Translated some more paragraphs of mq to spanish
author Igor TAmara <igor@tamarapatino.org>
date Mon, 08 Dec 2008 23:53:54 -0500
parents da4d34e0e250
children 93e7700c0322
line wrap: on
line source

\chapter{Administración de cambios con Colas de Mercurial}
\label{chap:mq}

\section{El problema de la administración de parches}
\label{sec:mq:patch-mgmt}

Un escenario frecuente: usted necesita instalar un paquete de software
desde las fuentes, pero encuentra un fallo que debe arreglar antes de
poder comenzar a usarlo.  Hace sus cambios, y se olvida del paquete
por un tiempo, unos meses después necesita actualizar a una nueva
versión del paquete.  Si la nueva versión del paquete todavía tiene el
fallo, debe extraer su arreglo del árbol de fuentes anteriores y
aplicarlo a la nueva versión.  Una tarea tediosa en la cual es fácil
equivocarse.

Este es un caso simple del problema del ``manejo de parches''.  Usted
tiene un árbol de fuentes del ``mantenedor principal'' que no puede
cambiar: necesita hacer algunos cambios locales sobre el árbol
principal; y desearía poder mantener tales cambios separados, de forma
tal que pueda aplicarlos a versiones más nuevas del árbol principal.

El problema de administración de parches surge en muchas situaciones.
Probablemente la más visible es cuando un usuario de un proyecto de
software de fuentes abiertas contribuye con un arreglo de un fallo o
una nueva característica a los mantenedores del proyecto en la forma
de un parche.

Aquellos que distribuyen sistemas operativos que incluyen programas
abiertos usualmente requieren hacer cambios en los paquetes que
distribuyen de tal forma que se armen apropiadamente en sus ambientes.

Cuando hay pocos cambios por mantener, es muy sencillo administrar un
solo parche con los programas estándar \command{diff} y
\command{patch}( ver la sección~\ref{sec:mq:patch} para ver cómo
emplear tales herramientas). Cuando la cantidad de cambios comienza a
crecer, tiene sentido mantener parches como ``porciones de trabajo''
individual, de forma que cada cambio contiene solamente un arreglo de
un fallo(el parche puede modificar varios archivos, pero está
``haciendo una sola cosa''), y puede tener cierta cantidad de tales
parches para diferentes fallos y cambios locales.  En esta situación,
si envía un parche que arregla un fallo a los mantenedores principales
de un paquete y ellos incluyen su arreglo en una publicación
posterior, puede deshacerse de tal parche cuando se actualice a la
nueva versión.

Mantener un solo parche frente a un árbol principal es algo tedioso y
es fácil equivocarse, pero no es difícil.  Aunque, la complejidad del
problema crece rápidamente a medida que la cantidad de parches que
tiene que mantener crece.  Con más que una pequeña cantidad de
cambios, entender cuáles ha aplicado se convierte de algo desordenado
a algo avasallante.

Afortunadamente Mercurial provee una extensión poderos: Colas de
Mercurial( o simplemente ``MQ''), que simplifica en gran medida el
problema de administración de parches.

\section{La prehistoria de las Colas de Mercurial}
\label{sec:mq:history}

A finales de los 90s, muchos desarrolladores del núcleo de Linux
comenzaron a mantener ``series de parches'' que modificaron el
comportamiento del núcleo de Linux.  Algunos se enfocaban en
estabilidad, otros en aumentar las características, y otros un poco
más especulativos.

Los tamaños de las series de parches crecieron rápidamente.  En el
2002, Andrew Morton publicó algunos guiones de línea de órdenes que
estuvo usando para automatizar la tarea de administrar su cola de
parches.  Andrew usó exitósamente tales guiones para administrar
centenas( aveces millares) de parches en el núcleo de Linux.

\subsection{Trabajar parches con quilt}
\label{sec:mq:quilt}

A comienzos del 2003, Andreas Gruenbacher y Martin Quinson tomaron la
aproximación de los guiones de Andrew y publicaron una herramienta
llamada
``patchwork quilt''~\cite{web:quilt}, o simplemente ``quilt''
(ver~\cite{gruenbacher:2005} el paper que lo describe).  Dado que
quilt automatizaba sustancialmente la administración de parches, fue
adoptado en gran medida por desarrolladores de programas abiertos.

Quilt maneja una \emph{pila de parches} sobre un árbol de directorios.
Para comenzar, usted le indica a quilt que administre un árbol de
directorios, le indica qué archivos manejar; Este almacena los nombres
y los contenidos de estos archivos.  Para arreglar un fallo, usted
crea un nuevo parche(con una sola orden), edita los archivos que está
arreglando y ``refresca'' el parche.

El paso de refresco hace que quilt revise el árbol de directorios;
actualiza el parche con todos los cambios que usted haya hecho.  Puede
crear otro parche sobre el primero, que hará seguimiento de los
cambios requeridos para modificar el árbol desde ``el árbol con un
parch aplicado'' a un ``árbol con dos parches aplicados''.

Usted puede \emph{elegir} qué cambios desea aplicar al árbol.  Si
``pop''\ndt{saca} un parche, los cambios hechos por tal parchve
desapareceŕan del árbol de directorios.  Quilt recuerda qué parches ha
sacado, para que pueda ``introducirlos''\ndt{push} posteriormente, así el
árbol de directorios se restaurará con las modificaciones que vienen
del parche.  Lo más importante es que puede ejecutar la orden
``refresh'' en cualquier momento, y el último parche será
actualizado.  Esto significa que puede, en cualquier momento, cambiar
qué parches serán aplicados y qué modificaciones hacen ellos.

Quilt no tiene nada que ver con herramientas de control de versiones,
y puede trabajar bien sobre un conjunto de fuentes que viene de un
archivo comprimido y empaquetado o una copia de trabajo de Subversion.

\subsection{Pasar de trabajo con parches con Quilt hacia Colas de Mercurial}
\label{sec:mq:quilt-mq}

A mediados de 2005, Chris Mason tomó las características de quilt y
escribió una extensión que llamó Colas de Mercurial\ndt{Mercurial
Queues}, que proporcionó un comportamiento a Mercurial al estilo
quilt.

La diferencia clave entre quilt y MQ es que quilt no sabe nada acerca
del sistema de control de revisiones, mientras que MQ está
\emph{integrado} con Mercurial.  Cada parche que usted introduce se
representa como un conjunto de cambios en Mercurial.  Si sustrae un
parche, el conjunto de cambios desaparece.\ndt{introduce originalmente es
push y pop es sustraer en este contexto, usaremos el original en inglés
cuando encontremos que facilita la comprensión}

Dado que quilt no se preocupa por las herramientas de control de
revisiones, continúa siendo una porción de software tremendamente útil
para aquellas situaciones en las cuales no puede usar Mercurial y MQ.

\section{La gran ventaja de MQ}

No puedo sobreestimar el valor que MQ ofrece en la unificación de
parches y el control de revisiones.

La principal razón por la cual los parches han persistido en el mundo
del software libre y de fuentes abiertas--a pesar de la creciente
disponibilidad de herramientas poderosas de control de revisiones-- es
la \emph{agilidad} que ofrecen.

Las herramientas tradicionales de control de revisiones llevan un
registro permanente e irreversible de todo lo que usted hace.  A pesar
de que esto tiene gran valor, también es bastante sutil.  Si requiere
realizar un experimento ((((wild-eyed)))), debe ser cuidadoso en cómo
lo hace, o puede dejar trazas innecesarias--o peor aún,
desconcertantes o desestabilizantes--- de los pasos y errores en el
registro de revisiones de forma permanente.

En contraste, con la cohesión de MQ con el control de revisiones
distribuidos y los parches, resulta más sencillo aislar su trabajo.
Sus parches viven encima de la historia de revisiones normales, y
puede hacer que ellos desaparezcan o reaparezcan cuando lo desee.  Si
no le gusta un parche, puede desecharlo.  Si un parche no satisface
todo lo que usted desea, puede arreglarlo---tantas veces como lo
requiera, hasta que lo haya refinado lo suficiente hacia sus
expectativas.

Por ejemplo, la integración de parches con el control de revisiones
hace que el entender los parches y revisar sus efectos---y sus
interacciones con el código en el cuál están enlazados--- sea
\emph{mucho} más sencillo.  Dado que todo parche que se aplique tiene
un conjunto de cambios asociado, puede usar
\hgcmdargs{log}{\emph{filename}} para ver qué conjuntos de cambios y
parches afectaron un fichero.  Puede usar la orden \hgext{bisect} para
hacer una búsqueda binaria sobre todos los conjuntos de cambios y
parches aplicados para ver dónde se introdujo un fallo o dónde fue
arreglado.  Puede usar la orden \hgcmd{annotate} para ver qué
conjuntos de cambios o parches modificaron una línea particular de un
archivo fuente. Y mucho más.

\section{Entender los parches}
\label{sec:mq:patch}

Dado que MQ no esconde su naturaleza parche-céntrica, es muy útil para
entender de qué se tratan los parches, y un poco acerca de las
herramientas que trabajan con ellos.

La orden de Unix tradicional \command{diff} compara dos ficheros, e
imprime una lista de diferencias de sus líneas.  La orden
\command{patch} entiende esas diferencias como \emph{modificaciones}
para construir un fichero.  Vea en la figura~\ref{ex:mq:diff} un
ejemplo sencillo de tales órdenes en acción.

\begin{figure}[ht]
  \interaction{mq.dodiff.diff}
  \caption{Uso sencillo de las órdenes \command{diff} y \command{patch}}
  \label{ex:mq:diff}
\end{figure}

El tipo de fichero que \command{diff} genera (y que \command{patch}
toma como entrada) se llama un ``parche'' o un ``diff''; no hay
diferencia entre un parche y un diff.  (Usaremos el término ``parche'',
dado que es el que más comunmente se usa.)

Un parche puede comenzar con un texto arbitrario; la orden \command{patch}
ignora este texto, pero MQ lo usa como el mensaje de consignación
cuando se crean conjuntos de cambios.  Para encontrar el inicio del
contenido de un parche, la orden \command{patch} busca la primera
línea que comience con la cadena ``\texttt{diff~-}''.

MQ trabaja con diffs \emph{unificados} (\command{patch} acepta varios
formatos de diff adicionales, pero MQ no).  Un diff unificado contiene
dos clases de encabezados.  El \emph{encabezado de fichero} describe
el fichero que se está modificando; contiene el nombre del fichero a
modificar.  Cuando \command{patch} ve un nuevo encabezado de fichero,
busca un fichero con ese nombre para modificarlo.

Después del encabezaado vienen varios \emph{trozos}.  Cada trozo
comienza con un encabezado; que identifica el rango de líneas del
fichero que el trozo debe modificar.  Después del encabezado, un trozo
comienza y termina con unas pocas líneas(usualmente tres) de texto del
fichero que no han sido modificadas; las cuales llamamos el
\emph{contexto} del trozo.  Si solamente hay una pequeña cantidad de
contexto entre trozos sucesivos, \command{diff} no imprime un nuevo
encabezado para el trozo, continua integrando los trozos, con unas
líneas de contexto entre las modificaciones.

Cada línea de contexto comienza con un caracter de espacio.  En el
trozo, si una línea comienza con ``\texttt{-}'' significa ``elimine
esta línea'', si la línea comienza con un ``\texttt{+}'' significa
``inserte esta línea''.  Por ejemplo, una línea que se modifica se
representa con una línea eliminada y una línea insertada.

Retomaremos aspectos más sutiles acerca de parches posteriormente(en
la sección~\ref{sec:mq:adv-patch}), pero en el momento usted ya
debería tener suficiente información para usar MQ.

\section{Comenzar a usar Colas de Mercurial}
\label{sec:mq:start}

Dado que MQ está implementado como una extensión, debe habilitarla
explícitamente antes de comenzar a usarla.  (No necesita descargar
nada; MQ viene con la distribución estándar de Mercurial.)  Para
habilitar MQ, edite su fichero \tildefile{.hgrc}, y añada las líneas
de la figura~\ref{ex:mq:config}.

\begin{figure}[ht]
  \begin{codesample4}
    [extensions]
    hgext.mq =
  \end{codesample4}
  \label{ex:mq:config}
  \caption{Líneas a añadir en \tildefile{.hgrc} para habilitar la extensión MQ}
\end{figure}

Cuando la extensión esté habilitada, aparecerán varios comandos.  Para
verificar que la extensión está trabajando, puede usar \hgcmd{help}
para ver si la orden \hgxcmd{mq}{qinit} está disponible; vea un
ejemplo en la figura~\ref{ex:mq:enabled}.

\begin{figure}[ht]
  \interaction{mq.qinit-help.help}
  \caption{Cómo verificar que MQ está habilitado}
  \label{ex:mq:enabled}
\end{figure}

Puede usar MQ en \emph{cualquier} repositorio de Mercurial, y sus
comandos solamente operarán con tal repositorio.  Para comenzar, basta
con preparar el repositorio con la orden \hgxcmd{mq}{qinit}(ver la
figura~\ref{ex:mq:qinit}).  Esta orden crea un directorio vacío
llamado \sdirname{.hg/patches}, donde MQ mantendrá sus metadatos. Como
otras ordenes de Mercurial, la orden \hgxcmd{mq}{qinit} no imprime
nada cuando es exitosa.

\begin{figure}[ht]
  \interaction{mq.tutorial.qinit}
  \caption{Preparar un repositorio para usar MQ}
  \label{ex:mq:qinit}
\end{figure}

\begin{figure}[ht]
  \interaction{mq.tutorial.qnew}
  \caption{Crear un nuevo parche}
  \label{ex:mq:qnew}
\end{figure}

\subsection{Crear un nuevo parche}

Para comenzar a trabajar en un nuevo parche use la orden
\hgxcmd{mq}{qnew}. Esta orden recibe un argumento, el nombre del
parche a crear.  MQ lo usará como el nombre del fichero en el
directorio \sdirname{.hg/patches}, como puede apreciarlo en la
figura~\ref{ex:mq:qnew}.

También hay otros dos nuevos ficheros en el directorio
\sdirname{.hg/patches}:  \sfilename{series} y \sfilename{status}.  El
fichero \sfilename{series} lista todos los parches de los cuales MQ
tiene noticia para este repositorio, con un parche por línea.
Mercurial usa el fichero \sfilename{status} para mantener registros
interns; da seguimiento a todos los parches que MQ ha \emph{aplicado}
en el repositorio.

\begin{note}
  En ciertas ocasiones usted querrá editar el fichero
  \sfilename{series} a mano; por ejemplo, cambiar el orden en que se
  aplican ciertos parches.  A pesar de esto, es una mala idea editar
  manualmente  el fichero \sfilename{status}, dado que es fácil
  desorientar a MQ acerca de lo que está pasando.
\end{note}

Una vez que haya creado un nuevo parche, puede editar los ficheros en
el directorio de trabajo, como lo haría usualmente.  Toda las órdenes
que de a Mercurial, tales como \hgcmd{diff} y \hgcmd{annotate},
trabajarán de la misma forma como lo han hecho antes.

\subsection{Refrescar un parche}

Cuando usted llega a un punto en el cual desea guardar su trabajo, use
la orden \hgxcmd{mq}{qrefresh}(figura~\ref{ex:mq:qnew}) para
actualizar el parche en el cual está trabajando.  Esta orden almacena
los cambios que haya hecho al directorio actual de trabajo en su
parche, y almacena el conjunto de cambios correspondiente que contiene
los cambios.

\begin{figure}[ht]
  \interaction{mq.tutorial.qrefresh}
  \caption{Refrescar un parche}
  \label{ex:mq:qrefresh}
\end{figure}

Puede ejecutar la orden \hgxcmd{mq}{qrefresh} tan seguido como quiera,
y es una buena forma de ``colocar marcas'' a su trabajo.  Refresque su
parche en momentos oportunos; intente un experimento; si el
experimento no funciona, Use \hgcmd{revert} sobre sus modificaciones
para volver al refresco anterior.

\begin{figure}[ht]
  \interaction{mq.tutorial.qrefresh2}
  \caption{Refrescar un parche muchas veces para acumular cambios}
  \label{ex:mq:qrefresh2}
\end{figure}

\subsection{Aplicar un parche tras otro y dar seguimiento}

Cuando haya terminado de trabajar en un parche, o necesite trabajar en
otro, puede usar la orden \hgxcmd{mq}{qnew} para crear un nuevo
parche.  Mercurial aplicará este parche sobre su parche anterior.
Para un ejemplo, ver la figura~\ref{ex:mq:qnew2}.  Note que el parche
contiene los cambios en nuestro parche anterior como parte de su
contexto( lo verá más claramente en la salida de \hgcmd{annotate}).

\begin{figure}[ht]
  \interaction{mq.tutorial.qnew2}
  \caption{Aplicar un parche después del primero}
  \label{ex:mq:qnew2}
\end{figure}

Hasta ahora, con excepción de \hgxcmd{mq}{qnew} y
\hgxcmd{mq}{qrefresh}, hemos sido cuidadosos para aplicar únicamente
órdenes usuaales de Mercurial.  De todas maneras, MQ ofrece muchos
comandos que son más sencillos de usar cuando esté pensando acerca de
parches, como se puede ver en la figura~\ref{ex:mq:qseries}:

\begin{itemize}
\item La orden \hgxcmd{mq}{qseries} lista cada parche del cual MQ
  tiene noticia en este repositorio, desde el más antiguo hasta el más
  nuevo(El último \emph{creado}).
\item La orden \hgxcmd{mq}{qapplied} lista cada parche que MQ haya
  \emph{aplicado} en este repositorio, de nuevo, desde el más antiguo
  hasta el más nuevo (El aplicado más recientemente).
\end{itemize}

\begin{figure}[ht]
  \interaction{mq.tutorial.qseries}
  \caption{Entender la pila de parches con \hgxcmd{mq}{qseries} y
    \hgxcmd{mq}{qapplied}}
  \label{ex:mq:qseries}
\end{figure}

\subsection{Manipular la pila de parches}

La discusión previa indicó que debe haber una diferencia entre los
parches ``conocidos'' y ``aplicados'', y efectivamente la hay.  MQ
puede manejar un parche sin que este haya sido aplicado al
repositorio.

Un parche \emph{aplicado} tiene su correspondiente conjunto de cambios
en el repositorio, y los efectos del parche y el conjunto de cambios
son visibles en el directorio de trabajo.  Puede deshacer la
aplicación de un parche con la orden \hgxcmd{mq}{qpop}.  MQ 
\emph{sabe acerca de}, o maneja un parche sustraído, pero el parche ya
no tendrá un conjunto de cambios correspondientes en el repositorio, y
el directorio de trabajo no contendrá los cambios hechos por el
parche.  La figura~\ref{fig:mq:stack} ilustra la diferencia entre
parches aplicados y seguidos.

\begin{figure}[ht]
  \centering
  \grafix{mq-stack}
  \caption{Parches aplicados y no aplicados en la pila de parches de MQ}
  \label{fig:mq:stack}
\end{figure}

Puede reaplicar un parche no aplicado o sustraído con la orden
\hgxcmd{mq}{qpush}.  Esto crea un nuevo conjunto de cambios
correspondiente al parche, y los cambios del parche estarán presentes
de nuevo en el directorio de trabajo.  Vea ejemplos de
\hgxcmd{mq}{qpop} y \hgxcmd{mq}{qpush} en acción en la
figura~\ref{ex:mq:qpop}.  Vea que hemos sustraído uno o dos parches,
la salida de\hgxcmd{mq}{qseries} continúa igual, mientras que
\hgxcmd{mq}{qapplied} ha  cambiado.

\begin{figure}[ht]
  \interaction{mq.tutorial.qpop}
  \caption{Modificar la pila de parches aplicados}
  \label{ex:mq:qpop}
\end{figure}

\subsection{Introducir y sustraer muchos parches}

Mientras que \hgxcmd{mq}{qpush} y \hgxcmd{mq}{qpop} operan sobre un
único parche cada vez, puede introducir y sustraer varios parches de
una vez.  La opción \hgxopt{mq}{qpush}{-a} de \hgxcmd{mq}{qpush}
introduce todos los cambios que no hayan sido aplicados, mientras que
la opción \hgxopt{mq}{qpop}{-a} de \hgxcmd{mq}{qpop} sustrae todos los
cambios aplicados.  (Vea la sección~\ref{sec:mq:perf} más adelante
en la cual se explican otras formas de de introducir y sustraer varios
cambios.)

\begin{figure}[ht]
  \interaction{mq.tutorial.qpush-a}
  \caption{Pushing all unapplied patches}
  \label{ex:mq:qpush-a}
\end{figure}

\subsection{Medidas de seguridad y cómo saltarlas}

Muchas órdenes MQ revisan el directorio de trabajo antes de hacer
cualquier cosa, y fallan si encuentran alguna modificación.  Lo hacen
para garantizar que usted no pierda cambio alguno de los que haya
hecho, pero que no hayan sido incorporados en algún parche.  La
figura~\ref{ex:mq:add} ilusta esto; la orden \hgxcmd{mq}{qnew} no
creará un nuevo parche si hay cambios notorios, causados en este caso
por aplicado la orden \hgcmd{add} a \filename{file3}.

\begin{figure}[ht]
  \interaction{mq.tutorial.add}
  \caption{Crear un parche a la fuerza}
  \label{ex:mq:add}
\end{figure}

Las órdenes que revisan el directorio actual cuentan con una opción
``Se lo que estoy haciendo'', que siempre está nombrada como
\option{-f}.  El significado exacto de \option{-f} depende de la
orden.  Por ejemplo, \hgcmdargs{qnew}{\hgxopt{mq}{qnew}{-f}}
incorporarán cualquier cambio notorio en el nuevo parche que crea pero
\hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-f}} revertirá las modificaciones a
cualquier fichero que haya sido afectado por el parche que está siendo
sustraído. ¡Asegúrese de leer la documentación de la opción \option{-f}
de cada comando antes de usarla!

\subsection{Trabajar con varios parches a la vez}

La orden \hgxcmd{mq}{qrefresh} siempre refresca el \emph{último}
parche aplicado.  Esto significa que usted puede suspender su trabajo
en un parche (refrescándolo), sustraerlo o introducirlo para lograr
que otro parche esté de último y trabajar en \emph{ese} parche por un
rato.

A continuación un ejemplo que ilustra cómo puede usar esta habilidad.
Digamos que está desarrollando una nueva característica en dos
parches.  El primero es un cambio en la parte fundamental de su
programa, y el segundo--sobre el primero---cambia la interfaz de
usuario para usar el código que ha añadido a la parte fundamental.  Si
ve que hay un fallo en la parte fundamental mientras está trabajando
en el parche de UI\ndt{Interfaz de Usuario, User Interface en inglés}, es fácil arreglar la parte fundamental.
Simplemente use \hgxcmd{mq}{qrefresh} sobre el parche de la UI para
guardar los cambios de su trabajo en progreso, y use \hgxcmd{mq}{qpop}
para sacar sustraer el parche de la parte fundamental.  Arregla el
fallo sobre la parte fundamental, aplique \hgxcmd{mq}{qrefresh} sobre
el parche fundamental, y aplique \hgxcmd{mq}{qpush} sobre el parche de
UI para continuar donde había quedado.

\section{Más acerca de parches}
\label{sec:mq:adv-patch}

MQ usa la orden GNU \command{patch} para aplicar los parches, por lo
tanto es útil conocer ciertos detalles de cómo trabaja
\command{patch}, y también acerca de los parches.

\subsection{La cantidad de franjas}

Si ve el encabezado de un parche, notará que la ruta al archivo tiene
un componente adicional al principio, que no está presente en la
ruta. Esta es una traza de cómo generaba anteriormente los parches la
gente(algunos aún lo hacen, pero es raro con las herramientas de
control de revisiones del actuales).

Alicia desempaquetaría un comprimido, editaría sus archivos, y querría
crear un parche.  Por lo tanto ella renombraría su directorio de
trabajo, desempacaría el comprimido de nuevo(para lo cual necesitó el
renombramiento), y usaría las opciones \cmdopt{diff}{-r} y
\cmdopt{diff}{-N} de \command{diff} para generar recursivamente un
parche entre el directorio original y el modificado.  El resultado
sería que el nombre del directorio original estaría al principio de
toda ruta en cada encabezado de fichero, y el nombre del directorio
modificado estaría al frente de la porción derecha de la ruta del
archivo.

Como alguien que reciba un parche de Alicia en la red podría obtener
dos directorios, uno original y el otro modificado con exactamente los
mismos nombres, la orden \command{patch} tiene la opción
\cmdopt{patch}{-p} que indica la cantidad de componentes de la ruta
a eliminar cuando se vaya a aplicar el parche.  Este número se
llama la \emph{cantidad de eliminaciones}.

La opción con ``\texttt{-p1}'' significa ``elimine uno''.  Si
\command{patch} ve un nombre de fichero \filename{foo/bar/baz} en el
encabezado del fichero, eliminará \filename{foo} y tratará de parchar
un fichero llamado \filename{bar/baz}.  (Hablando estrictamente, la
cantidad de eliminaciones se refiere a la cantidad de \emph{separadores de
 ruta} (y los componentes que vayan con ellos) a eliminar.  Si el
contador es uno volverá \filename{foo/bar} en \filename{bar}, pero
\filename{/foo/bar} (note la barra extra) en \filename{foo/bar}.)

La cantidad a eliminar``estándar'' para parches es uno; casi todos los
parches contienen un componente inicial de la ruta que necesita ser
eliminado.  La orden \hgcmd{diff} de Mercurial genera nombres de ruta
de esta forma, y la orden \hgcmd{import} y MQ esperan parches que
tengan a uno como cuenta de eliminaciones.

Si recibe un parche de alguien de quien desea adicionar adicionar a su
cola de parches, y el parche necesita una cuenta de eliminación que no
sea uno, no podrá aplicar \hgxcmd{mq}{qimport} en primera medida,
porque \hgxcmd{mq}{qimport} no tiene todavía una opción \texttt{-p}
option (ver~\bug{311}).  Lo mejor que puede hacer es aplicar
\hgxcmd{mq}{qnew} por su cuenta, y después usar \cmdargs{patch}{-p\emph{N}}
para aplicar tal parche, seguido de \hgcmd{addremove} para tener en
cuenta cualquier fichero adicionado o eliminado por el parche, seguido
de \hgxcmd{mq}{qrefresh}.  Esta complejidad puede ser innecesaria;
consulte~\bug{311} para más información.

\subsection{Estrategias para aplicar parches}

Cuando \command{patch} aplica un trozo, intenta varias estrategias
sucesivas que decrecen en precisión para intentar aplicarlo.  Esta
técnica de pruebas y error aveces permite que un parche que fue
generado contra una versión anterior de un fichero, sea aplicada sobre
una versión más nueva del mismo.

Primero \command{patch} intenta una correspondencia perfecta donde los
números de línea, el contexto y el texto a modificar deben coincidir
perfectamente.  Si no lo logra, intenta encontrar una correspondencia
exacta del contexto, sin tener en cuenta el número de línea.  Si es
exitoso, imprime una línea indicando que el trozo fue aplicado, pero a
un \emph{corrimiento} del número de línea original.

Si falla la correspondencia por contexto, \command{patch} elimina la
primera y la última línea del contexto, e intenta una correspondencia
\emph{reducida} del contexto.  Si el trozo con contexto reducido es
exitoso, imprime un mensaje indicando que aplicó el trozo con un
\emph{factor difuso} (el número después del factor difuso indica
cuántas líneas de contexto \command{patch} tuvo que eliminar antes de
aplicar el parche).

Cuando ninguna de estas técnicas funciona, \command{patch} imprime un
mensaje indicando que el trozo en cuestión se desechó.  Almacena los
trozos desechados(también llamados ``descartados'') en un fichero con
el mismo nombre, y la extensión \sfilename{.rej} añadida.  También
almacena una copia igual al fichero original con la extensión
\sfilename{.orig}; la copia del fichero sin extensión contendrá
cualquier cambio hecho por los trozos que \emph{sí} se aplicaron sin
problema.  Si usted tiene un parche que modifica \filename{foo} con
seis trozos, y uno de ellos falla al aplicarse, tendrá : un fichero
original \filename{foo.orig}, un fichero \filename{foo.rej} que
contiene el trozo, y \filename{foo}, que contiene los cambios que se
aplicaron por los cinco trozos exitosos.

\subsection{Algunos detalles de la representación de parches}

Hay ciertas cosas útiles por saber acerca de cómo trabaja
\command{patch} con los ficheros:
\begin{itemize}
\item Debería ser obvio que \command{patch} no puede manipular
  ficheros binarios.
\item No se preocupa por el bit ejecutable; crea ficheros nuevos en
  modo lectura, pero no ejecutable.
\item \command{patch} intenta eliminar un fichero como una diferencia
  entre el fichero a eliminar y un fichero vacío.  Y por lo tanto su
  idea de ``Borré este fichero'' debería pensarse como ``toda línea de
  este fichero fue eliminada'' en un parche.
\item Trata la adición de un fichero como un diff entre un fichero
  vacío y el fichero a ser adicionado.  Por lo tanto en un parche su
  idea de ``Añadí este fichero'' se vería como ``toda línea de este
  fichero fue añadida''.
\item Trata el renombramiento de un fichero como la eliminación del
  nombre anterior y la adición del nuevo nombre.  Esto significa que
  los ficheros renombrados dejan un rastro grande en los parches.
  (Tenga en cuenta que Mercurial no trata de inferir cuando los
  archivos han sido renombrados o copiados en un parche en este
  momento.)
\item \command{patch} no puede representar ficheros vacíos, por lo
  tanto no puede usar un parche para representar la noción ``Añadí
  este fichero vacío al árbol''.
\end{itemize}
\subsection{Cuidado con los difusos}

While applying a hunk at an offset, or with a fuzz factor, will often
be completely successful, these inexact techniques naturally leave
open the possibility of corrupting the patched file.  The most common
cases typically involve applying a patch twice, or at an incorrect
location in the file.  If \command{patch} or \hgxcmd{mq}{qpush} ever
mentions an offset or fuzz factor, you should make sure that the
modified files are correct afterwards.  

It's often a good idea to refresh a patch that has applied with an
offset or fuzz factor; refreshing the patch generates new context
information that will make it apply cleanly.  I say ``often,'' not
``always,'' because sometimes refreshing a patch will make it fail to
apply against a different revision of the underlying files.  In some
cases, such as when you're maintaining a patch that must sit on top of
multiple versions of a source tree, it's acceptable to have a patch
apply with some fuzz, provided you've verified the results of the
patching process in such cases.

\subsection{Handling rejection}

If \hgxcmd{mq}{qpush} fails to apply a patch, it will print an error
message and exit.  If it has left \sfilename{.rej} files behind, it is
usually best to fix up the rejected hunks before you push more patches
or do any further work.

If your patch \emph{used to} apply cleanly, and no longer does because
you've changed the underlying code that your patches are based on,
Mercurial Queues can help; see section~\ref{sec:mq:merge} for details.

Unfortunately, there aren't any great techniques for dealing with
rejected hunks.  Most often, you'll need to view the \sfilename{.rej}
file and edit the target file, applying the rejected hunks by hand.

If you're feeling adventurous, Neil Brown, a Linux kernel hacker,
wrote a tool called \command{wiggle}~\cite{web:wiggle}, which is more
vigorous than \command{patch} in its attempts to make a patch apply.

Another Linux kernel hacker, Chris Mason (the author of Mercurial
Queues), wrote a similar tool called
\command{mpatch}~\cite{web:mpatch}, which takes a simple approach to
automating the application of hunks rejected by \command{patch}.  The
\command{mpatch} command can help with four common reasons that a hunk
may be rejected:

\begin{itemize}
\item The context in the middle of a hunk has changed.
\item A hunk is missing some context at the beginning or end.
\item A large hunk might apply better---either entirely or in
  part---if it was broken up into smaller hunks.
\item A hunk removes lines with slightly different content than those
  currently present in the file.
\end{itemize}

If you use \command{wiggle} or \command{mpatch}, you should be doubly
careful to check your results when you're done.  In fact,
\command{mpatch} enforces this method of double-checking the tool's
output, by automatically dropping you into a merge program when it has
done its job, so that you can verify its work and finish off any
remaining merges.

\section{Getting the best performance out of MQ}
\label{sec:mq:perf}

MQ is very efficient at handling a large number of patches.  I ran
some performance experiments in mid-2006 for a talk that I gave at the
2006 EuroPython conference~\cite{web:europython}.  I used as my data
set the Linux 2.6.17-mm1 patch series, which consists of 1,738
patches.  I applied these on top of a Linux kernel repository
containing all 27,472 revisions between Linux 2.6.12-rc2 and Linux
2.6.17.

On my old, slow laptop, I was able to
\hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-a}} all 1,738 patches in 3.5 minutes,
and \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}} them all in 30 seconds.  (On a
newer laptop, the time to push all patches dropped to two minutes.)  I
could \hgxcmd{mq}{qrefresh} one of the biggest patches (which made 22,779
lines of changes to 287 files) in 6.6 seconds.

Clearly, MQ is well suited to working in large trees, but there are a
few tricks you can use to get the best performance of it.

First of all, try to ``batch'' operations together.  Every time you
run \hgxcmd{mq}{qpush} or \hgxcmd{mq}{qpop}, these commands scan the working
directory once to make sure you haven't made some changes and then
forgotten to run \hgxcmd{mq}{qrefresh}.  On a small tree, the time that
this scan takes is unnoticeable.  However, on a medium-sized tree
(containing tens of thousands of files), it can take a second or more.

The \hgxcmd{mq}{qpush} and \hgxcmd{mq}{qpop} commands allow you to push and pop
multiple patches at a time.  You can identify the ``destination
patch'' that you want to end up at.  When you \hgxcmd{mq}{qpush} with a
destination specified, it will push patches until that patch is at the
top of the applied stack.  When you \hgxcmd{mq}{qpop} to a destination, MQ
will pop patches until the destination patch is at the top.

You can identify a destination patch using either the name of the
patch, or by number.  If you use numeric addressing, patches are
counted from zero; this means that the first patch is zero, the second
is one, and so on.

\section{Updating your patches when the underlying code changes}
\label{sec:mq:merge}

It's common to have a stack of patches on top of an underlying
repository that you don't modify directly.  If you're working on
changes to third-party code, or on a feature that is taking longer to
develop than the rate of change of the code beneath, you will often
need to sync up with the underlying code, and fix up any hunks in your
patches that no longer apply.  This is called \emph{rebasing} your
patch series.

The simplest way to do this is to \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}}
your patches, then \hgcmd{pull} changes into the underlying
repository, and finally \hgcmdargs{qpush}{\hgxopt{mq}{qpop}{-a}} your
patches again.  MQ will stop pushing any time it runs across a patch
that fails to apply during conflicts, allowing you to fix your
conflicts, \hgxcmd{mq}{qrefresh} the affected patch, and continue pushing
until you have fixed your entire stack.

This approach is easy to use and works well if you don't expect
changes to the underlying code to affect how well your patches apply.
If your patch stack touches code that is modified frequently or
invasively in the underlying repository, however, fixing up rejected
hunks by hand quickly becomes tiresome.

It's possible to partially automate the rebasing process.  If your
patches apply cleanly against some revision of the underlying repo, MQ
can use this information to help you to resolve conflicts between your
patches and a different revision.

The process is a little involved.
\begin{enumerate}
\item To begin, \hgcmdargs{qpush}{-a} all of your patches on top of
  the revision where you know that they apply cleanly.
\item Save a backup copy of your patch directory using
  \hgcmdargs{qsave}{\hgxopt{mq}{qsave}{-e} \hgxopt{mq}{qsave}{-c}}.  This prints
  the name of the directory that it has saved the patches in.  It will
  save the patches to a directory called
  \sdirname{.hg/patches.\emph{N}}, where \texttt{\emph{N}} is a small
  integer.  It also commits a ``save changeset'' on top of your
  applied patches; this is for internal book-keeping, and records the
  states of the \sfilename{series} and \sfilename{status} files.
\item Use \hgcmd{pull} to bring new changes into the underlying
  repository.  (Don't run \hgcmdargs{pull}{-u}; see below for why.)
\item Update to the new tip revision, using
  \hgcmdargs{update}{\hgopt{update}{-C}} to override the patches you
  have pushed.
\item Merge all patches using \hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-m}
    \hgxopt{mq}{qpush}{-a}}.  The \hgxopt{mq}{qpush}{-m} option to \hgxcmd{mq}{qpush}
  tells MQ to perform a three-way merge if the patch fails to apply.
\end{enumerate}

During the \hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-m}}, each patch in the
\sfilename{series} file is applied normally.  If a patch applies with
fuzz or rejects, MQ looks at the queue you \hgxcmd{mq}{qsave}d, and
performs a three-way merge with the corresponding changeset.  This
merge uses Mercurial's normal merge machinery, so it may pop up a GUI
merge tool to help you to resolve problems.

When you finish resolving the effects of a patch, MQ refreshes your
patch based on the result of the merge.

At the end of this process, your repository will have one extra head
from the old patch queue, and a copy of the old patch queue will be in
\sdirname{.hg/patches.\emph{N}}. You can remove the extra head using
\hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a} \hgxopt{mq}{qpop}{-n} patches.\emph{N}}
or \hgcmd{strip}.  You can delete \sdirname{.hg/patches.\emph{N}} once
you are sure that you no longer need it as a backup.

\section{Identifying patches}

MQ commands that work with patches let you refer to a patch either by
using its name or by a number.  By name is obvious enough; pass the
name \filename{foo.patch} to \hgxcmd{mq}{qpush}, for example, and it will
push patches until \filename{foo.patch} is applied.  

As a shortcut, you can refer to a patch using both a name and a
numeric offset; \texttt{foo.patch-2} means ``two patches before
\texttt{foo.patch}'', while \texttt{bar.patch+4} means ``four patches
after \texttt{bar.patch}''.

Referring to a patch by index isn't much different.  The first patch
printed in the output of \hgxcmd{mq}{qseries} is patch zero (yes, it's one
of those start-at-zero counting systems); the second is patch one; and
so on.

MQ also makes it easy to work with patches when you are using normal
Mercurial commands.  Every command that accepts a changeset ID will
also accept the name of an applied patch.  MQ augments the tags
normally in the repository with an eponymous one for each applied
patch.  In addition, the special tags \index{tags!special tag
  names!\texttt{qbase}}\texttt{qbase} and \index{tags!special tag
  names!\texttt{qtip}}\texttt{qtip} identify the ``bottom-most'' and
topmost applied patches, respectively.

These additions to Mercurial's normal tagging capabilities make
dealing with patches even more of a breeze.
\begin{itemize}
\item Want to patchbomb a mailing list with your latest series of
  changes?
  \begin{codesample4}
    hg email qbase:qtip
  \end{codesample4}
  (Don't know what ``patchbombing'' is?  See
  section~\ref{sec:hgext:patchbomb}.)
\item Need to see all of the patches since \texttt{foo.patch} that
  have touched files in a subdirectory of your tree?
  \begin{codesample4}
    hg log -r foo.patch:qtip \emph{subdir}
  \end{codesample4}
\end{itemize}

Because MQ makes the names of patches available to the rest of
Mercurial through its normal internal tag machinery, you don't need to
type in the entire name of a patch when you want to identify it by
name.

\begin{figure}[ht]
  \interaction{mq.id.output}
  \caption{Using MQ's tag features to work with patches}
  \label{ex:mq:id}
\end{figure}

Another nice consequence of representing patch names as tags is that
when you run the \hgcmd{log} command, it will display a patch's name
as a tag, simply as part of its normal output.  This makes it easy to
visually distinguish applied patches from underlying ``normal''
revisions.  Figure~\ref{ex:mq:id} shows a few normal Mercurial
commands in use with applied patches.

\section{Useful things to know about}

There are a number of aspects of MQ usage that don't fit tidily into
sections of their own, but that are good to know.  Here they are, in
one place.

\begin{itemize}
\item Normally, when you \hgxcmd{mq}{qpop} a patch and \hgxcmd{mq}{qpush} it
  again, the changeset that represents the patch after the pop/push
  will have a \emph{different identity} than the changeset that
  represented the hash beforehand.  See
  section~\ref{sec:mqref:cmd:qpush} for information as to why this is.
\item It's not a good idea to \hgcmd{merge} changes from another
  branch with a patch changeset, at least if you want to maintain the
  ``patchiness'' of that changeset and changesets below it on the
  patch stack.  If you try to do this, it will appear to succeed, but
  MQ will become confused.
\end{itemize}

\section{Managing patches in a repository}
\label{sec:mq:repo}

Because MQ's \sdirname{.hg/patches} directory resides outside a
Mercurial repository's working directory, the ``underlying'' Mercurial
repository knows nothing about the management or presence of patches.

This presents the interesting possibility of managing the contents of
the patch directory as a Mercurial repository in its own right.  This
can be a useful way to work.  For example, you can work on a patch for
a while, \hgxcmd{mq}{qrefresh} it, then \hgcmd{commit} the current state of
the patch.  This lets you ``roll back'' to that version of the patch
later on.

You can then share different versions of the same patch stack among
multiple underlying repositories.  I use this when I am developing a
Linux kernel feature.  I have a pristine copy of my kernel sources for
each of several CPU architectures, and a cloned repository under each
that contains the patches I am working on.  When I want to test a
change on a different architecture, I push my current patches to the
patch repository associated with that kernel tree, pop and push all of
my patches, and build and test that kernel.

Managing patches in a repository makes it possible for multiple
developers to work on the same patch series without colliding with
each other, all on top of an underlying source base that they may or
may not control.

\subsection{MQ support for patch repositories}

MQ helps you to work with the \sdirname{.hg/patches} directory as a
repository; when you prepare a repository for working with patches
using \hgxcmd{mq}{qinit}, you can pass the \hgxopt{mq}{qinit}{-c} option to
create the \sdirname{.hg/patches} directory as a Mercurial repository.

\begin{note}
  If you forget to use the \hgxopt{mq}{qinit}{-c} option, you can simply go
  into the \sdirname{.hg/patches} directory at any time and run
  \hgcmd{init}.  Don't forget to add an entry for the
  \sfilename{status} file to the \sfilename{.hgignore} file, though

  (\hgcmdargs{qinit}{\hgxopt{mq}{qinit}{-c}} does this for you
  automatically); you \emph{really} don't want to manage the
  \sfilename{status} file.
\end{note}

As a convenience, if MQ notices that the \dirname{.hg/patches}
directory is a repository, it will automatically \hgcmd{add} every
patch that you create and import.

MQ provides a shortcut command, \hgxcmd{mq}{qcommit}, that runs
\hgcmd{commit} in the \sdirname{.hg/patches} directory.  This saves
some bothersome typing.

Finally, as a convenience to manage the patch directory, you can
define the alias \command{mq} on Unix systems. For example, on Linux
systems using the \command{bash} shell, you can include the following
snippet in your \tildefile{.bashrc}.

\begin{codesample2}
  alias mq=`hg -R \$(hg root)/.hg/patches'
\end{codesample2}

You can then issue commands of the form \cmdargs{mq}{pull} from
the main repository.

\subsection{A few things to watch out for}

MQ's support for working with a repository full of patches is limited
in a few small respects.

MQ cannot automatically detect changes that you make to the patch
directory.  If you \hgcmd{pull}, manually edit, or \hgcmd{update}
changes to patches or the \sfilename{series} file, you will have to
\hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}} and then
\hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-a}} in the underlying repository to
see those changes show up there.  If you forget to do this, you can
confuse MQ's idea of which patches are applied.

\section{Third party tools for working with patches}
\label{sec:mq:tools}

Once you've been working with patches for a while, you'll find
yourself hungry for tools that will help you to understand and
manipulate the patches you're dealing with.

The \command{diffstat} command~\cite{web:diffstat} generates a
histogram of the modifications made to each file in a patch.  It
provides a good way to ``get a sense of'' a patch---which files it
affects, and how much change it introduces to each file and as a
whole.  (I find that it's a good idea to use \command{diffstat}'s
\cmdopt{diffstat}{-p} option as a matter of course, as otherwise it
will try to do clever things with prefixes of file names that
inevitably confuse at least me.)

\begin{figure}[ht]
  \interaction{mq.tools.tools}
  \caption{The \command{diffstat}, \command{filterdiff}, and \command{lsdiff} commands}
  \label{ex:mq:tools}
\end{figure}

The \package{patchutils} package~\cite{web:patchutils} is invaluable.
It provides a set of small utilities that follow the ``Unix
philosophy;'' each does one useful thing with a patch.  The
\package{patchutils} command I use most is \command{filterdiff}, which
extracts subsets from a patch file.  For example, given a patch that
modifies hundreds of files across dozens of directories, a single
invocation of \command{filterdiff} can generate a smaller patch that
only touches files whose names match a particular glob pattern.  See
section~\ref{mq-collab:tips:interdiff} for another example.

\section{Good ways to work with patches}

Whether you are working on a patch series to submit to a free software
or open source project, or a series that you intend to treat as a
sequence of regular changesets when you're done, you can use some
simple techniques to keep your work well organised.

Give your patches descriptive names.  A good name for a patch might be
\filename{rework-device-alloc.patch}, because it will immediately give
you a hint what the purpose of the patch is.  Long names shouldn't be
a problem; you won't be typing the names often, but you \emph{will} be
running commands like \hgxcmd{mq}{qapplied} and \hgxcmd{mq}{qtop} over and over.
Good naming becomes especially important when you have a number of
patches to work with, or if you are juggling a number of different
tasks and your patches only get a fraction of your attention.

Be aware of what patch you're working on.  Use the \hgxcmd{mq}{qtop}
command and skim over the text of your patches frequently---for
example, using \hgcmdargs{tip}{\hgopt{tip}{-p}})---to be sure of where
you stand.  I have several times worked on and \hgxcmd{mq}{qrefresh}ed a
patch other than the one I intended, and it's often tricky to migrate
changes into the right patch after making them in the wrong one.

For this reason, it is very much worth investing a little time to
learn how to use some of the third-party tools I described in
section~\ref{sec:mq:tools}, particularly \command{diffstat} and
\command{filterdiff}.  The former will give you a quick idea of what
changes your patch is making, while the latter makes it easy to splice
hunks selectively out of one patch and into another.

\section{MQ cookbook}

\subsection{Manage ``trivial'' patches}

Because the overhead of dropping files into a new Mercurial repository
is so low, it makes a lot of sense to manage patches this way even if
you simply want to make a few changes to a source tarball that you
downloaded.

Begin by downloading and unpacking the source tarball,
and turning it into a Mercurial repository.
\interaction{mq.tarball.download}

Continue by creating a patch stack and making your changes.
\interaction{mq.tarball.qinit}

Let's say a few weeks or months pass, and your package author releases
a new version.  First, bring their changes into the repository.
\interaction{mq.tarball.newsource}
The pipeline starting with \hgcmd{locate} above deletes all files in
the working directory, so that \hgcmd{commit}'s
\hgopt{commit}{--addremove} option can actually tell which files have
really been removed in the newer version of the source.

Finally, you can apply your patches on top of the new tree.
\interaction{mq.tarball.repush}

\subsection{Combining entire patches}
\label{sec:mq:combine}

MQ provides a command, \hgxcmd{mq}{qfold} that lets you combine entire
patches.  This ``folds'' the patches you name, in the order you name
them, into the topmost applied patch, and concatenates their
descriptions onto the end of its description.  The patches that you
fold must be unapplied before you fold them.

The order in which you fold patches matters.  If your topmost applied
patch is \texttt{foo}, and you \hgxcmd{mq}{qfold} \texttt{bar} and
\texttt{quux} into it, you will end up with a patch that has the same
effect as if you applied first \texttt{foo}, then \texttt{bar},
followed by \texttt{quux}.

\subsection{Merging part of one patch into another}

Merging \emph{part} of one patch into another is more difficult than
combining entire patches.

If you want to move changes to entire files, you can use
\command{filterdiff}'s \cmdopt{filterdiff}{-i} and
\cmdopt{filterdiff}{-x} options to choose the modifications to snip
out of one patch, concatenating its output onto the end of the patch
you want to merge into.  You usually won't need to modify the patch
you've merged the changes from.  Instead, MQ will report some rejected
hunks when you \hgxcmd{mq}{qpush} it (from the hunks you moved into the
other patch), and you can simply \hgxcmd{mq}{qrefresh} the patch to drop
the duplicate hunks.

If you have a patch that has multiple hunks modifying a file, and you
only want to move a few of those hunks, the job becomes more messy,
but you can still partly automate it.  Use \cmdargs{lsdiff}{-nvv} to
print some metadata about the patch.
\interaction{mq.tools.lsdiff}

This command prints three different kinds of number:
\begin{itemize}
\item (in the first column) a \emph{file number} to identify each file
  modified in the patch;
\item (on the next line, indented) the line number within a modified
  file where a hunk starts; and
\item (on the same line) a \emph{hunk number} to identify that hunk.
\end{itemize}

You'll have to use some visual inspection, and reading of the patch,
to identify the file and hunk numbers you'll want, but you can then
pass them to to \command{filterdiff}'s \cmdopt{filterdiff}{--files}
and \cmdopt{filterdiff}{--hunks} options, to select exactly the file
and hunk you want to extract.

Once you have this hunk, you can concatenate it onto the end of your
destination patch and continue with the remainder of
section~\ref{sec:mq:combine}.

\section{Differences between quilt and MQ}

If you are already familiar with quilt, MQ provides a similar command
set.  There are a few differences in the way that it works.

You will already have noticed that most quilt commands have MQ
counterparts that simply begin with a ``\texttt{q}''.  The exceptions
are quilt's \texttt{add} and \texttt{remove} commands, the
counterparts for which are the normal Mercurial \hgcmd{add} and
\hgcmd{remove} commands.  There is no MQ equivalent of the quilt
\texttt{edit} command.

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "00book"
%%% End: