Mercurial Queues: una aplicación simple

Hace un tiempo comencé a leer un poco sobre esta extensión de Mercurial: Mercurial Queues (Mq). ¿Para qué sirve? Bueno, imagínense que tienen una instalación de WordPress con ciertas modificaciones que le han hecho. Supongan que la versión del CMS que están usando es la 2.6.5. Quieren actualizar a la 2.7 pero sin perder los cambios, y que la migración sea sencilla. Bueno, Mq les permite mantener estos cambios personales como parches, que pueden aplicar, modificar, quitar, reordenar… De esta forma, con una serie de pasos, pueden actualizar fácilmente el código “de fondo” (o sea, de WordPress 2.6.5 a la 2.7) y reaplicar esos parches sobre esta nueva base. En este post pueden ver el ejemplo desarrollado.


De todas formas, parece que ese no es el uso principal. Piensen que están colaborando con algún proyecto, donde utilizan Mercurial (o cualquier DCVS). Están trabajando en una nueva funcionalidad. Sabemos que los commits son inmutables. No sería conveniente que hagan commits en su repositorio local y luego intenten enviar todos esos cambios (que tendrán varios merges de por medio quizá) para la revisión, porque la dificulta. Lo conveniente sería (según explican al introducirnos en Mq) enviar parches con el trabajo finalizado. De esta forma podríamos ir manteniendo distintos parches de acuerdo a nuestro trabajo e ir actualizándolos a medida que avancemos. Como Mercurial Queues integra los parches a todo el sistema, los mismos son tratados como changesets, por lo tanto podemos pensar en los mismos como commits mutables: terminamos con nuestro trabajo y actualizamos el commit. Al día siguiente nos damos cuenta de que había un error y lo volvemos a actualizar con el nuevo trabajo. Incluso, como dije, podemos descartarlos, reordenarlos, etc. Y a medida que el trabajo se hace más complejo, podemos tener distintos parches, cada uno con cambios relacionados.

Yo tengo hecho mi CV en LaTeX bajo Mercurial. Después de un tiempo manteniéndolo y actualizándolo, me encontré colocando notas en forma de TODO o FIXME para recordar actualizar ciertas cosas, o trabajos sobre el mismo a medio hacer. El problema es que cuando tengo que enviar una versión limpia de mi CV, debo compilar una versión “estable” quitando todas estas modificaciones no terminadas. Por lo tanto es ideal usar Mq en esta situación: mantengo estos “features” o recordatorios como parches o commits mutables. Cuando quiero agregar algún recordatorio o estoy trabajando en una ampliación o reestruración, trabajo sobre los parches y los voy actualizando. Cuando veo que ya están listos, los transformo en changeset normales (o sea, inmutables). Cuando quiero compilar una versión estable, quito todos los parches, quedando así una versión limpia lista para enviar.

Algunos comandos como para que se den una idea de cómo funciona:

$ hg qinit
$ hg qnew nueva.funcionalidad
# Ahora estoy trabajando en el parche "nueva.funcionalidad". Realizo cambios, agrego archivos con "hd add", etc... trabajo comúnmente como siempre.
$ hg qrefresh
# con este comando actualizo el parche en el que estoy trabajando. Todos los cambios realizados son guardados ahora en "nueva.funcionalidad".

Si quiero quitar todos los parches aplicados ejecuto:

$ hg qpop -a

Si quiero aplicar todos los parches:

$ hg qpush -a

Si quiero moverme a un parche específico:

$ hg qgoto nombre.parche

Uno de los inconvenientes que surgió después de haberme encontrado con esta fantástica herramienta, fue que quería subir estos parches al repositorio. De esta forma, podría acceder a ellos y modificarlos desde cualquier máquina. Sin embargo esto no es trivial. La solución pasa por armar otro repositorio en el servidor. Por lo tanto el directorio local .hg/patches que posee todos los parches, se transforma en otro repositorio Mercurial y lo tratamos como tal: de vez en cuando subimos al repo de parches nuestros cambios a los mismos. Esto puede parecer tedioso, pero Mercurial ofrece unas utilidades que facilitan las cosas.

Me parece que es una extensión muy útil. En lo personal no me fue fácil agarrarle la mano rápidamente. Aunque como todo, para dominarlo hay que ponerlo en práctica.