Primeros pasos con Mercurial

Debería haber escrito este post hace algún tiempo pero ya se sabe como somos la gente importante que no tenemos tiempo a nada (modo ironic off). De todas formas nunca es tarde así que allá vamos, a adentrarnos en el maravilloso y fascinante mundo de Mercurial (hg para los amigos).

A estas alturas todos sabréis que Mercurial es una herramienta de sistema de control de versiones multiplataforma para desarrolladores de software implementado en Python (wikipedia dixit). Lo que igual se hace menos familiar es la facilidad con la que podemos crear un repositorio en 3 simples pasos: [@MORE@]

Creando un repositorio

  • 1.-\"hg init\" para agregar control de versiones a la carpeta en la que estemos situados.
  • 2.-\"hg addremove\" para detectar todos los archivos nuevos y eliminados y agregar todo el contenido de la carpeta al repositorio, si queremos hacerlo poco a poco (directorio a directorio o archivo a archivo) podemos utilizar \"hg add directorio|archivo\".
  • 3.-\"hg commit\" para guardar los cambios actuales en el repositorio, seguro que os suena la frase \"hacer un commit\" ;).
Con esto tenemos lo básico, una carpeta de la que queramos hacer repositorio hg tan solo necesita esos 3 pasos. Además podemos adornarnos un poco:
  • \"hg serve\" arranca un servidor web ligero en http://localhost:8000/ donde podrás explorar el repositorio, ver las versiones antiguas del código… Si queremos lanzarlo en otro puerto \"hg serve -p 8001\".
  • \"rm -rf .hg\" dejar de usar control de versiones en esa carpeta, así de simple :P.

Sistema distribuido

El proceso de commit cambia un poco en concepto con respecto a otros sistemas de versiones centralizados como Subversion. Mercurial, al ser distribuido, tiene un repositorio propio en cada clonación de código. A ver si doy explicado esto porque tiene su miga.

Supongamos un repositorio remoto al que hacemos un \"hg clone\" para empezar a trabajar en local, en nuestra máquina. Desde ese mismo momento obtendremos -además de la clonación del código- el propio repositorio Mercurial en local de forma que los commits que hagamos se quedarán en nuestro repositorio hasta que hagamos un \"push\" al servidor:
  • \"hg push\" propaga los cambios locales al servidor remoto del repositorio.
  • \"hg update\" (ejecutado en el servidor remoto del repositorio) actualiza los cambios pendientes del anterior push.
Llegados a este punto ya tenemos el nuevo código en el repositorio servidor, de forma que si el propio repositorio es el virtualhost en producción los cambios serán inmediatamente efectivos. Si por el contrario producción es -a su vez- un clone del repositorio servidor faltaría este último paso:
  • \"hg pull\" para propagar los cambios que se hayan commiteado al servidor remoto en local.
  • \"hg update\" actualiza los cambios pendientes del anterior \"pull\".

Esquema

En resumen, tal y como he planteado la organización en cada proyecto tendremos un mínimo de tres repositorios: local_devel ? repositorio_servidor ? producción (obviamente si hay varios desarrolladores también habrá más repositorios locales o de desarrollo):
  • local_devel: Primero haremos un hg clone para obtener código y repo de repositorio_servidor, trabajamos en local haciendo nuestros commits y cuando tengamos lista una feature haremos un hg push a repositorio_servidor. Nunca olvidarse de hacer hg pull para actualizar los cambios de los demás antes de ponerse a trabajar (lo que en Subversion sería un update).
  • repositorio_servidor: Donde creamos el repositorio en un principio (hg init, adremove, y el primer commit), una vez creado se nutre del hg push de todos los desarrolladores que están trabajando en su local_devel y debería hacerse un hg update por cada hg push.
  • producción: Se supone que este repositorio debe ser el más estable así que solo admitirá operaciones hg pull seguidas de hg update cuando estemos seguros que los cambios del repositorio_servidor son estables y funcionales.

Notas

Nota: Los binarios que estén en producción y no agreguemos al repositorio no se borran/sobreescriben al hacer un pull, así que lo suyo sería agregar al repositorio -hablando de proyectos existentes- solo el código fuente, nada de binarios ni archivos que luego no se puedan sobreescribir en un pull. En otras palabras, se solucionan todos los problemas de sobreescritura -overwrite- que teníamos con Subversion, rsync y su --exclude.

Nota2: Veo que ha quedado un post demasiado técnico (palabras que no todo el mundo entiende) e igual algo criptográfico en cuanto al esquema (imagino que lo suyo hubiera sido hacer un gráfico), seguro que me he centrado en un caso bastante particular, pido perdón de antemano. Cualquier comentario, sugerencia o aclaración es bienvenida.
code

About the author

Óscar
has doubledaddy super powers, father of Hugo and Nico, husband of Marta, *nix user, Djangonaut and open source passionate.
  • Te recomendari que pruebes Git :-D
  • No te ha quedado tan raro... en realidad es muy parecido a GIT. Es decir... me he puesto con GIT para cosas locales + GitHub para lo que sea público, y la verdad es que me gusta. En realidad no hay mucha diferencia con bazaar después de todo, y tampoco hay tanta con mercurial por lo que veo. Lo del hg serve puede ser una ventaja, claro (dependiendo de lo rico que sea ese interfaz web, claro :P). Buen artículo en definitiva.
  • Coincido con reidrac en que es muy buen articulo :) y en la semejanza que exite en los sistema de control de versiones distribuidos.Con los centralizados teniamos CVS y luego se mejoro al darse el salto Subversion pero ahora con los distribuidos tenemos git, bazaar, mercurial... (¿me dejo alguno?) que hacen practicamente lo mismo. ¿Teneis idea de como esta la \"cuota de mercado\" de este tipo de software?
  • Por lo que he leído y lo que comentáis parece sencilla una migración entre un sistema de control de versiones distribuido y otro. Algún día me tocará probar GIT o Bazaar, github tiene muy buena pinta. En cuanto a la \"cuota de mercado\" no tengo ni idea, pero me da que GIT se lleva la palma -al menos- en cuanto a desarrolladores de Ruby y Ruby On Rails.
  • Bazaar pega fuerte por el soporte de Canonical (y launchpad.net; claro), pero GIT se lleva casi todos los proyectos grandes (el kernel de Linux -claro-, Gnome, Perl, Qt, RoR, xorg, wine, ... y alguno más que me dejo). Al final, como resulta fácil \"reciclarse\" de uno a otro, tampoco tiene mucha imporancia mientras se use uno (¡y se use bien! :D).
  • reidrac: sí, pero radare usa Mercurial xDD
  • Hola, una consulta, en el caso que tengamos un proyecto "base" que usamos para otros proyectos, ¿como podría hacer que cuando modifico algo en el proyecto "base", se actualice automáticamente todos los otros proyectos que utilizan el proyecto "base?
  • @Arturo: Imagino que configurando un "hook" de forma que cuando haces commit al proyecto "base" actualice el resto de los que tiran de él. Pégale un vistazo a esta url: http://mercurial.selenic.com/w...
blog comments powered by Disqus