Está en la página 1de 204

Control Distribuido de Revisiones con Mercurial

Bryan OSullivan Copyright c 2006, 2007 Bryan OSullivan. Este material puede distribuirse unicamente bajo los t rminos y condiciones establecidos en la e versi n 1.0 de la Licencia de Publicaci n Abierta (OPL). Re rase por favor al ap ndice D para o o e e encontrar el texto de la licencia. Este libro fue preparado a partir de rev fc4daaad6415, fechado 2009-02-10 00:28 -0500, usando Mercurial rev Mercurial Distributed SCM (version 1.0.1) .

Indice general
Indice general Prefacio 0.1. Este libro es un trabajo en progreso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0.2. Acerca de los ejemplos en este libro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0.3. Colof neste libro es Libre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o 1. Introducci n o 1.1. Acerca del control de revisiones . . . . . . . . . . . . . 1.1.1. Por qu usar control de revisiones? . . . . . . . e 1.1.2. La cantidad de nombres del control de revisiones 1.2. Historia resumida del control de revisiones . . . . . . . . 1.3. Tendencias en el control de revisiones . . . . . . . . . . 1.4. Algunas ventajas del control distribuido de revisiones . . 1.4.1. Ventajas para proyectos de c digo abierto . . . . o 1.4.2. Ventajas para proyectos comerciales . . . . . . . 1.5. Por qu elegir Mercurial? . . . . . . . . . . . . . . . . e 1.6. Comparaci n de Mercurial con otras herramientas . . . . o 1.6.1. Subversion . . . . . . . . . . . . . . . . . . . . 1.6.2. Git . . . . . . . . . . . . . . . . . . . . . . . . 1.6.3. CVS . . . . . . . . . . . . . . . . . . . . . . . . 1.6.4. Herramientas comerciales . . . . . . . . . . . . 1.6.5. Elegir una herramienta de control de revisiones . 1.7. Migrar de otra herramienta hacia Mercurial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
I

2 2 2 2 3 3 3 4 4 5 5 6 7 7 8 8 8 9 9 10 10 11 11 11 11 12 12 12 12 13 13 14 14 15 16 17

2. Una gira de Mercurial: lo b sico a 2.1. Instalar Mercurial en su sistema . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.1. Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.2. Solaris . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.3. Mac OS X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.4. Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2. Arrancando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.1. Ayuda integrada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3. Trabajar con un repositorio . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3.1. Hacer una copia local de un repositorio . . . . . . . . . . . . . . . . . 2.3.2. Qu hay en un repositorio? . . . . . . . . . . . . . . . . . . . . . . . . e 2.4. Vistazo r pido al historial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a 2.4.1. Conjuntos de cambios, revisiones, y comunic ndose con otras personas a 2.4.2. Ver revisiones especcas . . . . . . . . . . . . . . . . . . . . . . . . 2.4.3. Informaci n m s detallada . . . . . . . . . . . . . . . . . . . . . . . . o a
I

2.5. Todo acerca de las opciones para comandos . . . 2.6. Hacer y repasar cambios . . . . . . . . . . . . . 2.7. Grabar cambios en un nuevo conjunto de cambios 2.7.1. Denir un nombre de usuario . . . . . . 2.7.2. Escribir un mensaje de consignaci n . . . o 2.7.3. Escribir un buen mensaje de consignaci n o 2.7.4. Cancelar una consignaci n . . . . . . . . o 2.7.5. Admirar nuestro trabajo . . . . . . . . . 2.8. Compartir cambios . . . . . . . . . . . . . . . . 2.8.1. Jalar cambios desde otro repositorio . . . 2.8.2. Actualizar el directorio de trabajo . . . . 2.8.3. Empujar cambios a otro repositorio . . . 2.8.4. Compartir cambios a trav s de una red . . e 3. Una gira de Mercurial: fusionar trabajo 3.1. Fusionar lneas de trabajo . . . . . . . . . . . . . 3.1.1. Conjuntos de cambios de frentes . . . . . 3.1.2. Hacer la fusi n . . . . . . . . . . . . . . o 3.1.3. Consignar los resultados de la fusi n . . . o 3.2. Fusionar cambios con conictos . . . . . . . . . 3.2.1. Usar una herramienta gr ca para fusi n a o 3.2.2. Un ejemplo real . . . . . . . . . . . . . . 3.3. Simplicar el ciclo jalar-fusionar-consignar . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

18 18 19 19 20 21 21 21 22 22 23 24 25 26 26 28 29 30 30 31 32 35 36 36 36 36 36 37 38 38 38 38 39 40 40 40 41 41 42 42 42 43 43 44 49 49 49 50 51

4. Tras bambalinas 4.1. Registro del historial de Mercurial . . . . . . . . . . . . 4.1.1. Seguir el historial de un unico chero . . . . . . 4.1.2. Administraci n de cheros monitoreados . . . . o 4.1.3. Registro de informaci n del conjunto de cambios o 4.1.4. Relaciones entre revisiones . . . . . . . . . . . . 4.2. Almacenamiento seguro y eciente . . . . . . . . . . . . 4.2.1. Almacenamiento eciente . . . . . . . . . . . . 4.2.2. Operaci n segura . . . . . . . . . . . . . . . . . o 4.2.3. Recuperaci n r pida de datos . . . . . . . . . . o a 4.2.4. Identicaci n e integridad fuerte . . . . . . . . . o 4.3. Historial de revisiones, ramas y fusiones . . . . . . . . . 4.4. El directorio de trabajo . . . . . . . . . . . . . . . . . . 4.4.1. Qu pasa en una consignaci n . . . . . . . . . . e o 4.4.2. Creaci n de un nuevo frente . . . . . . . . . . . o 4.4.3. Fusi n de frentes . . . . . . . . . . . . . . . . . o 4.5. Otras caractersticas de dise o interesantes . . . . . . . . n 4.5.1. Compresi n ingeniosa . . . . . . . . . . . . . . o 4.5.2. Reordenado de lectura/escritura y atomicidad . . 4.5.3. Acceso concurrente . . . . . . . . . . . . . . . . 4.5.4. Evitar movimientos de brazo . . . . . . . . . . . 4.5.5. Otros contenidos del estado de directorio . . . .

5. Mercurial da a da 5.1. C mo indicarle a Mercurial qu cheros seguir . . . . . . . . o e 5.1.1. Nombramiento explcito e implcito de cheros . . . . 5.1.2. Nota al margen: Mercurial trata cheros, no directorios 5.2. C mo dejar de hacer seguimiento a un chero . . . . . . . . . o
II

5.2.1. Al eliminar un chero no se afecta su historial . . . . . . . . . . . . . . . . . . . . . 5.2.2. Ficheros perdidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.3. Nota al margen: Por qu decirle explcitamente a Mercurial que elimine un chero? e 5.2.4. Atajo utilagregar y eliminar cheros en un solo paso . . . . . . . . . . . . . . . . 5.3. Copiar cheros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.1. Resultados de copiar un chero durante una fusi n . . . . . . . . . . . . . . . . . . o 5.3.2. Por qu los cambios se reejan en las copias? . . . . . . . . . . . . . . . . . . . . e 5.3.3. C mo hacer que los cambios no sigan a la copia? . . . . . . . . . . . . . . . . . . . o 5.3.4. Comportamiento de la orden hg copy . . . . . . . . . . . . . . . . . . . . . . . . 5.4. Renombrar cheros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.4.1. Renombrar cheros y fusionar cambios . . . . . . . . . . . . . . . . . . . . . . . . 5.4.2. Cambios de nombre divergentes y fusi n . . . . . . . . . . . . . . . . . . . . . . . o 5.4.3. Cambios de nombre convergentes y fusi n . . . . . . . . . . . . . . . . . . . . . . o 5.4.4. Otros casos lmite relacionados con renombramientos . . . . . . . . . . . . . . . . . 5.5. Recuperarse de equivocaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6. Colaborar con otros 6.1. La interfaz web de Mercurial . . . . . . . . . . . . . . . . . . . . . . . 6.2. Modelos de colaboraci n . . . . . . . . . . . . . . . . . . . . . . . . . o 6.2.1. Factores a tener en cuenta . . . . . . . . . . . . . . . . . . . . 6.2.2. Anarqua informal . . . . . . . . . . . . . . . . . . . . . . . . 6.2.3. Un repositorio central unico . . . . . . . . . . . . . . . . . . . 6.2.4. Trabajo con muchas ramas . . . . . . . . . . . . . . . . . . . . 6.2.5. Ramas de caractersticas . . . . . . . . . . . . . . . . . . . . . 6.2.6. El tren de publicaci n . . . . . . . . . . . . . . . . . . . . . . o 6.2.7. El modelo del kernel Linux . . . . . . . . . . . . . . . . . . . . 6.2.8. Solamente jalar frente a colaboraci n p blica . . . . . . . . . . o u 6.2.9. Cuando la colaboraci n encuentra la administraci n ramicada o o 6.3. Aspectos t cnicos de la colaboraci n . . . . . . . . . . . . . . . . . . . e o 6.4. Compartir informalmente con hg serve . . . . . . . . . . . . . . . . 6.4.1. Cuestiones adicionales para tener en cuenta . . . . . . . . . . . 6.5. Uso del protocolo Secure Shell (ssh) . . . . . . . . . . . . . . . . . . . 6.5.1. C mo leer y escribir URLs de ssh . . . . . . . . . . . . . . . . o 6.5.2. Encontrar un cliente ssh para su sistema . . . . . . . . . . . . . 6.5.3. Generar un par de llaves . . . . . . . . . . . . . . . . . . . . . 6.5.4. Uso de un agente de autenticaci n . . . . . . . . . . . . . . . . o 6.5.5. Congurar el lado del servidor apropiadamente . . . . . . . . . 6.5.6. Compresi n con ssh . . . . . . . . . . . . . . . . . . . . . . . o 6.6. Servir sobre HTTP usando CGI . . . . . . . . . . . . . . . . . . . . . . 6.6.1. Lista de chequeo de la conguraci n del servidor web . . . . . o 6.6.2. Conguraci n b sica de CGI . . . . . . . . . . . . . . . . . . . o a 6.6.3. Compartir varios repositorios con un gui n CGI . . . . . . . . . o 6.6.4. Descarga de cheros fuente . . . . . . . . . . . . . . . . . . . 6.6.5. Opciones de conguraci n en Web . . . . . . . . . . . . . . . . o 7. Nombres de cheros y asociaci n de patrones o 7.1. Nombrado de cheros simple . . . . . . . . . . . . . . . . . 7.2. Ejecuci n de comandos sin ning n nombre de chero . . . . o u 7.3. Reportar que est pasando . . . . . . . . . . . . . . . . . . a 7.4. Uso de patrones para identicar cheros . . . . . . . . . . . 7.4.1. Patrones glob estilo int rprete . . . . . . . . . . . . e 7.4.2. Asociaci n con patrones de expresiones regulares re o
III

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

51 51 52 52 52 53 54 54 54 55 56 56 57 57 58 59 59 59 60 60 60 61 63 63 63 64 64 65 65 65 65 66 66 67 67 67 69 69 69 70 72 73 73 75 75 75 77 77 77 78

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

7.5. Filtrado de cheros . . . . . . . . . . . . . . . . . . . . . 7.6. Ignorar cheros y directorios no deseados . . . . . . . . . 7.7. Sensibilidad a may sculas . . . . . . . . . . . . . . . . . u 7.7.1. Almacenamiento portable y seguro de repositorios 7.7.2. Detecci n de conictos de may sculas/min sculas o u u 7.7.3. Arreglar un conicto de may sculas/min sculas . u u

. . . . . .

. . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

79 79 79 80 80 80 81 81 83 84 84 84 84 85 86 88 90 90 91 91 91 91 92 92 93 93 94 95 95 96 96 98 101 102 102 102 103 106 107 107 107 107 107 108 109 109 110 110 110

8. Administraci n de versiones y desarrollo ramicado o 8.1. Dar un nombre persistente a una revisi n . . . . . . . . . . . . o 8.1.1. Manejo de conictos entre etiquetas durante una fusi n o 8.1.2. Etiquetas y clonado . . . . . . . . . . . . . . . . . . . 8.1.3. Cuando las etiquetas permanentes son demasiado . . . 8.2. El ujo de cambiosEl gran cuadro vs. el peque o . . . . . . n 8.3. Administrar ramas en repositorios estilo gran cuadro . . . . . 8.4. No repita trabajo: fusi n entre ramas . . . . . . . . . . . . . . o 8.5. Nombrar ramas dentro de un repositorio . . . . . . . . . . . . 8.6. Tratamiento de varias ramas nombradas en un repositorio . . . 8.7. Nombres de ramas y fusiones . . . . . . . . . . . . . . . . . . 8.8. Normalmente es util nombrar ramas . . . . . . . . . . . . . . 9. Encontrar y arreglar sus equivocaciones 9.1. Borrar el historial local . . . . . . . . . . . . . . . . . . 9.1.1. La consignaci n accidental . . . . . . . . . . . . o 9.1.2. Hacer rollback una transacci n . . . . . . . . . . o 9.1.3. Erroneamente jalado . . . . . . . . . . . . . . . 9.1.4. Despu s de publicar, un roll back es futil . . . . e 9.1.5. Solamente hay un roll back . . . . . . . . . . . . 9.2. Revertir un cambio equivocado . . . . . . . . . . . . . . 9.2.1. Errores al administrar cheros . . . . . . . . . . 9.3. Tratar cambios consignados . . . . . . . . . . . . . . . . 9.3.1. Retroceder un conjunto de cambios . . . . . . . 9.3.2. Retroceder el conjunto de cambios punta . . . . 9.3.3. Retroceso de un cambio que no es la punta . . . 9.3.4. M s control sobre el proceso de retroceso . . . . a 9.3.5. Por qu hg backout hace lo que hace . . . . . e 9.4. Cambios que nunca debieron ocurrir . . . . . . . . . . . 9.4.1. C mo protegerse de cambios que han escapado o 9.5. Al encuentro de la fuente de un fallo . . . . . . . . . . . 9.5.1. Uso de la orden hg bisect . . . . . . . . . . 9.5.2. Limpieza despu s de la b squeda . . . . . . . . e u 9.6. Consejos para encontrar fallos efectivamente . . . . . . . 9.6.1. Dar una entrada consistente . . . . . . . . . . . 9.6.2. Automatizar tanto como se pueda . . . . . . . . 9.6.3. Vericar los resultados . . . . . . . . . . . . . . 9.6.4. Tener en cuenta la interferencia entre fallos . . . 9.6.5. Acotar la b squeda perezosamente . . . . . . . . u . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

10. Manejo de eventos en repositorios mediante ganchos 10.1. Vistazo general de ganchos en Mercurial . . . . . . . . . . . . 10.2. Ganchos y seguridad . . . . . . . . . . . . . . . . . . . . . . 10.2.1. Los ganchos se ejecutan con sus privilegios de usuario 10.2.2. Los ganchos no se propagan . . . . . . . . . . . . . .
IV

10.2.3. Es posible hacer caso omiso de los ganchos . . . . . . . . . . . . . . . . . . . . . . . 10.2.4. Asegurarse de que ganchos crticos sean ejecutados . . . . . . . . . . . . . . . . . . . 10.3. Precauciones con ganchos pretxn en un repositorio de acceso compartido . . . . . . . . . . . 10.3.1. Ilustraci n del problema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o 10.4. Tutorial corto de uso de ganchos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.4.1. Llevar a cabo varias acciones por evento . . . . . . . . . . . . . . . . . . . . . . . . . 10.4.2. Controlar cu ndo puede llevarse a cabo una actividad . . . . . . . . . . . . . . . . . . a 10.5. Escribir sus propios ganchos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.5.1. Escoger c mo debe ejecutarse su gancho . . . . . . . . . . . . . . . . . . . . . . . . o 10.5.2. Par metros para ganchos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a 10.5.3. Valores de retorno de ganchos y control de actividades . . . . . . . . . . . . . . . . . 10.5.4. Escribir un gancho externo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.5.5. Indicar a Mercurial que use un gancho interno . . . . . . . . . . . . . . . . . . . . . . 10.5.6. Escribir un gancho interno . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.6. Ejemplos de ganchos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.6.1. Escribir mensajes de consignaci n signicativos . . . . . . . . . . . . . . . . . . . . o 10.6.2. Comprobar espacios en blanco nales . . . . . . . . . . . . . . . . . . . . . . . . . . 10.7. Ganchos adicionales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.7.1. aclcontrol de acceso a partes de un repositorio . . . . . . . . . . . . . . . . . . . . 10.7.2. bugzillaintegraci n con Bugzilla . . . . . . . . . . . . . . . . . . . . . . . . . . o 10.7.3. notifyenviar noticaciones de correo electr nico . . . . . . . . . . . . . . . . . . o 10.8. Informaci n para escritores de ganchos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o 10.8.1. Ejecuci n de ganchos internos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o 10.8.2. Ejecuci n de ganchos externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o 10.8.3. Averiguar de d nde vienen los conjuntos de cambios . . . . . . . . . . . . . . . . . . o 10.9. Referencia de ganchos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.9.1. changegroupluego de a adir conjuntos de cambios remotos . . . . . . . . . . . . . n 10.9.2. commitluego de la creaci n de un nuevo conjunto de cambios . . . . . . . . . . . . o 10.9.3. incomingluego de que un conjunto de cambios remoto es a adido . . . . . . . . . n 10.9.4. outgoingluego de la propagaci n de los conjuntos de cambios . . . . . . . . . . . o 10.9.5. prechangegroupantes de empezar la adici n de conjuntos de cambios remotos . . o 10.9.6. precommitantes de iniciar la consignaci n de un conjunto de cambios . . . . . . . o 10.9.7. preoutgoingantes de empezar la propagaci n de conjuntos de cambios . . . . . . o 10.9.8. pretagantes de etiquetar un conjunto de cambios . . . . . . . . . . . . . . . . . . 10.9.9. pretxnchangegroupantes de completar la adici n de conjuntos de cambios remotos o 10.9.10.pretxncommitantes de completar la consignaci n de un nuevo conjunto de cambios o 10.9.11.preupdateantes de actualizar o fusionar el directorio de trabajo . . . . . . . . . . . 10.9.12.tagluego de etiquetar un conjunto de cambios . . . . . . . . . . . . . . . . . . . . 10.9.13.updateluego de actualizar o fusionar el directorio de trabajo . . . . . . . . . . . . . 11. Personalizar los mensajes de Mercurial 11.1. Usar estilos que vienen con Mercurial . . . . 11.1.1. Especicar un estilo predeterminado . 11.2. Ordenes que soportan estilos y plantillas . . . 11.3. Cuestiones b sicas de plantillas . . . . . . . . a 11.4. Palabras claves m s comunes en las plantillas a 11.5. Secuencias de Control . . . . . . . . . . . . . 11.6. Uso de ltros con palabras claves . . . . . . . 11.6.1. Combinar ltros . . . . . . . . . . . 11.7. De plantillas a estilos . . . . . . . . . . . . . 11.7.1. Los cheros de estilo m s sencillos . a 11.7.2. Sintaxis de cheros de estilo . . . . . . . . . . . . . . . . . . . . . . . . . . .
V

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

110 111 111 112 112 112 113 113 113 114 114 114 115 115 115 115 116 117 117 119 122 124 124 124 125 125 125 126 126 126 127 127 127 128 128 128 129 129 129 130 130 131 131 131 132 133 134 135 135 137 137

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

11.8. Ejemplos de cheros de estilos . . . . . . . . . . . . . 11.8.1. Identicar equivocaciones en cheros de estilo 11.8.2. Identicar de forma unica un repositorio . . . . 11.8.3. Mostrando salida parecida a Subversion . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

137 137 138 139 140 140 140 141 141 141 142 143 143 144 145 145 146 146 147 148 148 149 150 150 151 151 152 152 153 153 154 155 155 155 156 156 158 158 159 160 160 160 161 161 162 163 163 164 164 165

12. Administraci n de cambios con Colas de Mercurial o 12.1. El problema de la administraci n de parches . . . . . . . . . . . . . . . o 12.2. La prehistoria de las Colas de Mercurial . . . . . . . . . . . . . . . . . 12.2.1. Trabajar parches con quilt . . . . . . . . . . . . . . . . . . . . 12.2.2. Pasar de trabajo con parches con Quilt hacia Colas de Mercurial 12.3. La gran ventaja de MQ . . . . . . . . . . . . . . . . . . . . . . . . . . 12.4. Entender los parches . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.5. Comenzar a usar Colas de Mercurial . . . . . . . . . . . . . . . . . . . 12.5.1. Crear un nuevo parche . . . . . . . . . . . . . . . . . . . . . . 12.5.2. Refrescar un parche . . . . . . . . . . . . . . . . . . . . . . . . 12.5.3. Aplicar un parche tras otro y dar seguimiento . . . . . . . . . . 12.5.4. Manipular la pila de parches . . . . . . . . . . . . . . . . . . . 12.5.5. Introducir y sustraer muchos parches . . . . . . . . . . . . . . 12.5.6. Medidas de seguridad y c mo saltarlas . . . . . . . . . . . . . o 12.5.7. Trabajar con varios parches a la vez . . . . . . . . . . . . . . . 12.6. M s acerca de parches . . . . . . . . . . . . . . . . . . . . . . . . . . a 12.6.1. La cantidad de franjas . . . . . . . . . . . . . . . . . . . . . . 12.6.2. Estrategias para aplicar parches . . . . . . . . . . . . . . . . . 12.6.3. Algunos detalles de la representaci n de parches . . . . . . . . o 12.6.4. Cuidado con los difusos . . . . . . . . . . . . . . . . . . . . . 12.6.5. Manejo de descartes . . . . . . . . . . . . . . . . . . . . . . . 12.7. maximizar el rendimiento de MQ . . . . . . . . . . . . . . . . . . . . . 12.8. Actualiar los parches cuando el c digo cambia . . . . . . . . . . . . . . o 12.9. Identicar parches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.10.Otra informaci n util . . . . . . . . . . . . . . . . . . . . . . . . . . . o 12.11.Administrar parches en un repositorio . . . . . . . . . . . . . . . . . . 12.11.1.Soporte de MQ para repositorios de parches . . . . . . . . . . . 12.11.2.Detalles a tener en cuenta . . . . . . . . . . . . . . . . . . . . 12.12.Otras herramientas para trabajar con parches . . . . . . . . . . . . . . . 12.13.Buenas pr cticas de trabajo con parches . . . . . . . . . . . . . . . . . a 12.14.Recetas de MQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.14.1.Administrar parches triviales . . . . . . . . . . . . . . . . . . 12.14.2.Combinar parches completos . . . . . . . . . . . . . . . . . . . 12.14.3.Fusionar una porci n de un parche dentro de otro . . . . . . . . o 12.15.Diferencias entre quilt y MQ . . . . . . . . . . . . . . . . . . . . . . . 13. Usos avanzados de las Colas de Mercurial 13.1. El problema de m ltiples objetivos . . . . . . . . . . . . . . . . . . . u 13.1.1. Aproximaciones tentadoras que no funcionan adecuadamente 13.2. Aplicar parches condicionalmente mediante guardias . . . . . . . . . 13.3. Controlar los guardias de un parche . . . . . . . . . . . . . . . . . . 13.4. Selecccionar los guardias a usar . . . . . . . . . . . . . . . . . . . . 13.5. Reglas de MQ para aplicar parches . . . . . . . . . . . . . . . . . . . 13.6. Podar el entorno de trabajo . . . . . . . . . . . . . . . . . . . . . . . 13.7. Dividir el chero series . . . . . . . . . . . . . . . . . . . . . . . . 13.8. Mantener la serie de parches . . . . . . . . . . . . . . . . . . . . . . 13.8.1. El arte de escribir parches de backport . . . . . . . . . . . . .
VI

. . . . . . . . . .

13.9. Consejos utiles para hacer desarrollo con MQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 13.9.1. Organizar parches en directorios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 13.9.2. Ver el historial de un parche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 14. Anadir funcionalidad con extensiones 14.1. Mejorar el desempe o con la extensi n inotify . . . . . . . . . n o 14.2. Soporte exible de diff con la extensi n extdiff . . . . . . . . . o 14.2.1. Denici n de alias de comandos . . . . . . . . . . . . . . o 14.3. Uso de la extensi n transplant para seleccionar . . . . . . . . . o 14.4. Enviar cambios va correo electr nico con la extensi n patchbomb o o 14.4.1. Cambiar el comportamiento de las bombas de parches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 168 170 172 172 172 173 175 175 175 175 177 177 179 179 179 179 179 179 179 180 180 180 180 180 181 181 181 182 182 182 182 182 183 183 183 183 183 183

A. Referencia de Ordenes A.1. hg addA ade cheros en la pr xima consignaci n . . . . . . . . . . . . . n o o A.2. hg diffimprime los cambios en el historial o el directorio actual . . . . . A.2.1. Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.3. hg versionimprime la informaci n de versi n y derechos de reproducci n o o o A.3.1. Consejos y trucos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B. Referencia de las Colas de Mercurial B.1. Referencia de ordenes MQ . . . . . . . . . . . . . . . . . . . . . . . . . . . B.1.1. hg qappliedimprimir los parches aplicados . . . . . . . . . . . B.1.2. hg qcommitconsignar cambios en la cola del repositorio . . . . B.1.3. hg qdeleteeliminar un parche del chero series . . . . . . . B.1.4. hg qdiffimprimir la diferencia del ultimo parche aplicado . . . B.1.5. hg qfoldfusionar (integrar) varios parches en uno solo . . . . B.1.6. hg qheaderdesplegar el encabezado/descripci n de un parche . o B.1.7. hg qimportimportar el parche de un tercero en la cola . . . . . B.1.8. hg qinitpreparar un repositorio para trabajar con MQ . . . . . B.1.9. hg qnewcrear un parche nuevo . . . . . . . . . . . . . . . . . . B.1.10. hg qnextimprimir el nombre del pr ximo parche . . . . . . . . o B.1.11. hg qpopsustraer parches de la pila . . . . . . . . . . . . . . . . B.1.12. hg qprevimprimir el nombre del parche anterior . . . . . . . . B.1.13. hg qpushintroducir parches a la pila . . . . . . . . . . . . . . . B.1.14. hg qrefreshactualiza el ultimo parche aplicado . . . . . . . . . B.1.15. hg qrenamerenombrar un parche . . . . . . . . . . . . . . . . . B.1.16. hg qrestorerestaurar el estado almacenado de la cola . . . . . B.1.17. hg qsavealmacena el estado actual de la cola . . . . . . . . . . B.1.18. hg qseriesimprime la serie completa de parches . . . . . . . . B.1.19. hg qtopimprime el nombre del parche actual . . . . . . . . . . B.1.20. hg qunappliedimprimir los parches que a n no se han aplicado u B.1.21. hg stripremover una revisi n y sus descendientes . . . . . . . o B.2. Referencia de cheros de MQ . . . . . . . . . . . . . . . . . . . . . . . . . B.2.1. El chero series . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.2.2. El chero status . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

C. Instalar Mercurial desde las fuentes 184 C.1. En un sistema tipo Unix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 C.2. En Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184

VII

D. Licencia de Publicaci n Abierta o D.1. Requerimientos en versiones modicadas y no modicadas D.2. Derechos de reproducci n . . . . . . . . . . . . . . . . . o D.3. Alcance de la licencia . . . . . . . . . . . . . . . . . . . . D.4. Requerimientos sobre trabajos modicados . . . . . . . . D.5. Recomendaciones de buenas pr cticas . . . . . . . . . . . a D.6. Opciones de licencia . . . . . . . . . . . . . . . . . . . . Bibliografa Indice alfab tico e

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

185 185 185 185 186 186 186 188 188

VIII

Indice de guras
2.1. Historial gr co del repositorio hello . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a 3.1. 3.2. 3.3. 3.4. 3.5. 4.1. 4.2. 4.3. 4.4. 4.5. 4.6. 4.7. 4.8. 4.9. Historial reciente divergente de los repositorios my-hello y my-new-hello . . . Contenidos del repositorio despu s de jalar my-hello a my-new-hello . . . . . e Directorio de trabajo y repositorio durante la fusi n, y consignaci n consecuente o o Cambios con conictos a un documento . . . . . . . . . . . . . . . . . . . . . . Usando kdiff3 para fusionar versiones de un chero . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 27 28 29 31 32 37 37 39 45 46 46 47 47 48 50 63

Relaci n entre cheros en el directorio de trabajo y cheros de registro en el repositorio o Relaciones entre metadatos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Instant nea de un revlog, con deltas incrementales . . . . . . . . . . . . . . . . . . . . a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . El directorio de trabajo puede tener dos padres . . . . . . . . . . . . . . . . . . . . . . El directorio de trabajo obtiene nuevos padres luego de una consignaci n . . . . . . . o El directorio de trabajo, actualizado a un conjunto de cambios anterior . . . . . . . . . Despu s de una consignaci n hecha mientras se usaba un conjunto de cambios anterior e o Fusi n de dos frentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o

5.1. Simular un directorio vaco con un chero oculto . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.1. Ramas de Caractersticas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.1. 9.2. 9.3. 9.4. Retroceso de un cambio con la orden hg backout . . . . . . . . . . . . . . . . . . . . . Retroceso automatizado de un cambio a algo que no es la punta con la orden hg backout Retroceso usando la orden hg backout . . . . . . . . . . . . . . . . . . . . . . . . . . . Fusi n manual de un retroceso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. 97 . 98 . 100 . 101 . . . . . . 112 113 114 116 116 117

10.1. Un gancho simple que se ejecuta al hacer la consignaci n de un conjunto de cambios o 10.2. Denici n de un segundo gancho commit . . . . . . . . . . . . . . . . . . . . . . . o 10.3. Uso del gancho pretxncommit para controlar consignaciones . . . . . . . . . . . . 10.4. Un gancho que prohbe mensajes de consignaci n demasiado cortos . . . . . . . . . o 10.5. Un gancho simple que revisa si hay espacios en blanco nales . . . . . . . . . . . . 10.6. Un mejor gancho para espacios en blanco nales . . . . . . . . . . . . . . . . . . .

11.1. Template keywords in use . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 11.2. Filtros de plantilla en acci n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 o 12.1. Uso sencillo de las ordenes diff y patch . . . . . . . . . 12.2. Lneas a a adir en /.hgrc para habilitar la extensi n MQ n o 12.3. C mo vericar que MQ est habilitado . . . . . . . . . . . o a 12.4. Preparar un repositorio para usar MQ . . . . . . . . . . . 12.5. Crear un nuevo parche . . . . . . . . . . . . . . . . . . .
IX

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

142 143 143 144 144

12.6. Refrescar un parche . . . . . . . . . . . . . . . . . . . . . . . . . 12.7. Refrescar un parche muchas veces para acumular cambios . . . . 12.8. Aplicar un parche despu s del primero . . . . . . . . . . . . . . . e 12.9. Entender la pila de parches con hg qseries y hg qapplied 12.10.Parches aplicados y no aplicados en la pila de parches de MQ . . . 12.11.Modicar la pila de parches aplicados . . . . . . . . . . . . . . . 12.12.Pushing all unapplied patches . . . . . . . . . . . . . . . . . . . . 12.13.Crear un parche a la fuerza . . . . . . . . . . . . . . . . . . . . . 12.14.Uso de las caractersticas de etiquetamiento al trabajar con MQ . . 12.15.Las ordenes diffstat, filterdiff, y lsdiff . . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

145 146 147 148 148 149 149 150 154 156

Prefacio
El control distribuido de revisiones es un territorio relativamente nuevo, y ha crecido hasta ahora gracias a a la voluntad que tiene la gente de salir y explorar territorios desconocidos. Estoy escribiendo este libro acerca de control de revisiones distribuido porque creo que es un tema importante que merece una gua de campo. Escog escribir acerca de Mercurial porque es la herramienta m s f cil para explorar a a el terreno, y sin embargo escala a las demandas de retadores ambientes reales donde muchas otras herramientas de control de revisiones fallan.

0.1.

Este libro es un trabajo en progreso

Estoy liberando este libro mientras lo sigo escribiendo, con la esperanza de que pueda ser util a otros. Tambi n e espero que los lectores contribuir n como consideren adecuado. a

0.2.

Acerca de los ejemplos en este libro

Este libro toma un enfoque inusual hacia las muestras de c digo. Cada ejemplo est en directocada uno es o a realmente el resultado de un script de shell que ejecuta los comandos de Mercurial que usted ve. Cada vez que una copia del libro es construida desde su c digo fuente, todos los scripts de ejemplo son ejecutados autom ticamente, y o a sus resultados actuales son comparados contra los resultados esperados. La ventaja de este enfoque es que los ejemplos siempre son precisos; ellos describen exactamente el comportamiento de la versi n de Mercurial que es mencionada en la portada del libro. Si yo actualizo la versi n de Mercurial o o que estoy documentando, y la salida de alg n comando cambia, la construcci n falla. u o Hay una peque a desventaja de este enfoque, que las fechas y horas que usted ver en los ejemplos tienden a n a estar aplastadas juntas de una forma que no sera posible si los mismos comandos fueran escritos por un humano. Donde un humano puede emitir no m s de un comando cada pocos segundos, con cualquier marca de tiempo resultante a correspondientemente separada, mis scripts automatizados de ejemplos ejecutan muchos comandos en un segundo. Como un ejemplo de esto, varios commits consecutivos en un ejemplo pueden aparecer como habiendo ocurrido durante el mismo segundo. Usted puede ver esto en el ejemplo bisect en la secci n 9.5, por ejemplo. o As que cuando usted lea los ejemplos, no le d mucha importancia a las fechas o horas que vea en las salidas de e los comandos. Pero tenga conanza en que el comportamiento que est viendo es consistente y reproducible. a

0.3.

Colof neste libro es Libre o

Este libro est licenciado bajo la Licencia de Publicaci n Abierta, y es producido en su totalidad usando herramiena o A tas de Software Libre. Es compuesto con LTEX; las ilustraciones son dibujadas y generadas con Inkscape. El c digo fuente completo para este libro es publicado como un repositorio Mercurial, en http://hg.serpentine. o com/mercurial/book.

Captulo 1

Introducci n o
1.1. Acerca del control de revisiones

El control de revisiones es el proceso de administrar diferentes versiones de una pieza de informaci n. En su forma o m s simple es algo que la mayora de gente hace a mano: cada vez que usted modica un chero, lo graba con un a nuevo nombre que contiene un n mero, cada uno mayor que el anterior. u Administrar manualmente muchas versiones de incluso s lo un chero es una tarea propensa a errores, a pesar de o que hace bastante tiempo hay herramientas que ayudan en este proceso. Las primeras herramientas para automatizar el control de revisiones fueron pensadas para que un usuario administrara un solo chero. En las d cadas pasadas, el e alcance de las herramientas de control de revisiones ha ido aumentando considerablemente; ahora manejan muchos cheros y facilitan el trabajo en conjunto de varias personas. Las mejores herramientas de control de revisiones de la actualidad no tienen problema con miles de personas trabajando en proyectos que consisten de cientos de miles de cheros.

1.1.1.

Por qu usar control de revisiones? e

Hay muchas razones por las cuales usted o su equipo deseara usar una herramienta autom tica de control de a revisiones para un proyecto. Llevar registro del historial y la evoluci n de su proyecto, para evitar hacer la tarea manualmente. Por cada o cambio, tendr una bit cora de qui n lo hizo; por qu se hizo; cu ndo se hizo; y de qu se trataba el cambio. a a e e a e Cuando trabaja con m s personas, los programas de control de revisiones facilitan la colaboraci n. Por ejemplo, a o cuando varias personas hacen cambios potencialmente incompatibles de forma casi simult nea, el programa le a ayudar a identicar y resolver tales conictos. a Puede ayudarle a recuperarse de equivocaciones. Si aplica un cambio que posteriormente se evidencia como un error, puede revertirlo a una versi n previa a uno o muchos cheros. De hecho, una herramienta realmente o buena, incluso puede ayudarle efectivamente a darse cuenta exactamente cu ndo se introdujo el error (para m s a a detalles ver la secci n 9.5). o Le ayudar a trabajar simult neamente, y a manejar las diferencias entre m ltiples versiones de su proyecto. a a u La mayora de estas razones son igualmente v lidas por lo menos en teora as est trabajando en un proyecto a e solo usted, o con mucha gente. Algo fundamental acerca de lo pr ctico de un sistema de control de revisiones en estas dos escalas (un hacker a solitario y un equipo gigantesco) es c mo se comparan los benecios con los costos. Una herramienta de control o de revisiones que sea difcil de entender o usar impondr un costo alto. a

Un proyecto de quinientas personas es muy propenso a colapsar solamente con su peso inmediatamente sin una herramienta y un proceso de control de versiones. En este caso, el costo de usar control de revisiones ni siquiera se tiene en cuenta, puesto que sin el, el fracaso est casi garantizado. a Por otra parte, un arreglo r pido de una sola persona, excluira la necesidad de usar una herramienta de control a de revisiones, porque casi seguramente, el costo de usar una estara cerca del costo del proyecto. No es as? Mercurial soporta ambas escalas de de desarrollo de manera unica. Puede aprender lo b sico en pocos minutos, y a dado su bajo sobrecosto, puede aplicar el control de revisiones al proyecto m s peque o con facilidad. Su simplicidad a n signica que no tendr que preocuparse por conceptos obtusos o secuencias de ordenes compitiendo por espacio a mental con lo que sea que realmente est tratando de hacer. Al mismo tiempo, Mercurial tiene alto desempe o y su e n naturaleza peer-to-peer le permite escalar indoloramente para manejar grandes proyectos. Ninguna herramienta de control de revisiones puede salvar un proyecto mal administrado, pero la elecci n de o herramientas puede hacer una gran diferencia en la uidez con la cual usted puede trabajar en un proyecto.

1.1.2.

La cantidad de nombres del control de revisiones

El control de revisiones es un campo amplio, tan amplio que no hay un acr nimo o nombre unico. A continuaci n o o presentamos un listado de nombres comunes y acr nimos que se podran encontrar: o Control de revisiones (RCS) Manejo de Conguraciones de Programas (SCM), o administrac n de conguraciones o Administraci n de c digo fuente o o Control de C digo Fuente, o Control de Fuentes o Control de Versiones (VCS) Algunas personas aducen que estos t rminos tienen signicados diversos, pero en la pr ctica se sobreponen tanto que e a no hay una forma acordada o incluso adecuada de separarlos.

1.2.

Historia resumida del control de revisiones

La herramienta de control de revisiones m s antigua conocida es SCCS (Sistema de Control de C digo), escrito a o por Marc Rochkind en Bell Labs, a comienzos de los setentas (1970s). SCCS operaba sobre cheros individuales, y requera que cada persona que trabajara en el proyecto tuviera acceso a un espacio compartido en un solo sistema. Solamente una persona poda modicar un chero en un momento dado; el arbitramiento del acceso a los cheros se haca con candados. Era com n que la gente pusiera los candados a los cheros, y que posteriormente olvidara u quitarlos, impidiendo que otro pudiera modicar los cheros en cuesti n sin la intervenci n del administrador. o o Walter Tichy desarroll una alternativa gratuita a SCCS a comienzos de los ochentas (1980s); llam a su programa o o RCS (Sistema de Control de Revisiones). Al igual que SCCS, RCS requera que los desarrolladores trabajaran en un unico espacio compartido y colocaran candados a los cheros para evitar que varias personas los modicaran simult neamente. a Despu s en los ochenta, Dick Grune us RCS como un bloque de construcci n para un conjunto de guiones de e o o lnea de comando, que inicialmente llam cmt, pero que renombr a CVS (Sistema Concurrente de Versiones). La o o gran innovaci n de CVS era que permita a los desarrolladores trabajar simult neamente de una forma m s o menos o a a independiente en sus propios espacios de trabajo. Los espacios de trabajo personales impedan que los desarrolladores se pisaran las mangueras todo el tiempo, situaci n com n con SCCS y RCS. Cada desarrollador tena una copia de o u todos los cheros del proyecto y poda modicar sus copias independientemente, Tenan que fusionar sus ediciones antes de consignar los cambios al repositorio central. Brian Berliner tom los scripts originales de Grune y los reescribi en C, publicando en 1989 el c digo sobre el o o o cual se ha desarrollado la versi n moderna de CVS. CVS adquiri posteriormente la habilidad de operar sobre una o o conexi n de red, dot ndolo de una arquitectura, cliente/servidor. La arquitectura de CVS es centralizada; el historial o a del proyecto est unicamente en el repositorio central. Los espacios de trabajo de los clientes contienen unicamente a 4

copias recientes de las versiones de los cheros, y pocos metadatos para indicar d nde est el servidor. CVS ha tenido o a un exito enorme; Es probablemente el sistema de control de revisiones m s extendido del planeta. a A comienzos de los noventa (1990s), Sun MicroSystems desarrollo un temprano sistema distribuido de control de revisiones llamado TeamWare. Un espacio de trabajo TeamWare contiene una copia completa del historial del proyecto. TeamWare no tiene la noci n de repositorio central. (CVS se basaba en RCS para el almacenamiento de su o historial; TeamWare usaba SCCS.) A medida que avanzaba la decada de los noventa, se empez a evidenciar los problemas de CVS. Almacena o cambios simult neos a muchos cheros de forma individual, en lugar de agruparlos como una operaci n unica y a o at mica l gicamente. No maneja bien su jerarqua de cheros; es f cil desordenar un repositorio al renombrar cheros o o a y directorios. Peor a n, su c digo fuente es difcil de leer y mantener, lo que hizo que su umbral de dolor para u o arreglar sus problemas arquitecturales fuera algo prohibitivo. En 2001, Jim Blandy y Karl Fogel, dos desarrolladores que haban trabajado en CVS, comenzaron un proyecto para reemplazarlo con una herramienta con mejor arquitectura y c digo m s limpio. El resultado, Subversion, no o a se separ del modelo centralizado cliente/servidor de CVS, pero a adi consignaciones at micas de varios cheros, o n o o mejor manejo de espacios de nombres , y otras caractersticas que lo hacen mejor que CVS. Desde su versi n inicial, o ha ido creciendo en popularidad r pidamente. a M s o menos en forma simult nea Graydon Hoare comenz a trabajar en un ambicioso sistema distribuido de a a o control de versiones que llam Monotone. Mientras que Monotone se enfocaba a evitar algunas fallas de dise o de o n CVS con una arquitectura peer-to-peer, fue mucho m s all de las herramientas anteriores (y posteriores) de control de a a revisiones en varios aspectos innovadores. Usa hashes criptogr cos como identicadores, y tiene una noci n integral a o de conanza para c digo de diversas fuentes. o Mercurial naci en el 2005. Algunos de sus aspectos de de dise o fueron inuenciados por Monotone, pero Mero n curial se enfoca en la facilidad de uso, gran rendimiento y escalabilidad para proyectos muy grandes.

1.3.

Tendencias en el control de revisiones

Ha habido una tendencia inconfundible en el desarrollo y uso de las herramientas de control de revisiones en las cuatro d cadas pasadas, mientras la gente se ha hecho familiar con las capacidades de sus herramientas y se ha visto e restringida por sus limitaciones. La primera generaci n comenz administrando cheros individuales en computadores por persona. A pesar de que o o tales herramientas representaron un avance importante frente al control de revisiones manual, su modelo de candados y la dependencia a un s lo computador los limit a equipos de trabajo peque os y acoplados. o o n La segunda generaci n dej atr s esas limitaciones movi ndose a arquitecturas centradas en redes, y administrando o o a e proyectos completos a la vez. A medida que los proyectos crecan, nacieron nuevos problemas. Con la necesidad de comunicaci n frecuente con los servidores, escalar estas m quinas se convirti en un problema en proyectos realmente o a o grandes. Las redes con poca estabilidad podran impedir que usuarios remotos se conectaran al servidor. A medida que los proyectos de c digo abierto comenzaron a ofrecer acceso de s lo lectura de forma an nima a cualquiera, la gente o o o sin permiso para consignar vio que no podan usar tales herramientas para interactuar en un proyecto de forma natural, puesto que no podan guardar sus cambios. La generaci n actual de herramientas de control de revisiones es peer-to-peer por naturaleza. Todos estos sistemas o han eliminado la dependencia de un unico servidor central, y han permitido que la gente distribuya sus datos de control de revisiones donde realmente se necesita. La colaboraci n a trav s de Internet ha cambiado las limitantes tecnol gicas o e o por la cuesti n de elecci n y consenso. Las herramientas modernas pueden operar sin conexi n indenidamente y o o o aut nomamente, necesitando una conexi n de red solamente para sincronizar los cambios con otro repositorio. o o

1.4.

Algunas ventajas del control distribuido de revisiones

A pesar de que las herramientas para el control distribuido de revisiones lleva varios a os siendo tan robustas y n usables como la generaci n previa de sus contrapartes, algunas personas que usan las herramientas m s antiguas no o a se han percatado de sus ventajas. Hay gran cantidad de situaciones en las cuales las herramientas distribuidas brillan frente a las centralizadas. 5

Para un desarrollador individual, las herramientas distribuidas casi siempre son m s r pidas que las centralizadas. a a Por una raz n sencilla: Una herramienta centralizada necesita comunicarse por red para las operaciones m s usuales, o a debido a que los metadatos se almacenan en una sola copia en el servidor central. Una herramienta distribuida almacena todos sus metadatos localmente. Con todo lo dem s de la misma forma, comunicarse por red tiene un sobrecosto en a una herramienta centralizada. No subestime el valor de una herramienta de respuesta r pida: Usted emplear mucho a a tiempo interactuando con su programa de control de revisiones. Las herramientas distribuidas son indiferentes a los caprichos de su infraestructura de servidores, de nuevo, debido a la replicaci n de metadatos en tantos lugares. Si usa un sistema centralizado y su servidor explota, ojal los medios o a fsicos de su copia de seguridad sean conables, y que su ultima copia sea reciente y adem s funcione. Con una a herramienta distribuida tiene tantas copias de seguridad disponibles como computadores de contribuidores. La conabilidad de su red afectar las herramientas distribuidas de una forma mucho menor que a las herramientas a centralizadas. Usted no puede siquiera usar una herramienta centralizada sin conexi n de red, excepto por algunas o ordenes muy limitadas. Con herramientas distribuidas, si sus conexi n cae mientras usted est trabajando, podra o a nisiquiera darse cuenta. Lo unico que que no podr hacer es comunicarse con repositorios en otros computadores, algo a que es relativamente raro comparado con las operaciones locales. Si tiene colaboradores remotos en su equipo, puede ser importante.

1.4.1.

Ventajas para proyectos de c digo abierto o

Si descubre un proyecto de c digo abierto y decide que desea comenzar a trabajar en el, y ese proyecto usa una o herramienta de control distribuido de revisiones, usted es de inmediato un par con la gente que se considera el alma del proyecto. Si ellos publican sus repositorios, usted puede copiar inmediatamente el historial del proyecto, hacer cambios y guardar su trabajo, usando las mismas herramientas de la misma forma que ellos. En contraste, con una herramienta centralizada, usted debe usar el programa en un modo s lo lectura a menos que alguien le otorgue o permisos para consignar cambios en el repositorio central. Hasta entonces, no podr almacenar sus cambios y sus a modicaciones locales correr n el riesgo de da arse cuando trate de actualizar su vista del repositorio. a n Las bifurcaciones (forks) no son un problema Se ha mencionado que las herramientas de control distribuido de versiones albergan un riesgo a los proyectos de c digo abierto, puesto que se vuelve muy sencillo hacer una bifurcaci n1 del desarrollo del proyecto. Una bio o furcaci n sucede cuando hay diferencias de opini n o actitud entre grupos de desarrolladores que desemboca en la o o decisi n de la imposibilidad de continuar trabajando juntos. Cada parte toma una copia m s o menos completa del o a c digo fuente del proyecto y toma su propio rumbo. o En algunas ocasiones los lderes de las bifurcaciones reconcilian sus diferencias. Con un sistema centralizado de control de revisiones, el proceso t cnico de reconciliarse es doloroso, y se hace de forma muy manual. Usted tiene que e decidir qu historial de revisiones va a ganar, e injertar los cambios del otro equipo en el arbol de alguna manera. e Con esto usualmente se pierde algo o todo del historial de la revisi n de alguna de las partes. o Lo que las herramientas distribuidas hacen con respecto a las bifurcaciones, es que las bifurcaciones son la unica forma de desarrollar un proyecto. Cada cambio que usted hace es potencialmente un punto de bifurcaci n. La gran o fortaleza de esta aproximaci n es que las herramientas distribuidas de control de revisiones tiene que ser bueno al o fusionar las bifurcaciones, porque las bifurcaciones son absolutamente fundamentales: pasan todo el tiempo. Si todas las porciones de trabajo que todos hacen, todo el tiempo, se enmarcan en t rminos de bifurcaciones e y fusiones, entonces a aquello a lo que se reere en el mundo del c digo abierto a una bifurcaci n se convierte o o puramente en una cuesti n social. Lo que hacen las herramientas distribuidas es disminuir la posibilidad de una o bifurcaci n porque: o Eliminan la distinci n social que imponen las herramientas centralizadas: aqu lla entre miembros (personas con o e permiso de consignar) y forasteros (los que no tienen el permiso). Facilitan la reconciliaci n despu s de una bifurcaci n social, porque todo lo que concierne al programa de o e o control de revisiones es una fusi n. o
1 N.

del T. fork.

Algunas personas se resisten a las herramientas distribuidas porque desean mantener control completo sobre sus proyectos, y creen que las herramientas centralizadas les dan tal control. En todo caso, si este es su parecer, y usted publica sus repositorios de CVS o Subversion, hay muchas herramientas disponibles que pueden obtener el historial completo (aunque sea lentamente) y recrearlo en otro sitio que usted no controla. Siendo as un control ilusorio, puesto que est impidiendo la uidez de colaboraci n en lugar de prevenir que alguien se sienta impulsado a obtener una a o copia y hacer una bifurcaci n con su historial. o

1.4.2.

Ventajas para proyectos comerciales

Muchos proyectos comerciales tienen grupos de trabajo distribuidos alrededor del globo. Quienes contribuyen y est n lejos de un repositorio central ver n una ejecuci n m s lenta de los comandos y tal vez menos conabilidad. a a o a Los sistemas de control de revisi n comerciales intentan amortiguar estos problemas con adiciones de replicaci n o o remota que usualmente son muy costosos y complicados de administrar. Un sistema distribuido no padece estos problemas. Mejor a n, puede colocar varios servidores autorizados, por ejemplo, uno por sitio, de tal forma que no haya u comunicaci n redundante entre repositorios sobre enlaces de conexi n costosos. o o Los sistemas de control de revisiones distribuidos tienden a ser poco escalables. No es inusual que costosos sistemas centralizados caigan ante la carga combinada de unas cuantas docenas de usuarios concurrentes. De nuevo, las respuestas tpicas de replicaci n tienden a ser costosas y complejas de instalar y administrar. Dado que la carga en o un servidor centralsi es que tiene unoes muchas veces menor con una herramienta distribuida (debido a que los datos est n replicados en todas partes), un solo servidor econ mico puede tratar las necesidades de equipos mucho a o m s grandes, y la replicaci n para balancear la carga se vuelve cosa de guiones. a o Si tiene un empleado en el campo, se beneciar grandemente de un sistema distribuido de control de versiones a al resolver problemas en el sitio del cliente. La herramienta le permitir generar construcciones a la medida, probar a diferentes arreglos de forma independiente y buscar de forma eciente las fuentes de fallos en el historial y regresiones en los ambientes de los clientes, todo sin necesidad de conectarse al servidor de su compa a. n

1.5.

Por qu elegir Mercurial? e

Mercurial cuenta con un conjunto unico de propiedades que lo hacen una elecci n particularmente buena como o sistema de control de revisiones, puesto que: Es f cil de aprender y usar. a Es liviano. Escala de forma excelente. Es f cil de acondicionar. a Si los sistemas de control de revisiones le son familiares, debera estar listo para usar Mercurial en menos de cinco minutos. Si no, s lo va a tomar unos pocos minutos m s. Las ordenes de Mercurial y su conjunto de caractersticas o a son uniformes y consistentes generalmente, y basta con que siga unas pocas reglas generales en lugar de un mont n o de excepciones. En un proyecto peque o, usted puede comenzar a trabajar con Mercurial en pocos momentos. Crear nuevos camn bios y ramas, transferir cambios (localmente o por la red); y las operaciones relacionadas con el estado y el historial son r pidas. Mercurial buscar ser ligero y no incomodar en su camino combinando poca sobrecarga cognitiva con a operaciones asombrosamente r pidas. a La utilidad de Mercurial no se limita a proyectos peque os: est siendo usado por proyectos con centenas de miles n a de contribuyentes, cada uno conteniendo decenas de miles de cheros y centenas de megabytes de c digo fuente o Si la funcionalidad b sica de Mercurial no es suciente para usted, es muy f cil extenderlo. Mercurial se comporta a a muy bien con tareas de scripting y su limpieza interna junto con su implementaci n en Python permiten a adir caraco n tersticas f cilmente en forma de extensiones. Hay un buen n mero de extensiones utiles y populares en este momento, a u desde ayudar a identicar fallos hasta mejorar su desempe o. n 7

1.6.

Comparaci n de Mercurial con otras herramientas o

Antes de leer, por favor tenga en cuenta que esta secci n necesariamente reeja mis propias experiencias, intereses o y (tengo que decirlo) mis preferencias. He usado cada una de las herramientas de control de versiones listadas a continuaci n, y en muchos casos por varios a os. o n

1.6.1.

Subversion

Subversion es una herramienta de control de revisiones muy popular, desarrollada para reemplazar a CVS. Tiene una arquitectura centralizada tipo cliente/servidor. Subversion y Mercurial tienen comandos con nombres similares para hacer las mismas operaciones, por lo que si le son familiares en una, ser sencillo aprender a usar la otra. Ambas herramientas son portables en todos los sistemas a operativos populares. Antes de la versi n 1.5, Subversion no tena soporte para fusiones. En el momento de la escritura, sus capcidades o para llevar cuenta de las funciones son nuevas, complicadas y poco estables2 . Mercurial tiene una ventaja considerable en desempe o sobre Subversion en cualquier operaci n de control de n o revisiones que yo haya medido. He medido sus ventajas con factores desde dos hasta seis veces comparando con ale a a macenamiento de cheros ra local Subversion 1.4.3, el cual es el m todo de acceso m s r pido. En los escenarios m s realistas incluyendo almacenamiento con la red de por medio, Subversion se encuentra en desventaja a n mayor. a u Dado que casi todas las ordenes de Subversion deben tratar con el servidor y Subversion no tiene utilidades de replicaci n adecuadas, la capacidad del servidor y el ancho de banda se convierten en cuellos de botella para proyectos o modestamente grandes. Adicionalmente, Subversion tiene un sobrecosto considerable en almacenamiento para evitar transacciones por red en algunas operaciones, tales como encontrar cheros modicados (status) y desplegar informaci n frente a la o revisi n actual (diff). Como resultado, la copia de trabajo de Subversion termina siendo del mismo tama o o m s o n a grande que un repositorio de Mercurial y el directorio de trabajo, a pesar de que el repositorio de Mercurial contiene el historial completo del proyecto. Subversion tiene soporte amplio de otras herramientas. Mercurial por ahora est bastante atr s en este aspecto. a a Esta diferencia est disminuyendo, y algunas de las herramientas GUI3 , eclipsan sus equivalentes de Subversion. Al a igual que Mercurial, Subversion tiene un excelente manual de usuario. Dado que Subversion no almacena el historial de revisiones en el cliente, es muy bueno para administrar proyectos que tienen muchos cheros binarios grandes y opacos. Si consigna cincuenta revisiones de un chero de 10MB que no es comprimible, el esapacio en el cliente de Subversion se mantendr constante mientras que el espacio usado a por cualquier Sistema Distribuido de Control de Revisiones crecer r pidamente en proporci n con el n mero de a a o u revisiones, debido a que las diferencias entre cada revisi n es grande. o Adicionalmente, generalmente es difcil o m s bien, imposible mezclar diferentes versiones de un chero binario. a La habilidad de Subversion para permitirle al usuario poner una cerradura a un chero, de modo que tenga un permiso exclusivo para consignar cambios, puede ser una ventaja signicativa en un proyecto donde los cheros binarios sean usados ampliamente. Mercurial puede importar el historial de revisiones de un repositorio de Subversion. Tambi n puede exportar el e historial de revisiones a un repositorio de Subversion. De esta forma es sencillo dar un vistazo y usar Mercurial y Subversion en paralelo antes de decidirse a dar el paso. La conversi n del historial es incremental, de modo que o puede aplicar una conversi n inicial, y despu s conversiones peque as y adicionales posteriormente para traer nuevos o e n cambios.

1.6.2.

Git

Git es una herramienta distribuida de control de revisiones desarrollada para administrar el arbol del kernel de Linux. Al igual que Mercurial los principios de su dise o fueron inuenciados por Monotone. n
3 N. 2 N.

del T. buggy del T. Interfaz de Usuario Gr ca a

Git tiene un conjunto de ordenes muy grande; en la versi n 1.5.0 ofrece 139 ordenes individuales. Tiene cierta o reputaci n de ser difcil de aprender. Comparado con Git, Mercurial tiene un fuerte enfoque hacia la facilidad. o En t rminos de rendimiento, Git es extremadamente r pido. En muchos casos, es m s r pido que Mercurial, por lo e a a a menos en Linux, mientras que Mercurial se comporta mejor en otras operaciones. De todas maneras en Windows, el desempe o y el nivel general de soporte que ofrece Git, al momento de la escritura, est bastante atr s de Mercurial. n a a Mientras que el repositorio de Mercurial no requiere mantenimiento, el repositorio de Git requiere frecuentes reempaquetados de sus metadatos. Sin estos, el desempe o se degrada y el uso de espacio crece r pidamente. Un n a servidor que contenga repositorios de Git que no sean reempacados rigurosa y frecuentemente requerir trabajo ina tenso de disco durante las copias de seguridad, y ha habido situaciones en copias de seguridad diaria que toman m s a de 24 horas como resultado. Un repositorio reci n reempacado de Git es un poco m s peque o que un repositorio de e a n Mercurial, pero un repositorio sin reempacar es varios ordenes de magnitud m s grande. a El coraz n de Git est escrito en C. Muchas ordenes de Git est n implementadas como guiones de lnea de coo a a mandos o de Perl y la calidad de esos guiones vara ampliamente. He encontrado muchas situaciones en las cuales los guiones no tuvieron en cuenta la presencia de errores que podran haber sido fatales. Mercurial puede importar el historial de revisiones de un repositorio de Git.

1.6.3.

CVS

CVS es probablemente la herramienta de control de revisiones m s ampliamente usada en el planeta. Debido a su a edad y su poca pulcritud interna, ha sido ligeramente mantenida en muchos a os. n Tiene una arquitectura centralizada cliente/servidor. No agrupa cambios relacionados en consignaciones at micas, o pemitiendo que con facilidad la gente rompa la construcci n: una persona puede consignar exit samente parte del o o cambio y estar bloqueada por la necesidad de una mezcla, forzando a otras personas a ver solamente una porci n del o trabajo que estaban buscando hacer. Esto afecta tambi n la forma como usted trabaja con el historial del proyecto. Si e quiere ver todas las modicaciones que alguien hizo como parte de una tarea, necesitar inspeccionar manualmente a las descripciones y las marcas de tiempo de cambio de cada chero involucrado (esto, si usted saber cu les eran tales a cheros). CVS tiene una noci n confusa de etiquetas y ramas que yo no tratara incluso de describir. No soporta renomo bramiento de cheros o directorios adecuadamente, facilitando el corromper un repositorio. Casi no tiene chequeo de consistencia interna, por lo tanto es casi imposible identicar por que o c mo se corrompi un repositorio. Yo no o o recomendara un repositorio de CVS para proyecto alguno, ni existente ni nuevo. Mercurial puede importar el historial de revisiones de CVS. De todas maneras hay ciertas precauciones que aplican; las cuales tambi n son necesarias para cualquier herramienta importadora de historial de CVS. Debido a la falta e de atomicidad de cambios y el no versionamiento de la jerarqua del sistema de cheros, es imposible reconstruir completamente el historial de CVS con precisi n; hay cierto trabajo de conjetura involucrado y los renombramientos o tampoco se mostrar n. Debido a que gran parte de la administraci n avanzada de CVS tiene que hacerse manualmente a o y por lo tanto es proclive al error, es com n que los importadores de CVS encuentren muchos problemas con reposiu torios corruptos (marcas de tiempo totalmente desubicadas y cheros que han permanecido con candados por m s de a una d cada son dos de los problemas menos interesantes de los que puedo retomar de mi experiencia personal). e Mercurial puede importar el historial de revisiones de un repositorio CVS.

1.6.4.

Herramientas comerciales

Perforce tiene una arquitectura centralizada cliente/servidor sin almacenamiento de dato alguno de cach en el e lado del cliente. A diferencia de las herramientas modernas de control de revisiones, Perforce requiere que un usuario ejecute un comando para informar al servidor acerca de todo chero que se vaya a editar. El rendimiento de Perforce es muy bueno para equipos peque os, pero se degrada r pidamente cuando el n mero n a u de usuarios va m s all de pocas docenas. Instalaciones modestamente grandes de Perforce requiere la organizaci n a a o de proxies para soportar la carga que sus usuarios generan.

1.6.5.

Elegir una herramienta de control de revisiones

Con la excepci n de CVS, toda las herramientas que se han listado anteriormente tienen fortalezas unicas que las o hacen valiosas de acuerdo al tipo de trabajo. No hay una unica herramienta de control de revisiones que sea la mejor en todas las situaciones. Por ejemplo, Subversion es una buena elecci n para trabajar con edici n frecuente de cheros binarios, debido a o o su naturaleza centralizada y soporte para poner candados a cheros. Personalmente encuentro las propiedades de simplicidad, desempe o, y buen soporte de fusiones de Mercurial una n combinaci n llamativa que ha dado buenos frutos por varios a os. o n

1.7.

Migrar de otra herramienta hacia Mercurial

Mercurial viene con una extensi n llamada convert, que puede importar historiales de revisiones de forma increo mental desde varias herramientas de control de revisiones. Por incremental, quiero decir que puede migrar toda el historial de un proyecto en una primera instancia y despu s volver a ejecutar la migraci n posteriormente para obtener e o los nuevos cambios que han sucedido despu s de la migraci n inicial. e o A continuaci n presentamos las herramientas de revisiones que soporta el comando convert: o Subversion CVS Git Darcs Adicionalmente, convert puede exportar cambios de Mercurial hacia Subversion. Lo que hace posible probar Subversion y Mercurial en paralelo antes de lanzarse a un migraci n total, sin arriesgarse a perder trabajo alguno. o El comando hg convert es sencillo de usar. Basta con apuntarlo hacia la ruta o el URL del repositorio fuente, opcionalmente darle el nombre del nombre del repositorio destino y comenzar a hacer su trabajo. Despu s de la a e conversi n inicial, basta con invocar de nuevo el comando para importar cambios nuevos. o

10

Captulo 2

Una gira de Mercurial: lo b sico a


2.1. Instalar Mercurial en su sistema

Hay paquetes binarios precompilados de Mercurial disponibles para cada sistema operativo popular. Esto hace f cil empezar a usar Mercurial en su computador inmediatamente. a

2.1.1.

Linux

Dado que cada distribuci n de Linux tiene sus propias herramientas de manejo de paquetes, polticas, y ritmos o de desarrollo, es difcil dar un conjunto exhaustivo de instrucciones sobre c mo instalar el paquete de Mercurial. La o versi n de Mercurial que usted tenga a disposici n puede variar dependiendo de qu tan activa sea la persona que o o e mantiene el paquete para su distribuci n. o Para mantener las cosas simples, me enfocar en instalar Mercurial desde la lnea de comandos en las distribuciones e de Linux m s populares. La mayora de estas distribuciones proveen administradores de paquetes gr cos que le a a permitir n instalar Mercurial con un solo clic; el nombre de paquete a buscar es mercurial. a Debian apt-get install mercurial 1 Fedora Core yum install mercurial 1 Gentoo emerge mercurial 1 OpenSUSE yum install mercurial 1 Ubuntu El paquete de Mercurial de Ubuntu est basado en el de Debian. Para instalarlo, ejecute el siguiente comando. a
1

apt-get install mercurial El paquete de Mercurial para Ubuntu tiende a atrasarse con respecto a la versi n de Debian por un margen de o tiempo considerable (al momento de escribir esto, 7 meses), lo que en algunos casos signicar que usted puede a encontrarse con problemas que ya habr n sido resueltos en el paquete de Debian. a

2.1.2.

Solaris

SunFreeWare, en http://www.sunfreeware.com, es una buena fuente para un gran n mero de paquetes compiu lados para Solaris para las arquitecturas Intel y Sparc de 32 y 64 bits, incluyendo versiones actuales de Mercurial. 11

2.1.3.

Mac OS X

Lee Cantey publica un instalador de Mercurial para Mac OS X en http://mercurial.berkwood.com. Este paquete funciona en tanto en Macs basados en Intel como basados en PowerPC. Antes de que pueda usarlo, usted debe instalar una versi n compatible de Universal MacPython [BI]. Esto es f cil de hacer; simplemente siga las o a instrucciones del sitio de Lee. Tambi n es posible instalar Mercurial usando Fink o MacPorts, dos administradores de paquetes gratuitos y pope ulares para Mac OS X. Si usted tiene Fink, use sudo apt-get install mercurial-py25. Si usa MacPorts, sudo port install mercurial.

2.1.4.

Windows

Lee Cantey publica un instalador de Mercurial para Windows en http://mercurial.berkwood.com. Este paquete no tiene dependencias externas; simplemente funciona. Nota: La versi n de Windows de Mercurial no convierte autom ticamente los nes o a de lnea entre estilos Windows y Unix. Si usted desea compartir trabajo con usuar ios de Unix, deber hacer un trabajo adicional de conguraci n. XXX Terminar a o esto.

2.2.

Arrancando

Para empezar, usaremos el comando hg version para revisar si Mercurial est instalado adecuadamente. La a informaci n de la versi n que es impresa no es tan importante; lo que nos importa es si imprime algo en absoluto. o o
1 2 3 4 5 6

$ hg version Mercurial Distributed SCM (version 1.0.1) Copyright (C) 2005-2008 Matt Mackall <mpm@selenic.com> and others This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

2.2.1.

Ayuda integrada

Mercurial provee un sistema de ayuda integrada. Esto es invaluable para esas ocasiones en la que usted est atorado a tratando de recordar c mo ejecutar un comando. Si est completamente atorado, simplemente ejecute hg help; esto o a imprimir una breve lista de comandos, junto con una descripci n de qu hace cada uno. Si usted solicita ayuda sobre a o e un comando especco (como abajo), se imprime informaci n m s detallada. o a
1 2 3 4 5 6 7 8 9 10 11 12 13 14

$ hg help init hg init [-e CMD] [--remotecmd CMD] [DEST] create a new repository in the given directory Initialize a new repository in the given directory. directory does not exist, it is created. If the given

If no directory is given, the current directory is used. It is possible to specify an ssh:// URL as the destination. Look at the help text for the pull command for important details about ssh:// URLs.

12

15 16 17 18 19 20

options: -e --ssh --remotecmd specify ssh command to use specify hg command to run on the remote side

use "hg -v help init" to show global options Para un nivel m s impresionante de detalle (que usted no va a necesitar usualmente) ejecute hg help -v. La opci n a o -v es la abreviaci n para --verbose, y le indica a Mercurial que imprima m s informaci n de lo que hara usualmente. o a o

2.3.

Trabajar con un repositorio

En Mercurial, todo sucede dentro de un repositorio. El repositorio para un proyecto contiene todos los cheros que pertenecen a ese proyecto, junto con un registro hist rico de los cheros de ese proyecto. o No hay nada particularmente m gico acerca de un repositorio; es simplemente un arbol de directorios en su sistema a de cheros que Mercurial trata como especial. Usted puede renombrar o borrar un repositorio en el momento que lo desee, usando bien sea la lnea de comandos o su explorador de cheros.

2.3.1.

Hacer una copia local de un repositorio

Copiar un repositorio es s lo ligeramente especial. Aunque usted podra usar un programa normal de copia de o cheros para hacer una copia del repositorio, es mejor usar el comando integrado que Mercurial ofrece. Este comando se llama hg clone1 , porque crea una copia id ntica de un repositorio existente. e
1 2 3 4 5 6 7 8 9

$ hg clone http://hg.serpentine.com/tutorial/hello destination directory: hello requesting all changes adding changesets adding manifests adding file changes added 5 changesets with 5 changes to 2 files updating working directory 2 files updated, 0 files merged, 0 files removed, 0 files unresolved Si nuestro clonado tiene exito, deberamos tener un directorio local llamado hello. Este directorio contendr algunos a cheros.

1 2 3 4 5

$ ls -l total 0 drwxr-xr-x 3 jerojasro jerojasro 120 Feb 10 18:23 hello $ ls hello Makefile hello.c Estos cheros tienen el mismo contenido e historial en nuestro repositorio y en el repositorio que clonamos. Cada repositorio Mercurial est completo, es autocontenido e independiente. Contiene su propia copia de los a cheros y el historial de un proyecto. Un repositorio clonado recuerda la ubicaci n de la que fue clonado, pero no se o comunica con ese repositorio, ni con ning n otro, a menos que usted le indique que lo haga. u Lo que esto signica por ahora es que somos libres de experimentar con nuestro repositorio, con la tranquilidad de saber que es una caja de arena privada que no afectar a nadie m s. a a
1 N.

del T. Del t rmino clonar en ingl s. e e

13

2.3.2.

Qu hay en un repositorio? e

Cuando miramos en detalle dentro de un repositorio, podemos ver que contiene un directorio llamado .hg. Aqu es donde Mercurial mantiene todos los metadatos del repositorio.
1 2 3

$ cd hello $ ls -a . .. .hg Makefile

hello.c

Los contenidos del directorio .hg y sus subdirectorios son exclusivos de Mercurial. Usted es libre de hacer lo que desee con cualquier otro chero o directorio en el repositorio. Para introducir algo de terminologa, el directorio .hg es el repositorio real, y todos los cheros y directorios que coexisten con el est n en el directorio de trabajo. Una forma sencilla de recordar esta distinci n es que el repositorio a o contiene el historial de su proyecto, mientras que el directorio de trabajo contiene una instant nea de su proyecto en a un punto particular del historial.

2.4.

Vistazo r pido al historial a

Una de las primeras cosas que se desea hacer con un repositorio nuevo, poco conocido, es conocer su historial. El comando hg log nos permite ver el mismo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

$ hg log changeset: tag: user: date: summary: changeset: user: date: summary: changeset: user: date: summary: changeset: user: date: summary: changeset: user: date: summary:

4:2278160e78d4 tip Bryan OSullivan <bos@serpentine.com> Sat Aug 16 22:16:53 2008 +0200 Trim comments. 3:0272e0d5a517 Bryan OSullivan <bos@serpentine.com> Sat Aug 16 22:08:02 2008 +0200 Get make to generate the final binary from a .o file. 2:fef857204a0c Bryan OSullivan <bos@serpentine.com> Sat Aug 16 22:05:04 2008 +0200 Introduce a typo into hello.c. 1:82e55d328c8c mpm@selenic.com Fri Aug 26 01:21:28 2005 -0700 Create a makefile 0:0a04b987be5a mpm@selenic.com Fri Aug 26 01:20:50 2005 -0700 Create a standard "hello, world" program

Por defecto este programa imprime un p rrafo breve por cada cambio al proyecto que haya sido grabado. Dentro de a la terminologa de Mercurial, cada uno de estos eventos es llamado conjunto de cambios, porque pueden contener un registro de cambios a varios cheros. 14

Los campos de la salida de hg log son los siguientes. changeset2 Este campo tiene un n mero, seguido por un :, seguido por una cadena hexadecimal. Ambos son identicadores u para el conjunto de cambios. Hay dos identicadores porque el n mero es m s corto y m s f cil de recordar que u a a a la cadena hexadecimal. user3 La identidad de la persona que cre el conjunto de cambios. Este es un campo en el que se puede almacenar o cualquier valor, pero en la mayora de los casos contiene el nombre de una persona y su direcci n de correo o electr nico. o date4 La fecha y hora en la que el conjunto de cambios fue creado, y la zona horaria en la que fue creado. (La fecha y hora son locales a dicha zona horaria; ambos muestran la fecha y hora para la persona que cre el conjunto de o cambios). summary5 La primera lnea del texto que us la persona que cre el conjunto de cambios para describir el mismo. o o El texto impreso por hg log es s lo un sumario; omite una gran cantidad de detalles. o La gura 2.1 es una representaci n gr ca del historial del repositorio hello, para hacer m s f cil ver en qu dio a a a e recci n est uyendo el historial. Volveremos a esto varias veces en este captulo y en los siguientes. o a
4: 2278 (la ms nueva) 4: 2278

3: 0272

2: fef8

nmero de revisin

identificador del conjunto de cambios

1: 82e5

0: 0a04

(la ms antigua)

Figura 2.1: Historial gr co del repositorio hello a

2.4.1.

Conjuntos de cambios, revisiones, y comunic ndose con otras personas a

Ya que el ingl s es un lenguaje notablemente desordenado, y el area de ciencias de la computaci n tiene una e o notable historia de confusi n de t rminos (porqu usar s lo un t rmino cuando cuatro pueden servir?), el control de o e e o e revisiones tiene una variedad de frases y palabras que tienen el mismo signicado. Si usted habla acerca del historial de Mercurial con alguien, encontrar que la expresi n conjunto de cambios es abreviada a menudo como cambio a o o (por escrito) cset6 , y algunas veces un se hace referencia a un conjunto de cambios como una revisi n o rev7 . o Si bien no es relevante qu palabra use usted para referirse al concepto conjunto de cambios, el identicador que e usted use para referise a un conjunto de cambios particular es muy importante. Recuerde que el campo changeset en la salida de hg log identica un conjunto de cambios usando tanto un n mero como una cadena hexadecimal. u
del T. Conjunto de cambios. del T. Usuario. 4 N. del T. Fecha. 5 N. del T. Sumario. 6 N. del T. Abreviatura para la expresi n changeset en ingl s. o e 7 N. del T. De nuevo, como abreviaci n para el t rmino en ingl s para revisi n (revision). o e e o
3 N. 2 N.

15

El n mero de revisi n s lo es v lido dentro del repositorio. u o o a Por otro lado, la cadena hexadecimal es el identicador permanente e inmutable que siempre identicar ese a conjunto de cambios en todas las copias del repositorio. La diferencia es importante. Si usted le enva a alguien un correo electr nico hablando acerca de la revisi n 33, hay o o una probabilidad alta de que la revisi n 33 de esa persona no sea la misma suya. Esto sucede porque el n mero de o u revisi n depende del orden en que llegan los cambios al repositorio, y no hay ninguna garanta de que los mismos o cambios llegar n en el mismo orden en diferentes repositorios. Tres cambios dados a, b, c pueden aparecer en un a repositorio como 0, 1, 2, mientras que en otro aparecen como 1, 0, 2. Mercurial usa los n meros de revisi n simplemente como una abreviaci n conveniente. Si usted necesita hablar u o o con alguien acerca de un conjunto de cambios, o llevar el registro de un conjunto de cambios por alguna otra raz n o (por ejemplo, en un reporte de fallo), use el identicador hexadecimal.

2.4.2.

Ver revisiones especcas

Para reducir la salida de hg log a una sola revisi n, use la opci n -r (o --rev). Puede usar un n mero de o o u revisi n o un identicador hexadecimal de conjunto de cambios, y puede pasar tantas revisiones como desee. o
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

$ hg log -r 3 changeset: 3:0272e0d5a517 user: Bryan OSullivan <bos@serpentine.com> date: Sat Aug 16 22:08:02 2008 +0200 summary: Get make to generate the final binary from a .o file. $ hg log -r 0272e0d5a517 changeset: 3:0272e0d5a517 user: Bryan OSullivan <bos@serpentine.com> date: Sat Aug 16 22:08:02 2008 +0200 summary: Get make to generate the final binary from a .o file. $ hg log -r 1 -r 4 changeset: 1:82e55d328c8c user: mpm@selenic.com date: Fri Aug 26 01:21:28 2005 -0700 summary: Create a makefile changeset: tag: user: date: summary: 4:2278160e78d4 tip Bryan OSullivan <bos@serpentine.com> Sat Aug 16 22:16:53 2008 +0200 Trim comments.

Si desea ver el historial de varias revisiones sin tener que mencionar cada una de ellas, puede usar la notaci n de o rango; esto le permite expresar el concepto quiero ver todas las revisiones entre a y b, inclusive.
1 2 3 4 5 6

$ hg log -r 2:4 changeset: 2:fef857204a0c user: Bryan OSullivan <bos@serpentine.com> date: Sat Aug 16 22:05:04 2008 +0200 summary: Introduce a typo into hello.c.

16

7 8 9 10 11 12 13 14 15 16 17

changeset: user: date: summary: changeset: tag: user: date: summary:

3:0272e0d5a517 Bryan OSullivan <bos@serpentine.com> Sat Aug 16 22:08:02 2008 +0200 Get make to generate the final binary from a .o file. 4:2278160e78d4 tip Bryan OSullivan <bos@serpentine.com> Sat Aug 16 22:16:53 2008 +0200 Trim comments.

Mercurial tambi n respeta el orden en que usted especica las revisiones, as que hg log -r 2:4 muestra 2, 3, 4 e mientras que hg log -r 4:2 muestra 4, 3, 2.

2.4.3.

Informaci n m s detallada o a

Aunque la informaci n presentada por hg log es util si usted sabe de antemano qu est buscando, puede o e a que necesite ver una descripci n completa del cambio, o una lista de los cheros que cambiaron, si est tratando de o a averiguar si un conjunto de cambios dado es el que usted est buscando. La opci n -v (or --verbose) del comando a o hg log le da este nivel extra de detalle.
1 2 3 4 5 6 7 8 9

$ hg log -v -r 3 changeset: 3:0272e0d5a517 user: Bryan OSullivan <bos@serpentine.com> date: Sat Aug 16 22:08:02 2008 +0200 files: Makefile description: Get make to generate the final binary from a .o file.

Si desea ver tanto la descripci n como el contenido de un cambio, a ada la opci n -p (o --patch). Esto muestra o n o el contenido de un cambio como un diff unicado (si usted nunca ha visto un diff unicado antes, vea la secci n 12.4 o para un vistazo global).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

$ hg log -v -p -r 2 changeset: 2:fef857204a0c user: Bryan OSullivan <bos@serpentine.com> date: Sat Aug 16 22:05:04 2008 +0200 files: hello.c description: Introduce a typo into hello.c.

diff -r 82e55d328c8c -r fef857204a0c hello.c --- a/hello.c Fri Aug 26 01:21:28 2005 -0700 +++ b/hello.c Sat Aug 16 22:05:04 2008 +0200 @@ -11,6 +11,6 @@ int main(int argc, char **argv) { 17

17 18 19 20 21

+ }

printf("hello, world!\n"); printf("hello, world!\"); return 0;

2.5.

Todo acerca de las opciones para comandos

Tomemos un breve descanso de la tarea de explorar los comandos de Mercurial para hablar de un patr n en la o manera en que trabajan; ser util tener esto en mente a medida que avanza nuestra gira. a Mercurial tiene un enfoque directo y consistente en el manejo de las opciones que usted le puede pasar a los comandos. Se siguen las convenciones para opciones que son comunes en sistemas Linux y Unix modernos. Cada opci n tiene un nombre largo. Por ejemplo, el comando hg log acepta la opci n --rev, como ya hemos o o visto. Muchas opciones tienen tambi n un nombre corto. En vez de --rev, podemos usar -r. (El motivo para que e algunas opciones no tengan nombres cortos es que dichas opciones se usan rara vez.) Las opciones largas empiezan con dos guiones (p.ej. --rev), mientras que las opciones cortas empiezan con uno (e.g. -r). El nombre y uso de las opciones es consistente en todos los comandos. Por ejemplo, cada comando que le permite pasar un ID de conjunto de cambios o un n mero de revisi n acepta tanto la opci n -r como la --rev. u o o En los ejemplos en este libro, uso las opciones cortas en vez de las largas. Esto s lo muestra mis preferencias, as que o no le d signicado especial a eso. e Muchos de los comandos que generan salida de alg n tipo mostrar n m s salida cuando se les pase la opci n -v u a a o (o --verbose8 ), y menos cuando se les pase la opci n -q (o --quiet9 ). o

2.6.

Hacer y repasar cambios

Ahora que tenemos una comprensi n adecuada sobre c mo revisar el historial en Mercurial, hagamos algunos o o cambios y veamos c mo examinarlos. o Lo primero que haremos ser aislar nuestro experimento en un repositorio propio. Usaremos el comando hg a clone, pero no hace falta clonar una copia del repositorio remoto. Como ya contamos con una copia local del mismo, podemos clonar esa. Esto es mucho m s r pido que clonar a trav s de la red, y en la mayora de los casos clonar un a a e repositorio local usa menos espacio en disco tambi n. e
1 2 3 4 5

$ cd .. $ hg clone hello my-hello updating working directory 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd my-hello A manera de recomendaci n, es considerado buena pr ctica mantener una copia prstina de un repositorio remoto a o a mano, del cual usted puede hacer clones temporales para crear cajas de arena para cada tarea en la que desee trabajar. Esto le permite trabajar en m ltiples tareas en paralelo, teniendo cada una de ellas aislada de las otras hasta que est n u e completas y usted est listo para integrar los cambios de vuelta. Como los clones locales son tan baratos, clonar y e destruir repositorios no consume demasiados recursos, lo que facilita hacerlo en cualquier momento.
9 N. 8 N.

del T. Prolijo. del T. Silencioso.

18

En nuestro repositorio my-hello, hay un chero hello.c que contiene el cl sico programa hello, world10 . a Usaremos el cl sico y venerado comando sed para editar este chero y hacer que imprima una segunda lnea de a salida. (Estoy usando el comando sed para hacer esto s lo porque es f cil escribir un ejemplo automatizado con el. o a Dado que usted no tiene esta restricci n, probablemente no querr usar sed; use su editor de texto preferido para hacer o a lo mismo).
1

$ sed -i /printf/a\\tprintf("hello again!\\n"); hello.c El comando hg status de Mercurial nos dice lo que Mercurial sabe acerca de los cheros en el repositorio.

1 2 3 4

$ ls Makefile hello.c $ hg status M hello.c El comando hg status no imprime nada para algunos cheros, s lo una lnea empezando con M para el chero o hello.c. A menos que usted lo indique explcitamente, hg status no imprimir nada respecto a los cheros que a no han sido modicados. La M indica que Mercurial se dio cuenta de que nosotros modicamos hello.c. No tuvimos que decirle a Mercurial que bamos a modicar ese chero antes de hacerlo, o que lo modicamos una vez terminamos de hacerlo; el fue capaz de darse cuenta de esto por s mismo. Es algo util saber que hemos modicado el chero hello.c, pero preferiramos saber exactamente qu cambios e hicimos. Para averiguar esto, usamos el comando hg diff.

1 2 3 4 5 6 7 8 9 10 11

$ hg diff diff -r 2278160e78d4 hello.c --- a/hello.c Sat Aug 16 22:16:53 2008 +0200 +++ b/hello.c Tue Feb 10 18:23:34 2009 +0000 @@ -8,5 +8,6 @@ int main(int argc, char **argv) { printf("hello, world!\"); + printf("hello again!\n"); return 0; }

2.7.

Grabar cambios en un nuevo conjunto de cambios

Podemos modicar, compilar y probar nuestros cambios, y usar hg status y hg diff para revisar los mismos, hasta que estemos satisfechos con los resultados y lleguemos a un momento en el que sea natural que querramos guardar nuestro trabajo en un nuevo conjunto de cambios. El comando hg commit nos permite crear un nuevo conjunto de cambios. Nos referiremos usualmente a esto como hacer una consigna o consignar.

2.7.1.

Denir un nombre de usuario

Cuando usted trata de ejecutar hg commit11 por primera vez, no est garantizado que lo logre. Mercurial registra a su nombre y direcci n en cada cambio que usted consigna, para que m s adelante otros puedan saber qui n es el o a e responsable de cada cambio. Mercurial trata de encontrar un nombre de usuario adecuado con el cual registrar la consignaci n. Se intenta con cada uno de los siguientes m todos, en el orden presentado. o e
11 N. 10 N.

del T. Hola, mundo. del T. Hacer una consignaci n o

19

1. Si usted pasa la opci n -u al comando hg commit en la lnea de comandos, seguido de un nombre de usuario, o se le da a esto la m xima precedencia. a 2. A continuaci n se revisa si usted ha denido la variable de entorno HGUSER. o 3. Si usted crea un chero en su directorio personal llamado .hgrc, con una entrada username, se usa luego. Para revisar c mo debe verse este chero, re rase a la secci n 2.7.1 m s abajo. o e o a 4. Si usted ha denido la variable de entorno EMAIL, ser usada a continuaci n. a o 5. Mercurial le pedir a su sistema buscar su nombre de usuario local, y el nombre de m quina, y construir un a a a nombre de usuario a partir de estos componentes. Ya que esto generalmente termina generando un nombre de usuario no muy util, se imprimir una advertencia si es necesario hacerlo. a Si todos estos procedimientos fallan, Mercurial fallar , e imprimir un mensaje de error. En este caso, no le permia a tir hacer la consignaci n hasta que usted dena un nombre de usuario. a o Trate de ver la variable de entorno HGUSER y la opci n -u del comando hg commit como formas de hacer caso o omiso de la selecci n de nombre de usuario que Mercurial hace normalmente. Para uso normal, la manera m s simple y o a sencilla de denir un nombre de usuario para usted es crear un chero .hgrc; los detalles se encuentran m s adelante. a Crear el chero de conguraci n de Mercurial o Para denir un nombre de usuario, use su editor de texto favorito para crear un chero llamado .hgrc en su directorio personal. Mercurial usar este chero para obtener las conguraciones personalizadas que usted haya hecho. a El contenido inicial de su chero .hgrc debera verse as.
1 2 3

# Este es un fichero de configuracin de Mercurial. o [ui] username = Primernombre Apellido <correo.electronico@dominio.net> La lnea [ui] dene una section del chero de conguraci n, as que usted puede leer la lnea username = ... o como dena el valor del elemento username en la secci n ui. Una secci n continua hasta que empieza otra nueva, o o o se llega al nal del chero. Mercurial ignora las lneas vacas y considera cualquier texto desde el caracter # hasta el nal de la lnea como un comentario. Escoger un nombre de usuario Usted puede usar el texto que desee como el valor del campo de conguraci n username, ya que esta informaci n o o ser leda por otras personas, e interpretada por Mercurial. La convenci n que sigue la mayora de la gente es usar su a o nombre y direcci n de correo, como en el ejemplo anterior. o Nota: El servidor web integrado de Mercurial ofusca las direcciones de correo, para dicultar la tarea de las herramientas de recolecci n de direcciones de correo o que usan los spammersa . Esto reduce la probabilidad de que usted empiece a recibir m s correo basura si publica un repositorio en la red. a
a N.

del T. Personas que envan correo no solicitado, tambi n conocido como correo basura e

2.7.2.

Escribir un mensaje de consignaci n o

Cuando consignamos un cambio, Mercurial nos ubica dentro de un editor de texto, para ingresar un mensaje que describa las modicaciones que hemos introducido en este conjunto de cambios. Esto es conocido como un mensaje de consignaci n. Ser un registro de lo que hicimos y porqu lo hicimos, y ser impreso por hg log una vez hayamos o a e a hecho la consignaci n. o
1

$ hg commit 20

El editor en que hg commit nos ubica contendr una lnea vaca, seguida de varias lneas que empiezan con la a cadena HG:.
1 2

lnea vaca HG: changed hello.c Mercurial ignora las lneas que empiezan con HG:; s lo las usa para indicarnos para cu les cheros est registrando o a a los cambios. Modicar o borrar estas lneas no tiene ning n efecto. u

2.7.3.

Escribir un buen mensaje de consignaci n o

Ya que por defecto hg log s lo muestra la primera lnea de un mensaje de consignaci n, lo mejor es escribir un o o mensaje cuya primera lnea tenga signicado por s misma. A continuaci n se encuentra un ejemplo de un mensaje de o consignaci n que no sigue esta pauta, y debido a ello tiene un sumario que no es legible. o
1 2 3 4

changeset: user: date: summary:

73:584af0e231be Persona Censurada <persona.censurada@ejemplo.org> Tue Sep 26 21:37:07 2006 -0700 se incluye buildmeister/commondefs. Aade un mdulo n o

Con respecto al resto del contenido del mensaje de consignaci n, no hay reglas estrictas-y-r pidas. Mercurial no o a interpreta ni le da importancia a los contenidos del mensaje de consignaci n, aunque es posible que su proyecto tenga o polticas que denan una manera particular de escribirlo. Mi preferencia personal es usar mensajes de consignaci n cortos pero informativos, que me digan algo que no o puedo inferir con una mirada r pida a la salida de hg log --patch. a

2.7.4.

Cancelar una consignaci n o

Si usted decide que no desea hacer la consignaci n mientras est editando el mensaje de la misma, simplemente o a cierre su editor sin guardar los cambios al chero que est editando. Esto har que no pase nada ni en el repositorio ni a a en el directorio de trabajo. Si ejecutamos el comando hg commit sin ning n argumento, se registran todos los cambios que hemos hecho, u como lo indican hg status y hg diff.

2.7.5.

Admirar nuestro trabajo

Una vez hemos terminado la consignaci n, podemos usar el comando hg tip12 para mostrar el conjunto de o cambios que acabamos de crear. La salida de este comando es id ntica a la de hg log, pero s lo muestra la revisi n e o o m s reciente en el repositorio. a
1 2 3 4 5 6 7 8 9 10 11

$ hg tip -vp changeset: 5:fccff93807a3 tag: tip user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:34 2009 +0000 files: hello.c description: Added an extra line of output

diff -r 2278160e78d4 -r fccff93807a3 hello.c


12 N.

del T. Punta.

21

12 13 14 15 16 17 18 19 20 21

--- a/hello.c Sat Aug 16 22:16:53 2008 +0200 +++ b/hello.c Tue Feb 10 18:23:34 2009 +0000 @@ -8,5 +8,6 @@ int main(int argc, char **argv) { printf("hello, world!\"); + printf("hello again!\n"); return 0; }

Nos referimos a la revisi n m s reciente en el repositorio como la revisi n de punta, o simplemente la punta. o a o

2.8.

Compartir cambios

Anteriormente mencionamos que los repositorios en Mercurial est n auto contenidos. Esto quiere decir que el a conjunto de cambios que acabamos de crear s lo existe en nuestro repositorio my-hello. Veamos unas cuantas formas o de propagar este cambio a otros repositorios.

2.8.1.

Jalar cambios desde otro repositorio

Para empezar, clonemos nuestro repositorio hello original, el cual no contiene el cambio que acabamos de consignar. Llamaremos a este repositorio temporal hello-pull.
1 2 3 4

$ cd .. $ hg clone hello hello-pull updating working directory 2 files updated, 0 files merged, 0 files removed, 0 files unresolved Usaremos el comando hg pull para traer los cambios de my-hello y ponerlos en hello-pull. Sin embargo, traer cambios desconocidos y aplicarlos en un repositorio es una perspectiva que asusta al menos un poco. Mercurial cuenta con el comando hg incoming13 para decirnos qu cambios jalara el comando hg pull al repositorio, e sin jalarlos.

1 2 3 4 5 6 7 8 9 10

$ cd hello-pull $ hg incoming ../my-hello comparing with ../my-hello searching for changes changeset: 5:fccff93807a3 tag: tip user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:34 2009 +0000 summary: Added an extra line of output

(Por supuesto, alguien podra enviar m s conjuntos de cambios al repositorio en el tiempo que pasa entre la ejecuci n a o de hg incoming y la ejecuci n de hg pull para jalar los cambios, as que es posible que terminemos jalando o cambios que no esper bamos.) a Traer cambios al repositorio simplemente es cuesti n de ejecutar el comando hg pull, indic ndole de qu reposo a e itorio debe jalarlos.
13 N.

del T. Entrante, o cambios entrantes.

22

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

$ hg tip changeset: tag: user: date: summary:

4:2278160e78d4 tip Bryan OSullivan <bos@serpentine.com> Sat Aug 16 22:16:53 2008 +0200 Trim comments.

$ hg pull ../my-hello pulling from ../my-hello searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files (run hg update to get a working copy) $ hg tip changeset: 5:fccff93807a3 tag: tip user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:34 2009 +0000 summary: Added an extra line of output

Como puede verse por las salidas antes-y-despu s de hg tip, hemos jalado exitosamente los cambios en nuestro e repositorio. A n falta un paso para que podamos ver estos cambios en nuestro directorio de trabajo. u

2.8.2.

Actualizar el directorio de trabajo

Hasta ahora hemos pasado por alto la relaci n entre un repositorio y su directorio de trabajo. El comando hg o pull que ejecutamos en la secci n 2.8.1 trajo los cambios al repositorio, pero si revisamos, no hay rastro de esos o cambios en el directorio de trabajo. Esto pasa porque hg pull (por defecto) no modica el directorio de trabajo. En vez de eso, usamos el comando hg update14 para hacerlo.
1 2 3 4 5 6 7

$ grep printf hello.c printf("hello, world!\"); $ hg update tip 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ grep printf hello.c printf("hello, world!\"); printf("hello again!\n"); Puede parecer algo raro que hg pull no actualice el directorio de trabajo autom ticamente. De hecho, hay a una buena raz n para esto: usted puede usar hg update para actualizar el directorio de trabajo al estado en que se o encontraba en cualquier revisi n del historial del repositorio. Si usted hubiera actualizado el directorio de trabajo a una o revisi n anteriordigamos, para buscar el origen de un falloy hubiera corrido un hg pull que hubiera actualizado o el directorio de trabajo autom ticamente a la nueva revisi n, puede que no estuviera particularmente contento. a o Sin embargo, como jalar-y-actualizar es una secuencia de operaciones muy com n, Mercurial le permite combinau rlas al pasar la opci n -u a hg pull. o

hg pull -u
14 N.

del T. Actualizar.

23

Si mira de vuelta la salida de hg pull en la secci n 2.8.1 cuando lo ejecutamos sin la opci n -u, ver que el o o a comando imprimi un amable recordatorio de que tenemos que encargarnos explcitamente de actualizar el directorio o de trabajo:
1

(run hg update to get a working copy) Para averiguar en qu revisi n se encuentra el directorio de trabajo, use el comando hg parents. e o

1 2 3 4 5 6 7

$ hg parents changeset: 5:fccff93807a3 tag: tip user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:34 2009 +0000 summary: Added an extra line of output

Si mira de nuevo la gura 2.1, ver echas conectando cada conjunto de cambios. En cada caso, el nodo del que la a echa sale es un padre, y el nodo al que la echa llega es su hijo. El directorio de trabajo tiene un padre exactamente de la misma manera; ese es el conjunto de cambios que contiene actualmente el directorio de trabajo. Para actualizar el conjunto de trabajo a una revisi n particular, pase un n mero de revisi n o un ID de conjunto de o u o cambios al comando hg update.
1 2 3 4 5 6 7 8 9 10

$ hg update 2 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg parents changeset: 2:fef857204a0c user: Bryan OSullivan <bos@serpentine.com> date: Sat Aug 16 22:05:04 2008 +0200 summary: Introduce a typo into hello.c. $ hg update 2 files updated, 0 files merged, 0 files removed, 0 files unresolved Si no indica explcitamente una revisi n, hg update actualizar hasta la revisi n de punta, como se vio en la segunda o a o llamada a hg update en el ejemplo anterior.

2.8.3.

Empujar cambios a otro repositorio

Mercurial nos permite empujar cambios a otro repositorio, desde el repositorio que estemos usando actualmente. De la misma forma que en el ejemplo de hg pull arriba, crearemos un repositorio temporal para empujar all nue stros cambios.
1 2 3 4

$ cd .. $ hg clone hello hello-push updating working directory 2 files updated, 0 files merged, 0 files removed, 0 files unresolved El comando hg outgoing15 nos dice qu cambios seran empujados en el otro repositorio. e

1 2

$ cd my-hello $ hg outgoing ../hello-push


15 N.

del T. Saliente. Cambios salientes.

24

3 4 5 6 7 8 9 10

comparing with ../hello-push searching for changes changeset: 5:fccff93807a3 tag: tip user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:34 2009 +0000 summary: Added an extra line of output Y el comando hg push se encarga de empujar dichos cambios.

1 2 3 4 5 6 7

$ hg push ../hello-push pushing to ../hello-push searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files Al igual que hg pull, el comando hg push no actualiza el directorio de trabajo del repositorio en el que estamos empujando los cambios. (A diferencia de hg pull, hg push no ofrece la opci n -u para actualizar el directorio o de trabajo del otro repositorio.) Qu pasa si tratamos de jalar o empujar cambios y el repositorio receptor ya tiene esos cambios? Nada emocioe nante.

1 2 3 4

$ hg push ../hello-push pushing to ../hello-push searching for changes no changes found

2.8.4.

Compartir cambios a trav s de una red e

Los comandos que hemos presentando en las pocas secciones anteriores no est n limitados a trabajar con repositoa rios locales. Cada uno de ellos funciona exactamente de la misma manera a trav s de una conexi n de red. Simplemente e o pase una URL en vez de una ruta local.
1 2 3 4 5 6 7 8 9

$ hg outgoing http://hg.serpentine.com/tutorial/hello comparing with http://hg.serpentine.com/tutorial/hello searching for changes changeset: 5:fccff93807a3 tag: tip user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:34 2009 +0000 summary: Added an extra line of output En este ejemplo, podemos ver qu cambios empujaramos al repositorio remoto, aunque, de manera entendible, el e repositorio remoto est congurado para no permitir a usuarios an nimos empujar cambios a el. a o

1 2 3 4

$ hg push http://hg.serpentine.com/tutorial/hello pushing to http://hg.serpentine.com/tutorial/hello searching for changes ssl required

25

Captulo 3

Una gira de Mercurial: fusionar trabajo


Hasta ahora hemos cubierto c mo clonar un repositorio, hacer cambios, y jalar o empujar dichos cambios de un o repositorio a otro. Nuestro siguiente paso es fusionar cambios de repositorios separados.

3.1.

Fusionar lneas de trabajo


Alicia y Roberto tienen cada uno una copia personal del repositorio de un proyecto en el que est n trabajando. a Alicia arregla un fallo en su repositorio; Roberto a ade una nueva caracterstica en el suyo. Ambos desean que n el repositorio compartido contenga el arreglo del fallo y la nueva caracterstica. Frecuentemente trabajo en varias tareas diferentes en un mismo proyecto al mismo tiempo, cada una aislada convenientemente de las otras en su propio repositorio. Trabajar de esta manera signica que a menudo debo fusionar una parte de mi propio trabajo con otra.

Fusionar es una parte fundamental de trabajar con una herramienta de control distribuido de versiones.

Como fusionar es una operaci n tan necesaria y com n, Mercurial la facilita. Revisemos el proceso. Empezaremos o u clonando (otro) repositorio (ve lo seguido que aparecen?) y haciendo un cambio en el.
1 2 3 4 5 6 7

$ cd .. $ hg clone hello my-new-hello updating working directory 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd my-new-hello $ sed -i /printf/i\\tprintf("once more, hello.\\n"); hello.c $ hg commit -m A new hello for a new day. Ahora deberamos tener dos copias de hello.c con contenidos diferentes. El historial de los dos repositorios diverge ahora, como se ilustra en la gura 3.1.

1 2 3 4 5 6 7 8 9

$ cat hello.c /* * Placed in the public domain by Bryan OSullivan. This program is * not covered by patents in the United States or other countries. */ #include <stdio.h> int main(int argc, char **argv) 26

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

{ printf("once more, hello.\n"); printf("hello, world!\"); return 0; } $ cat ../my-hello/hello.c /* * Placed in the public domain by Bryan OSullivan. This program is * not covered by patents in the United States or other countries. */ #include <stdio.h> int main(int argc, char **argv) { printf("hello, world!\"); printf("hello again!\n"); return 0; }

myhello
5: fccf

mynewhello Los cambios ms recientes difieren


5: 05b9

revisin principal (sin hijos)

4: 2278

4: 2278

3: 0272

3: 0272

2: fef8

historia comn

2: fef8

1: 82e5

1: 82e5

0: 0a04

0: 0a04

Figura 3.1: Historial reciente divergente de los repositorios my-hello y my-new-hello Ya sabemos que jalar los cambios desde nuestro repositorio my-hello no tendr efecto en el directorio de trabajo. a
1 2 3 4 5 6 7

$ hg pull ../my-hello pulling from ../my-hello searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files (+1 heads) 27

(run hg heads to see heads, hg merge to merge) Sin embargo, el comando hg pull dice algo acerca de frentes1 .

3.1.1.

Conjuntos de cambios de frentes

Un frente es un cambio que no tiene descendientes, o hijos, como tambi n se les conoce. La revisi n de punta es, e o por tanto, un frente, porque la revisi n m s reciente en un repositorio no tiene ning n hijo. Sin embargo, un repositorio o a u puede contener m s de un frente. a
6: fccf

tip (y principal) principal


5: 05b9

4: 2278

3: 0272

2: fef8

1: 82e5

0: 0a04

Figura 3.2: Contenidos del repositorio despu s de jalar my-hello a my-new-hello e En la gura 3.2 usted puede ver el efecto que tiene jalar los cambios de my-hello a my-new-hello. El historial que ya exista en my-new-hello se mantiene intacto, pero fue a adida una nueva revisi n. Reri ndonos a la gura 3.1, n o e podemos ver que el ID del conjunto de cambios se mantiene igual en el nuevo repositorio, pero el n mero de revisi n u o ha cambiado. (Incidentalmente, este es un buen ejemplo de porqu no es seguro usar n meros de revisi n cuando se e u o habla de conjuntos de cambios). Podemos ver los frentes en un repositorio usando el comando hg heads2 .
1 2 3 4 5 6 7 8 9 10

$ hg heads changeset: tag: parent: user: date: summary: changeset: user:


2 N. 1 N.

6:fccff93807a3 tip 4:2278160e78d4 Bryan OSullivan <bos@serpentine.com> Tue Feb 10 18:23:34 2009 +0000 Added an extra line of output 5:05b9c1e50b3c Bryan OSullivan <bos@serpentine.com>

del T. El autor se reere a heads aqu. del T. Frentes.

28

11 12 13

date: summary:

Tue Feb 10 18:23:36 2009 +0000 A new hello for a new day.

3.1.2.

Hacer la fusi n o

Qu pasa si tratamos de usar el comando usual, hg update, para actualizar el nuevo frente? e
1 2

$ hg update abort: crosses branches (use hg merge or hg update -C) Mercurial nos indica que el comando hg update no har la fusi n; no actualizar el directorio de trabajo cuando a o a considera que lo que deseamos hacer es una fusi n, a menos que lo obliguemos a hacerlo. En vez de hg update, o usamos el comando hg merge para hacer la fusi n entre los dos frentes. o

1 2 3 4

$ hg merge merging hello.c 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, dont forget to commit)

Directorio de trabajo durante la fusin

Repositorio despus de consignar la fusin

fusin

directorio de trabajo durante la fusin


6: fccf

punta 7: 22a5

punta (y frente)

6: fccf

frente

5: 05b9

5: 05b9

4: 2278

4: 2278

Figura 3.3: Directorio de trabajo y repositorio durante la fusi n, y consignaci n consecuente o o Esto actualiza el directorio de trabajo, de tal forma que contenga los cambios de ambos frentes, lo que se ve reejado tanto en la salida de hg parents como en los contenidos de hello.c.
1 2 3 4 5 6 7 8 9

$ hg parents changeset: 5:05b9c1e50b3c user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:36 2009 +0000 summary: A new hello for a new day. changeset: tag: parent: 6:fccff93807a3 tip 4:2278160e78d4 29

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

user: date: summary:

Bryan OSullivan <bos@serpentine.com> Tue Feb 10 18:23:34 2009 +0000 Added an extra line of output

$ cat hello.c /* * Placed in the public domain by Bryan OSullivan. This program is * not covered by patents in the United States or other countries. */ #include <stdio.h> int main(int argc, char **argv) { printf("once more, hello.\n"); printf("hello, world!\"); printf("hello again!\n"); return 0; }

3.1.3.

Consignar los resultados de la fusi n o

Siempre que hacemos una fusi n, hg parents mostrar dos padres hasta que consignemos (hg commit) los o a resultados de la fusi n. o
1

$ hg commit -m Merged changes Ahora tenemos una nueva revisi n de punta; note que tiene los dos frentes anteriores como sus padres. Estos son las o mismas revisiones que mostr previamente el comando hg parents. o

1 2 3 4 5 6 7 8 9

$ hg tip changeset: tag: parent: parent: user: date: summary:

7:22a572779faf tip 5:05b9c1e50b3c 6:fccff93807a3 Bryan OSullivan <bos@serpentine.com> Tue Feb 10 18:23:36 2009 +0000 Merged changes

En la gura 3.3 usted puede apreciar una representaci n de lo que pasa en el directorio de trabajo durante la fusi n o o cuando se hace la consignaci n. Durante la fusi n, el directorio de trabajo tiene dos conjuntos de cambios como sus o o padres, y estos se vuelven los padres del nuevo conjunto de cambios.

3.2.

Fusionar cambios con conictos

La mayora de las fusiones son algo simple, pero a veces usted se encontrar fusionando cambios donde m s de a a uno de ellos afecta las mismas secciones de los mismos cheros. A menos que ambas modicaciones sean id nticas, e el resultado es un conicto, en donde usted debe decidir c mo reconciliar ambos cambios y producir un resultado o coherente.

30

Saludos! Soy Shehu Musa Abacha, sobrina del anterior dictador de Nigeria Sani Abacha. Le contacto en secreto, buscando los medios para desarrollar

Saludos! Soy Alhaji Abba Abacha, hijo del anterior dictador de Nigeria Sani Abacha. Le contacto en secreto, buscando los medios para desarrollar

Nuestros cambios

Sus cambios

Saludos! Soy Mariam Abacha, la esposa del anterior dictador de Nigeria Sani Abacha. Le contacto en secreto, buscando los medios para desarrollar

Versin inicial

Figura 3.4: Cambios con conictos a un documento La gura 3.4 ilustra un ejemplo con dos cambios generando conictos en un documento. Empezamos con una sola versi n del chero; luego hicimos algunos cambios; mientras tanto, alguien m s hizo cambios diferentes en el mismo o a texto. Lo que debemos hacer para resolver el conicto causado por ambos cambios es decidir c mo debe quedar o nalmente el chero. Mercurial no tiene ninguna utilidad integrada para manejar conictos. En vez de eso, ejecuta un programa externo llamado hgmerge. Es un gui n de lnea de comandos que es instalado junto con Mercurial; usted puede modicarlo o para que se comporte como usted lo desee. Por defecto, lo que hace es tratar de encontrar una de varias herramientas para fusionar que es probable que est n instaladas en su sistema. Primero se intenta con unas herramientas para fusionar e cambios autom ticamente; si esto no tiene exito (porque la fusi n demanda una gua humana) o dichas herramientas a o no est n presentes, el gui n intenta con herramientas gr cas para fusionar. a o a Tambi n es posible hacer que Mercurial ejecute otro programa o gui n en vez de hgmerge, deniendo la variable e o de entorno HGMERGE con el nombre del programa de su preferencia.

3.2.1.

Usar una herramienta gr ca para fusi n a o

Mi herramienta favorita para hacer fusiones es kdiff3, y la usar para describir las caractersticas comunes de las e herramientas gr cas para hacer fusiones. Puede ver una captura de pantalla de kdiff3 ejecut ndose, en la gura 3.5. a a El tipo de fusi n que la herramienta hace se conoce como fusi n de tres vas, porque hay tres versiones diferentes del o o chero en que estamos interesados. Debido a esto la herramienta divide la parte superior de la ventana en tres paneles. A la izquierda est la revisi n base del chero, p.ej. la versi n m s reciente de la que descienden las dos a o o a versiones que estamos tratando de fusionar. En la mitad est nuestra versi n del chero, con las modicaciones que hemos hecho. a o A la derecha est la versi n del chero de ellos, la que forma parte del conjunto de cambios que estamos a o tratando de fusionar. En el panel inferior se encuentra el resultado actual de la fusi n. Nuestra tarea es reemplazar todo el texto rojo, que o muestra los conictos sin resolver, con una fusi n adecuada de nuestra versi n del chero y la de ellos. o o Los cuatro paneles est n enlazados; si avanzamos vertical o horizontalmente en cualquiera de ellos, los otros son a actualizados para mostrar las secciones correspondientes del chero que tengan asociado.

31

Figura 3.5: Usando kdiff3 para fusionar versiones de un chero En cada conicto del chero podemos escoger resolverlo usando cualquier combinaci n del texto de la revisi n o o base, la nuestra, o la de ellos. Tambi n podemos editar manualmente el chero en que queda la fusi n, si es necesario e o hacer cambios adicionales. Hay muchas herramientas para fusionar cheros disponibles. Se diferencian en las plataformas para las que est n a disponibles, y en sus fortalezas y debilidades particulares. La mayora est n anadas para fusionar texto plano, mien a tras que otras est n pensadas para formatos de cheros especializados (generalmente XML). a

3.2.2.

Un ejemplo real

En este ejemplo, reproduciremos el historial de modicaciones al chero de la gura 3.4 mostrada anteriormente. Empecemos creando un repositorio con la versi n base de nuestro documento. o
1 2 3 4 5 6 7

$ > > > > $ $

cat > letter.txt <<EOF Greetings! I am Mariam Abacha, the wife of former Nigerian dictator Sani Abacha. EOF hg add letter.txt hg commit -m 419 scam, first draft

Clonaremos el repositorio y haremos un cambio al chero.


1 2 3 4

$ cd .. $ hg clone scam scam-cousin updating working directory 1 files updated, 0 files merged, 0 files removed, 0 files unresolved 32

5 6 7 8 9 10 11

$ $ > > > > $

cd scam-cousin cat > letter.txt <<EOF Greetings! I am Shehu Musa Abacha, cousin to the former Nigerian dictator Sani Abacha. EOF hg commit -m 419 scam, with cousin

Y haremos otro clon, para simular a alguien m s haciendo un cambio al mismo chero. (Esto introduce la idea de a que no es tan inusual hacer fusiones consigo mismo, cuando usted asla tareas en repositorios separados, y de hecho encuentra conictos al hacerlo.)
1 2 3 4 5 6 7 8 9 10 11

$ cd .. $ hg clone scam scam-son updating working directory 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd scam-son $ cat > letter.txt <<EOF > Greetings! > I am Alhaji Abba Abacha, son of the former > Nigerian dictator Sani Abacha. > EOF $ hg commit -m 419 scam, with son Ahora que tenemos dos versiones diferentes de nuestro chero, crearemos un entorno adecuado para hacer la fusi n. o

1 2 3 4 5 6 7 8 9 10 11 12 13 14

$ cd .. $ hg clone scam-cousin scam-merge updating working directory 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd scam-merge $ hg pull -u ../scam-son pulling from ../scam-son searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files (+1 heads) not updating, since new heads added (run hg heads to see heads, hg merge to merge) En este ejemplo, no usar el comando normal de Mercurial para hacer la fusi n (hgmerge), porque lanzara mi linda e o herramienta automatizada para correr ejemplos dentro de una interfaz gr ca de usuario. En vez de eso, denir la a e variable de entorno HGMERGE para indicarle a Mercurial que use el comando merge. Este comando forma parte de la instalaci n base de muchos sistemas Unix y similares. Si usted est ejecutando este ejemplo en su computador, no se o a moleste en denir HGMERGE.

1 2 3 4 5

$ export HGMERGE=merge $ hg merge merging letter.txt merge: warning: conflicts during merge merging letter.txt failed! 33

6 7 8 9 10 11 12 13 14 15 16 17

0 files updated, 0 files merged, 0 files removed, 1 files unresolved There are unresolved merges, you can redo the full merge using: hg update -C 1 hg merge 2 $ cat letter.txt Greetings! <<<<<<< /tmp/tour-merge-conflictsNZwSt/scam-merge/letter.txt I am Shehu Musa Abacha, cousin to the former ======= I am Alhaji Abba Abacha, son of the former >>>>>>> /tmp/letter.txtother.749P-k Nigerian dictator Sani Abacha. Debido a que merge no puede resolver los conictos que aparecen, el deja marcadores de fusi n en el chero con o conictos, indicando si provienen de nuestra versi n o de la de ellos. o Mercurial puede saber por el c digo de salida del comando merge que no fue posible hacer la fusi n exitosao o mente, as que nos indica qu comandos debemos ejecutar si queremos rehacer la fusi n. Esto puede ser util si, por e o ejemplo, estamos ejecutando una herramienta gr ca de fusi n y salimos de ella porque nos confundimos o cometimos a o un error. Si la fusi n autom tica o manual falla, no hay nada que nos impida arreglar los cheros afectados por o a nosotros mismos, y consignar los resultados de nuestra fusi n: o

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

$ cat > letter.txt <<EOF > Greetings! > I am Bryan OSullivan, no relation of the former > Nigerian dictator Sani Abacha. > EOF $ hg resolve -m letter.txt hg: unknown command resolve Mercurial Distributed SCM basic commands: add annotate clone commit diff export init log merge parents pull push remove serve status update add the specified files on the next commit show changeset information per file line make a copy of an existing repository commit the specified files or all outstanding changes diff repository (or selected files) dump the header and diffs for one or more changesets create a new repository in the given directory show revision history of entire repository or files merge working directory with another revision show the parents of the working dir or revision pull changes from the specified source push changes to the specified destination remove the specified files on the next commit export the repository via HTTP show changed files in the working directory update working directory

use "hg help" for the full list of commands or "hg -v" for details $ hg commit -m Send me your money 34

31 32 33 34 35 36 37 38 39

$ hg tip changeset: tag: parent: parent: user: date: summary:

3:e29827f5cf51 tip 1:eac603d73208 2:78b0a9e9cf1b Bryan OSullivan <bos@serpentine.com> Tue Feb 10 18:23:37 2009 +0000 Send me your money

3.3.

Simplicar el ciclo jalar-fusionar-consignar

El proceso de fusionar cambios delineado anteriomente es directo, pero requiere la ejecuci n de tres comandos en o sucesi n. o
1 2 3

hg pull hg merge hg commit -m Fusionados cambios remotos En la consignaci n nal usted debe proveer un mensaje adecuado, que casi siempre es un fragmento de texto de o relleno carente de valor particular. Sera agradable reducir la cantidad de pasos necesarios, si fuera posible. De hecho, Mercurial es distribuido junto con una extensi n llamada fetch3 que hace precisamente esto. o Mercurial cuenta con un mecanismo de extensi n exible que le permite a sus usuarios extender su funcionalidad, o manteniendo el n cleo de Mercurial peque o y f cil de manejar. Algunas extensiones a aden nuevos comandos que u n a n usted puede usar desde la lnea de comandos, mientras que otros funcionan tras bambalinas, por ejemplo, a adiendo n funcionalidad al servidor. La extensi n fetch a ade un comando llamado, no sorpresivamente, hg fetch. Esta extensi n act a como una o n o u combinaci n de hg pull, hg update y hg merge. Empieza jalando cambios de otro repositorio al repositorio o actual. Si encuentra que los cambios a aden un nuevo frente en el repositorio actual, inicia una fusi n, y luego consigna n o el resultado de la misma con un mensaje generado autom ticamente. Si no se a adieron nuevos frentes, actualiza el a n directorio de trabajo con el nuevo conjunto de cambios de punta. Activar la extensi n fetch es f cil. Edite su .hgrc, y vaya a (o cree) la secci n [extensions]. Luego a ada una o a o n lnea que diga simplemente fetch .

1 2

[extensions] fetch = (Normalmente, a la derecha del = debera aparecer la ubicaci n de la extensi n, pero como el comando fetch es o o parte de la distribuci n est ndar, Mercurial sabe d nde buscarla.) o a o

3 N.

del T. Descargar, traer.

35

Captulo 4

Tras bambalinas
A diferencia de varios sistemas de control de revisiones, los conceptos en los que se fundamenta Mercurial son lo sucientemente simples como para entender f cilmente c mo funciona el software. Saber esto no es necesario, pero a o considero util tener un modelo mental de qu es lo que sucede. e Comprender esto me da la conanza de que Mercurial ha sido cuidadosamente dise ado para ser tanto seguro como n eciente. Y tal vez con la misma importancia, si es f cil para m hacerme a una idea adecuada de qu est haciendo el a e a software cuando llevo a cabo una tarea relacionada con control de revisiones, es menos probable que me sosprenda su comportamiento. En este captulo, cubriremos inicialmente los conceptos centrales del dise o de Mercurial, y luego discutiremos n algunos detalles interesantes de su implementaci n. o

4.1.
4.1.1.

Registro del historial de Mercurial


Seguir el historial de un unico chero

Cuando Mercurial sigue las modicaciones a un chero, guarda el historial de dicho chero en un objeto de metadatos llamado lelog1 . Cada entrada en el chero de registro contiene suciente informaci n para reconstruir una o revisi n del chero que se est siguiendo. Los cheros de registro son almacenados como cheros el el directorio o a .hg/store/data. Un chero de registro contiene dos tipos de informaci n: datos de revisiones, y un ndice para o ayudar a Mercurial a buscar revisiones ecientemente. El chero de registro de un chero grande, o con un historial muy largo, es guardado como cheros separados para datos (sujo .d) y para el ndice (sujo .i). Para cheros peque os con un historial peque o, los datos de n n revisiones y el ndice son combinados en un unico chero .i. La correspondencia entre un chero en el directorio de trabajo y el chero de registro que hace seguimiento a su historial en el repositorio se ilustra en la gura 4.1.

4.1.2.

Administraci n de cheros monitoreados o

Mercurial usa una estructura llamada maniesto para centralizar la informaci n que maneja acerca de los cheros o que monitorea. Cada entrada en el maniesto contiene informaci n acerca de los cheros involucrados en un unico o conjunto de cambios. Una entrada registra qu cheros est n presentes en el conjunto de cambios, la revisi n de cada e a o chero, y otros cuantos metadatos del mismo.

4.1.3.

Registro de informaci n del conjunto de cambios o

La bit cora de cambios contiene informaci n acerca de cada conjunto de cambios. Cada revisi n indica qui n a o o e consign un cambio, el comentario para el conjunto de cambios, otros datos relacionados con el conjunto de cambios, o y la revisi n del maniesto a usar. o
1 N.

del T. Fichero de registro

36

Directorio de trabajo

Repositorio .hg/store/data/README.i

README

src/hello.c

.hg/store/data/src/hello.c.d .hg/store/data/src/hello.c.i

Figura 4.1: Relaci n entre cheros en el directorio de trabajo y cheros de registro en el repositorio o

4.1.4.

Relaciones entre revisiones

Dentro de una bit cora de cambios, un maniesto, o un chero de registro, cada revisi n conserva un apuntador a o a su padre inmediato (o sus dos padres, si es la revisi n de una fusi n). Como mencio e anteriormente, tambi n hay o o n e relaciones entre revisiones a trav s de estas estructuras, y tienen naturaleza jer rquica. e a Por cada conjunto de cambios en un repositorio, hay exactamente una revisi n almacenada en la bit cora de o a cambios. Cada revisi n de la bit cora de cambios contiene un apuntador a una unica revisi n del maniesto. Una o a o revisi n del maniesto almacena un apuntador a una unica revisi n de cada chero de registro al que se le haca o o seguimiento cuando fue creado el conjunto de cambios. Estas relaciones se ilustran en la gura 4.2.
Bitcora de cambios

Manifiesto

Bitcora de archivos

Figura 4.2: Relaciones entre metadatos Como lo muestra la gura, no hay una relaci n uno a uno entre las revisiones en el conjunto de cambios, el o maniesto, o el chero de registro. Si el maniesto no ha sido modicado de un conjunto de cambios a otro, las entradas en la bit cora de cambios para esos conjuntos de cambios apuntar n a la misma revisi n del maniesto. Si a a o un chero monitoreado por Mercurial no sufre ning n cambio de un conjunto de cambios a otro, la entrada para dicho u chero en las dos revisiones del maniesto apuntar a la misma revisi n de su chero de registro. a o 37

4.2.

Almacenamiento seguro y eciente

La base com n de las bit coras de cambios, los maniestos, y los cheros de registros es provista por una unica u a estructura llamada el revlog2 .

4.2.1.

Almacenamiento eciente

El revlog provee almacenamiento eciente de revisiones por medio del mecanismo de deltas3 . En vez de almacenar una copia completa del chero por cada revisi n, almacena los cambios necesarios para transformar una revisi n o o anterior en la nueva revisi n. Para muchos tipos de chero, estos deltas son tpicamente de una fracci n porcentual del o o tama o de una copia completa del chero. n Algunos sistemas de control de revisiones obsoletos s lo pueden manipular deltas de cheros de texto plano. Ellos o o bien almacenan los cheros binarios como instant neas completas, o codicados en alguna representaci n de texto a o plano adecuada, y ambas alternativas son enfoques que desperdician bastantes recursos. Mercurial puede manejar deltas de cheros con contenido binario arbitrario; no necesita tratar el texto plano como un caso especial.

4.2.2.

Operaci n segura o

Mercurial s lo a ade datos al nal de los cheros de revlog. Nunca modica ninguna secci n de un chero una o n o vez ha sido escrita. Esto es m s robusto y eciente que otros esquemas que requieren modicar o reescribir datos. a Adicionalmente, Mercurial trata cada escritura como parte de una transacci n, que puede cubrir varios cheros. o Una transacci n es at mica: o bien la transacci n tiene exito y entonces todos sus efectos son visibles para todos o o o los lectores, o la operaci n completa es cancelada. Esta garanta de atomicidad implica que, si usted est ejecutando o a dos copias de Mercurial, donde una de ellas est leyendo datos y la otra los est escribiendo, el lector nunca ver un a a a resultado escrito parcialmente que podra confundirlo. El hecho de que Mercurial s lo hace adiciones a los cheros hace m s f cil proveer esta garanta transaccional. A o a a medida que sea m s f cil hacer operaciones como esta, m s conanza tendr usted en que sean hechas correctamente. a a a a

4.2.3.

Recuperaci n r pida de datos o a

Mercurial evita ingeniosamente un problema com n a todos los sistemas de control de revisiones anteriores u el problema de la recuperaci n4 ineciente de datos. Muchos sistemas de control de revisiones almacenan los cono tenidos de una revisi n como una serie incremental de modicaciones a una instant nea. Para reconstruir una versi n o a o cualquiera, primero usted debe leer la instant nea, y luego cada una de las revisiones entre la instant nea y su versi n a a o objetivo. Entre m s largo sea el historial de un chero, m s revisiones deben ser ledas, y por tanto toma m s tiempo a a a reconstruir una versi n particular. o La innovaci n que aplica Mercurial a este problema es simple pero efectiva. Una vez la cantidad de informaci n de o o deltas acumulada desde la ultima instant nea excede un umbral jado de antemano, se almacena una nueva instant nea a a (comprimida, por supuesto), en lugar de otro delta. Esto hace posible reconstruir cualquier versi n de un chero o r pidamente. Este enfoque funciona tan bien que desde entonces ha sido copiado por otros sistemas de control de a revisiones. La gura 4.3 ilustra la idea. En una entrada en el chero ndice de un revlog, Mercurial almacena el rango de entradas (deltas) del chero de datos que se deben leer para reconstruir una revisi n en particular. o Nota al margen: la inuencia de la compresi n de vdeo o Si le es familiar la compresi n de vdeo, o ha mirado alguna vez una emisi n de TV a trav s de cable digital o o e o un servicio de sat lite, puede que sepa que la mayor parte de los esquemas de compresi n de vdeo almacenan e o
del T. Contracci n de revision log, registro de revisi n. o o del T. Diferencias. 4 N. del T. Retrieval. Recuperaci n en el sentido de traer los datos, o reconstruirlos a partir de otros datos, pero no debido a una falla o calamidad, o sino a la operaci n normal del sistema. o
3 N. 2 N.

38

ndice de bitcora de revisiones (archivo .i) Datos de Bitacora de revisiones (archivo .d)

Delta, rev 2 a 3 ndice, rev 7 Snapshot, rev 4

Delta, rev 4 a 5 Delta, rev 5 a 6 Delta, rev 6 a 7

Figura 4.3: Instant nea de un revlog, con deltas incrementales a cada cuadro del mismo como un delta contra el cuadro predecesor. Adicionalmente, estos esquemas usan t cnicas de e compresi n con p rdida para aumentar la tasa de compresi n, por lo que los errores visuales se acumulan a lo largo o e o de una cantidad de deltas inter-cuadros. Ya que existe la posibilidad de que un ujo de vdeo se pierda ocasionalmente debido a fallas en la se al, y n para limitar la acumulaci n de errores introducida por la compresi n con p rdidas, los codicadores de vdeo insertan o o e peri dicamente un cuadro completo (tambi n llamado cuadro clave) en el ujo de vdeo; el siguiente delta es geno e erado con respecto a dicho cuadro. Esto quiere decir que si la se al de vdeo se interrumpe, se reanudar una vez se n a reciba el siguiente cuadro clave. Adem s, la acumulaci n de errores de codicaci n se reinicia con cada cuadro clave. a o o

4.2.4.

Identicaci n e integridad fuerte o

Adem s de la informaci n de deltas e instant neas, una entrada en un revlog contiene un hash criptogr co de a o a a los datos que representa. Esto hace difcil falsicar el contenido de una revisi n, y hace f cil detectar una corrupci n o a o accidental. Los hashes proveen m s que una simple revisi n de corrupci n: son usados como los identicadores para las a o o revisiones. Los hashes de identicaci n de conjuntos de cambios que usted ve como usuario nal son de las revisiones o de la bit cora de cambios. Aunque los cheros de registro y el maniesto tambi n usan hashes, Mercurial s lo los usa a e o tras bambalinas. Mercurial verica que los hashes sean correctos cuando recupera revisiones de cheros y cuando jala cambios desde otro repositorio. Si se encuentra un problema de integridad, Mercurial se quejar y detendr cualquier operaci n a a o que est haciendo. e Adem s del efecto que tiene en la eciencia en la recuperaci n, el uso peri dico de instant neas de Mercurial lo a o o a hace m s robusto frente a la corrupci n parcial de datos. Si un chero de registro se corrompe parcialmente debido a a o un error de hardware o del sistema, a menudo es posible reconstruir algunas o la mayora de las revisiones a partir de las secciones no corrompidas del chero de registro, tanto antes como despu s de la secci n corrompida. Esto no sera e o posible con un sistema de almacenamiento basado unicamente en deltas.

39

4.3.

Historial de revisiones, ramas y fusiones

Cada entrada en el revlog de Mercurial conoce la identidad de la revisi n de su ancestro inmediato, al que se conoce o usualmente como su padre. De hecho, una revisi n contiene sitio no s lo para un padre, sino para dos. Mercurial usa o o un hash especial, llamado el ID nulo, para representar la idea de no hay padre aqu. Este hash es simplemente una cadena de ceros. En la gura 4.4 usted puede ver un ejemplo de la estructura conceptual de un revlog. Los cheros de registro, maniestos, y bit coras de cambios comparten la misma estructura; s lo dieren en el tipo de datos almacenados en a o cada delta o instant nea. a La primera revisi n en un revlog (al nal de la imagen) tiene como padre al ID nulo, en las dos ranuras disponibles o para padres. En una revisi n normal, la primera ranura para padres contiene el ID de la revisi n padre, y la segunda o o contiene el ID nulo, se alando as que la revisi n s lo tiene un padre real. Un par de revisiones que tenga el mismo ID n o o padre son ramas. Una revisi n que representa una fusi n entre ramas tiene dos IDs de revisi n normales en sus ranuras o o o para padres.

4.4.

El directorio de trabajo

En el directorio de trabajo, Mercurial almacena una instant nea de los cheros del repositorio como si fueran los a de un conjunto de cambios particular. El directorio de trabajo sabe qu conjunto de cambios contiene. Cuando usted actualiza el directorio de trabae jo para que contenga un conjunto de cambios particular, Mercurial busca la revisi n adecuada del maniesto para o averiguar qu cheros estaba monitoreando cuando se hizo la consignaci n del conjunto de cambios, y qu revisi n e o e o de cada chero era la actual en ese momento. Luego de eso, recrea una copia de cada uno de esos cheros, con los mismos contenidos que tenan cuando fue consignado el conjunto de cambios. El estado de directorio5 contiene el conocimiento de Mercurial acerca del directorio de trabajo. All se detalla a qu conjunto de cambios es actualizado el directorio de trabajo, y todos los cheros que Mercurial est monitoreando e a en este directorio. Tal como la revisi n de un revlog tiene espacio para dos padres, para que pueda representar tanto una revisi n o o normal (con un solo padre) o una fusi n de dos revisiones anteriores, el estado de directorio tiene espacio para dos o padres. Cuando usted usa el comando hg update, el conjunto de cambios al que usted se actualiza es almacenado en la casilla destinada al primer padre, y un ID nulo es almacenado en la segunda. Cuando usted hace una fusi n o (hg merge) con otro conjunto de cambios, la casilla para el primer padre permanece sin cambios, y la casilla para el segundo es actualizada con el conjunto de cambios con el que usted acaba de hacer la fusi n. El comando hg o parents le indica cu les son los padres del estado de directorio. a

4.4.1.

Qu pasa en una consignaci n e o

El estado de directorio almacena informaci n sobre los padres para algo m s que mero registro. Mercurial usa los o a padres del estado de directorio como los padres de un nuevo conjunto de cambios cuando usted hace una consignaci n. o La gura 4.5 muestra el estado normal del directorio de trabajo, que tiene un unico conjunto de cambios como padre. Dicho conjunto de cambios es la punta, el conjunto de cambios m s reciente en el repositorio que no tiene a hijos. Es util pensar en el directorio de trabajo como en el conjunto de cambios que estoy a punto de enviar. Cualquier chero que usted le diga a Mercurial que fue a adido, borrado, renombrado o copiado, se ver reejado en ese conjunto n a de cambios, como tambi n se ver n las modicaciones a cualquiera de los cheros que Mercurial ya est monitoreane a e do; el nuevo conjunto de cambios dentr los padres del directorio de trabajo como propios. a Luego de una consignaci n, Mercurial actualizar los padres del directorio de trabajo, de tal manera que el primer o a padre sea el ID del nuevo conjunto de cambios, y el segundo sea el ID nulo. Esto puede verse en la gura 4.6. Mercurial no toca ninguno de los cheros del directorio de trabajo cuando usted hace la consignaci n; s lo modica el estado de o o directorio para anotar sus nuevos padres.
5 N.

del T. dirstate, en ingl s en el original. e

40

4.4.2.

Creaci n de un nuevo frente o

Es perfectamente normal actualizar el directorio de trabajo a un conjunto de cambios diferente a la punta actual. Por ejemplo, usted podra desear saber en qu estado se encontraba su proyecto el martes pasado, o podra estar buscando e en todos los conjuntos de cambios para saber cu ndo se introdujo un fallo. En casos como estos, la acci n natural a o es actualizar el directorio de trabajo al conjunto de cambios de su inter s, y examinar directamente los cheros en el e directorio de trabajo para ver sus contenidos tal como estaban en el momento de hacer la consignaci n. El efecto que o tiene esto se muestra en la gura 4.7. Una vez se ha actualizado el directorio de trabajo a un conjunto de cambios anterior, qu pasa si se hacen cambios, e y luego se hace una consignaci n? Mercurial se comporta en la misma forma que describ anteriormente. Los padres o del directorio de trabajo se convierten en los padres del nuevo conjunto de cambios. Este nuevo conjunto de cambios no tiene hijos, as que se convierte en la nueva punta. Y el repositorio tiene ahora dos conjuntos de cambios que no tienen hijos; a estos los llamamos frentes. Usted puede apreciar la estructura que esto crea en la gura 4.8. Nota: Si usted es nuevo en Mercurial, debera tener en mente un error com n, u que es usar el comando hg pull sin ninguna opci n. Por defecto, el comando o hg pull no actualiza el directorio de trabajo, as que usted termina trayendo nuevos conjuntos de cambios a su repositorio, pero el directorio de trabajo sigue usando el mismo conjunto de cambios que tena antes de jalar. Si usted hace al gunos cambios, y luego hace una consignaci n, estar creando un nuevo frente, o a porque su directorio de trabajo no es sincronizado a cualquiera que sea la nueva punta. Pongo la palabra error en comillas porque todo lo que usted debe hacer para recticar la situaci n es hacer una fusi n (hg merge), y luego una consignaci n o o o (hg commit). En otras palabras, esto casi nunca tiene consecuencias negativas; s lo sorprende a la gente. Discutir otras formas de evitar este comportamiento, o e y porqu Mercurial se comporta de esta forma, inicialmente sorprendente, m s e a adelante.

4.4.3.

Fusi n de frentes o

Cuando usted ejecuta el comando hg merge, Mercurial deja el primer padre del directorio de trabajo intacto, y escribe como segundo padre el conjunto de cambios contra el cual usted est haciendo la fusi n, como se muestra en a o la gura 4.9. Mercurial tambi n debe modicar el directorio de trabajo, para fusionar los cheros que el monitorea en los dos e conjuntos de cambios. Con algunas simplicaciones, el proceso es el siguiente, por cada chero en los maniestos de ambos conjuntos de cambios. Si ning n conjunto de cambios ha modicado un chero, no se hace nada con el mismo. u Si un conjunto de cambios ha modicado un chero, y el otro no lo ha hecho, se crea una copia del chero con las modicaciones pertinentes en el directorio de trabajo. Si un conjunto de cambios borra un chero, y el otro no lo ha hecho (o tambi n lo borr ), se borra dicho chero e o del directorio de trabajo. Si un conjunto de cambios ha borrado un chero, pero el otro lo ha modicado, se le pregunta al usuario qu hacer: conservar el chero modicado, o borrarlo? e Si ambos conjuntos de cambios han modicado un chero, se invoca el programa externo de fusi n para denir o el nuevo contenido del chero fusionado. Esto puede requerir interacci n directa de parte del usuario. o Si un conjunto de cambios ha modicado un chero, y el otro ha renombrado o copiado el mismo, asegurarse de que los cambios sigan al nuevo nombre de chero.

41

Hay m s detalleshacer una fusi n tiene una gran cantidad de casos especialespero estas son las elecciones m s a o a comunes que se ven involucradas en una fusi n. Como usted puede ver, muchos de los casos son completamente o autom ticos, y de hecho la mayora de las fusiones terminan autom ticamente, sin requerir la interacci n del usuario a a o para resolver ning n conicto. u Cuando considere qu pasa cuando usted hace una consignaci n despu s de una fusi n, de nuevo el directorio e o e o de trabajo es el conjunto de cambios que estoy a punto de consignar. Una vez termina su trabajo el comando hg merge, el directorio de trabajo tiene dos padre; estos se convertir n en los padres del nuevo conjunto de cambios. a Mercurial le permite hacer m ltiples fusiones, pero usted debe consignar los resultados de cada fusi n sucesiu o vamente. Esto es necesario porque Mercurial s lo monitorea dos padres, tanto para las revisiones como para los o directorios de trabajo. Aunque t cnicamente es posible fusionar varios conjuntos de trabajo en una sola operaci n, la e o posibilidad de confundir al usuario y crear un desorden terrible en la fusi n se hace incontenible de inmediato. o

4.5.

Otras caractersticas de diseno interesantes

En las secciones anteriores, he tratado de resaltar algunos de los aspectos m s importantes del dise o de Mercurial, a n para mostrar que se presta gran cuidado y atenci n a la conabilidad y el desempe o. Sin embargo, la atenci n a o n o los detalles no para ah. Hay una cantidad de aspectos de la construcci n de Mercurial que encuentro interesantes o personalmente. Detallar unos cuantos de ellos aqu, aparte de los elementos importantes de arriba, para que, si e usted est interesado, pueda obetener una idea mejor de la cantidad de esfuerzo mental invertido en el dise o de un a n sistema bien dise ado. n

4.5.1.

Compresi n ingeniosa o

Cuando es adecuado, Mercurial almacenar tanto las instant neas como los deltas en formato comprimido. Lo hace a a tratando siempre de comprimir una instant nea o delta, y conservando la versi n comprimida s lo si es m s peque a a o o a n que la versi n sin compresi n. o o Esto implica que Mercurial hace lo correcto cuando almacena un chero cuyo formato original est comprimido, a como un chero zip o una imagen JPEG. Cuando estos tipos de cheros son comprimidos por segunda vez, el chero resultante usualmente es m s grande que la versi n comprimida una sola vez, por lo que Mercurial almacenar el a o a chero zip o JPEG original. Los deltas entre revisiones de un chero comprimido usualmente son m s grandes que las instant neas del mismo a a chero, y Mercurial de nuevo hace lo correcto en estos casos. El encuentra que dicho delta excede el umbral respecto al cual se debera almacenar una instant nea completa del chero, as que almacena la instant nea, ahorrando espacio a a de nuevo respecto al enfoque simplista de usar unicamente deltas. Recompresi n de red o Cuando almacena las revisiones en disco, Mercurial usa el algoritmo de compresi n deaci n (el mismo usado o o en el popular formato de chero zip), que provee una buena velocidad con una tasa de compresi n respetable. Sin o embargo, cuando se transmiten datos de revisiones a trav s de una conexi n de red, Mercurial descomprime los datos e o comprimidos de las revisiones. Si la conexi n es hecha a trav s de HTTP, Mercurial recomprime el ujo completo de datos usando un algoritmo de o e compresi n que brinda una mejor tasa de compresi n (el algoritmo Burrows-Wheeler del ampliamente usado paquete o o de compresi n bzip2). Esta combinaci n de algoritmo y compresi n del ujo completo de datos (en vez de una o o o revisi n a la vez) reduce sustancialmente la cantidad de bytes a transferir, brindando as un mejor desempe o de red o n sobre casi todo tipo de redes. (Si la conexi n se hace sobre ssh, Mercurial no recomprmime el ujo, porque ssh puede hacer esto por s mismo.) o

4.5.2.

Reordenado de lectura/escritura y atomicidad

A adir datos al nal de un chero no es todo lo que hace falta para garantizar que un lector no ver una escritura n a parcial. Si recuerda la gura 4.2, las revisiones en la bit cora de cambios apuntan a revisiones en el maniesto, y las a 42

revisiones en el maniesto apuntan a revisiones en cheros de registro. Esta jerarqua es deliberada. Un escritor inicia una transacci n al escribir los datos del cheros del chero de registro y el maniesto, y no o escribe nada en la bit cora de cambios hasta que dichas escrituras hayan terminado. Un lector empieza leyendo datos a de la bit cora de cambios, luego del maniesto, y nalmente del chero de registro. a Como el escritor siempre termina de escribir los datos en el chero de registro y en el maniesto antes de escribir a la bit cora de cambios, un lector nunca ver un apuntador a una versi n parcialmente escrita de revisiones del a a o maniesto desde la bit cora de cambios, y nunca leer un apuntador a una revisi n parcialmente escrita del chero de a a o registro desde el maniesto.

4.5.3.

Acceso concurrente

El reordenado de lectura/escritura y la atomicidad garantizan que Mercurial nunca necesita bloquear un repositorio cuando est leyendo datos, a n si se est escribiendo al repositorio mientras se hace la lectura. Esto tiene un gran a u a efecto en la escalabilidad; usted puede tener cualquier cantidad de procesos Mercurial leyendo datos de un repositorio de manera segura al mismo tiempo, sin importar si se est escribiendo al mismo o no. a La naturaleza carente de bloqueos de la lectura signica que si usted est compartiendo un repositorio en un a sistema multiusuario, no necesita dar a los usuarios locales permisos de escritura a su repositorio para que ellos puedan clonarlo o jalar cambios; s lo necesitan permisos de lectura. (Esta no es una caracterstica com n entre los o u sistemas de control de revisiones, as que no la d por hecha! Muchos de ellos requieren que los lectores sean capaces e de bloquear el repositorio antes de poder leerlo, y esto requiere acceso de escritura en al menos un directorio, lo que por supuesto se convierte en una fuente de todo tipo de problemas administrativos y de seguridad bastante molestos.) Mercurial usar bloqueos para asegurarse de que s lo un proceso pueda escribir a un repositorio al mismo tiempo o (el mecanismo de bloqueo es seguro incluso sobre sistemas de cheros notoriamente hostiles al bloqueo, como NFS). Si un repositorio est bloqueado, los escritores esperar n un buen rato para revisar si el repositorio ya ha sido desbloa a queado, pero si el repositorio sique bloqueado por mucho tiempo, el proceso que intenta escribir fallar por tiempo de a espera m ximo. Esto signica que sus guiones autom ticos diarios no se quedar n esperando para siempre, apil ndose a a a a si el sistema se cay sin que nadie se diera cuenta, por ejemplo. (S, el tiempo de espera m ximo es congurable, de o a cero a innito). Acceso seguro al estado de directorio Al igual que con los datos de revisi n, Mercurial no requiere un bloqueo para leer el chero de estado de directorio; o s se usa un bloqueo para escribir a el. Para evitar la posibilidad de leer una copia parcialmente escrita del chero de estado de directorio, Mercurial escribe a un chero con un nombre unico en el mismo directorio del chero de estado de directorio, y luego renombra at micamente este chero temporal a dirstate6 . As se garantiza que el chero o llamado dirstate est completo, y no parcialmente escrito. e

4.5.4.

Evitar movimientos de brazo

Un aspecto crtico para el desempe o de Mercurial es evitar los movimientos del brazo de lectura del disco duro, ya n que cualquier movimiento de brazo es mucho m s costoso que incluso una operaci n de lectura relativamente grande. a o Es por esto que, por ejemplo, el estado de directorio es almacenado como un solo chero. Si hubiera un estado de directorio por cada directorio que Mercurial monitorea, el disco hara un movimiento de brazo por cada directorio. En cambio, Mercurial lee el estado de directorio completo en un solo paso. Mercurial tambi n usa un esquema de copiar al escribir cuando clona un repositorio en un mismo medio de e almacenamiento local. En vez de copiar cada chero de revlog del repositorio viejo al nuevo, se crea un enlace duro, que es una manera sucinta de decir estos dos nombres apuntan al mismo chero. Cuando Mercurial est a punto de a escribir a uno de los cheros de revlog, revisa si la cantidad de nombres apuntando al chero es de m s de uno. Si lo a es, m s de un repositorio est usando el chero, as que Mercurial hace una nueva copia del chero, privada para este a a repositorio.
6 N.

del T. Estado de directorio.

43

Algunos desarrolladores de control de revisiones han indicado que la idea de hacer una copia privada completa de un chero no es eciente desde el punto de vista de almacenamiento. Aunque esto es cierto, el almacenamiento es barato, y este m todo brinda el m ximo rendimiento al tiempo que delega la mayor parte del trabajo de manejo de e a cheros al sistema operativo. Un esquema alternativo seguramente reducira el desempe o y aumentara la complejidad n del software, cada uno de los cuales es mucho m s importante para la sensaci n que se tiene del software en el trabajo a o da a da.

4.5.5.

Otros contenidos del estado de directorio

Debido a que Mercurial no lo fuerza a indicar si usted est modicando un chero, se usa el estado de directorio a para almacenar informaci n extra para poder determinar efecientemente si usted ha modicado un chero. Por cada o chero en el directorio de trabajo, se almacena el momento en que Mercurial modic por ultima vez el chero, y el o tama o del chero en ese momento. n Cuando usted a ade (hg add), remueve (hg remove), renombra (hg rename) o copia (hg copy) cheros, n Mercurial actualiza el estado de directorio para saber qu hacer con dichos cheros cuando usted haga la consignaci n. e o Cuando Mercurial est revisando el estado de los cheros en el directorio de trabajo, revisa primero la fecha de a modicaci n del chero. Si no ha cambiado, el chero no ha sido modicado. Si el tama o del chero ha cambiado, o n el chero ha sido modicado. S lo en el caso en que el tiempo de modicaci n ha cambiado, pero el tama o no, es o o n necesario leer el contenido del chero para revisar si ha cambiado. Almacenar estos pocos datos reduce dram ticaa mente la cantidad de datos que Mercurial debe leer, lo que brinda una mejora en el rendimiento grande, comparado con otros sistemas de control de revisiones.

44

Hash de revisin 1b67dc96f27a

Revisin principal (sin hijos)

Datos de revisin (delta o snapshot) ...

Primer padre 34b8b7a15ea1

Segundo padre 000000000000

Hash de revisin 34b8b7a15ea1

Revisin de fusin (dos padres)

Datos de Revisin (delta o snapshot) ...

Primer padre 5b80c922ebdd

Segundo padre 32bf9a5f22c0

Hash de revisin 5b80c922ebdd Datos de revisin (delta o snapshot) ...

Hash de revisin 32bf9a5f22c0 Datos de revisin (delta o snapshot) ...

Primer padre ff9dc8bc2a8b

Segundo padre 000000000000

Primer padre ecacb6b4c9fd

Segundo padre 000000000000

Hash de revisin ecacb6b4c9fd Datos de revisin (delta o snapshot) ...

Ramas (dos revisiones, mismo padre)


Hash de revisin ff9dc8bc2a8b

Primer padre ff9dc8bc2a8b

Segundo padre 000000000000

Primera revisin (ambos padres nulos)

Datos de revisin (delta o snapshot) ...

Primer padre 000000000000

Segundo padre 000000000000

Figura 4.4:

45

Historia en el repositorio

Padres del directorio de trabajo Primer padre

e7639888bb2f e7639888bb2f 7b064d8bac5e

Segundo padre 000000000000

000000000000

Figura 4.5: El directorio de trabajo puede tener dos padres

Historia en el repositorio

Padres del directorio de trabajo Primer padre

Nuevo conjunto de cambios

dfbbb33f3fa3 dfbbb33f3fa3 e7639888bb2f Segundo padre 7b064d8bac5e 000000000000

000000000000

Figura 4.6: El directorio de trabajo obtiene nuevos padres luego de una consignaci n o

46

Historia en el repositorio

Padres del directorio de trabajo Primer padre

e7639888bb2f 7b064d8bac5e 7b064d8bac5e

Segundo padre 000000000000

000000000000

Figura 4.7: El directorio de trabajo, actualizado a un conjunto de cambios anterior

Cabeza Preexistente

Cabeza recin creada (y tip)

Padres del directorio de trabajo Primer padre

e7639888bb2f

ffb20e1701ea ffb20e1701ea

7b064d8bac5e

Segundo padre 000000000000

000000000000

Figura 4.8: Despu s de una consignaci n hecha mientras se usaba un conjunto de cambios anterior e o

47

Cabeza preexistente

Cabeza recin creada(y tip)

Padres del directorio de trabajo Primer padre (sin cambio)

e7639888bb2f

ffb20e1701ea ffb20e1701ea

7b064d8bac5e

Segundo padre e7639888bb2f

000000000000

Figura 4.9: Fusi n de dos frentes o

48

Captulo 5

Mercurial da a da
5.1. C mo indicarle a Mercurial qu cheros seguir o e

Mercurial no trabaja con cheros en su repositorio a menos que usted se lo indique explcitamente. La orden hg status le mostrar cu les cheros son desconocidos para Mercurial; se emplea un ? para mostrar tales cheros. a a Para indicarle a Mercurial que tenga en cuenta un chero, emplee la orden hg add. Una vez que haya adicionado el chero, la lnea referente al chero al aplicar la orden hg status para tal chero cambia de ? a A.
1 2 3 4 5 6 7 8 9 10

$ $ $ $ ? $ $ A $ $

hg init add-example cd add-example echo a > a hg status a hg add a hg status a hg commit -m Added one file hg status

Despu s de invocar hg commit, los cheros que haya adicionado antes de consignar no se listar n en la salida e a de hg status. La raz n para esto es que hg status solamente le muestra aquellos cheros interesantes o los que usted haya modicado o a aquellos sobre los que usted haya indicado a Mercurial hacer algo de forma predeterminada. Si tiene un repositorio que contiene miles de cheros, rara vez desear saber cu les de ellos est n a a a siendo seguidos por Mercurial, pero que no han cambiado. (De todas maneras, puede obtener tal informaci n; m s o a adelante hablaremos de ello.) Cuando usted a ade un chero, Mercurial no hace nada con el inmediatamente. En cambio, tomar una instant nea n a a del estado del chero la pr xima vez que usted consigne. Continuar haciendo seguimiento a los cambios que haga o a sobre el chero cada vez que consigne, hasta que usted lo elimine.

5.1.1.

Nombramiento explcito e implcito de cheros

Mercurial tiene un comportamiento util en el cual si a una orden, le pasa el nombre de un directorio, todas las ordenes lo interpretar n como Deseo operar en cada chero de este directorio y sus subdirectorios. a
1 2 3 4

$ $ $ $

mkdir b echo b > b/b echo c > b/c mkdir b/d 49

5 6 7 8 9 10

$ echo d > b/d/d $ hg add b adding b/b adding b/c adding b/d/d $ hg commit -m Added all files in subdirectory Tenga en cuenta que en este ejemplo Mercurial imprimi los nombres de los cheros que se adicionaron, mientras que o no lo hizo en el ejemplo anterior cuando adicionamos el chero con nombre a. En el ultimo caso hicimos explcito el nombre del chero que dese bamos adicionar en la lnea de ordenes, y a Mercurial asume en tales casos que usted sabe lo que est haciendo y no imprime informaci n alguna. a o Cuando hacemos implcitos los nombres de los cheros dando el nombre de un directorio, Mercurial efect a el u paso extra de imprimir el nombre de cada chero con el que va a hacer algo. Esto para aclarar lo que est sucediendo, a y reducir en lo posible una sorpresa silenciosa pero fatal. Este comportamiento es com n a la mayora de ordenes en u Mercurial.

5.1.2.

Nota al margen: Mercurial trata cheros, no directorios

Mercurial no da seguimiento a la informaci n de los directorios. En lugar de eso tiene en cuenta las rutas de o los cheros. Antes de crear un chero, primero crea todos los directorios que hagan falta para completar la ruta del mismo. Despu s de borrar un chero, borra todos los directorios vacos que estuvieran en la ruta del chero borrado. e Suena como una diferencia trivial, pero tiene una consecuencia pr ctica menor: no es posible representar un directorio a completamente vaco en Mercurial. Los directorios vacos rara vez son utiles, y hay soluciones alternativas no intrusivas que usted puede emplear para obtener el efecto apropiado. Los desarrolladores de Mercurial pensaron que la complejidad necesaria para administrar directorios vacos no vala la pena frente al benecio limitado que esta caracterstica podra traer. Si necesita un directorio vaco en su repositorio, hay algunas formas de lograrlo. Una es crear un directorio, despu s hacer hg add a un chero oculto dentro de ese directorio. En sistemas tipo Unix, cualquier chero cuyo e nombre comience con un punto (.) es tratado como oculto por la mayora de comandos y herramientas GUI. Esta aproximaci n se ilustra en la gura 5.1. o
1 2 3 4 5 6 7 8 9 10 11 12 13 14

$ hg init hidden-example $ cd hidden-example $ mkdir empty $ touch empty/.hidden $ hg add empty/.hidden $ hg commit -m Manage an empty-looking directory $ ls empty $ cd .. $ hg clone hidden-example tmp updating working directory 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ ls tmp empty $ ls tmp/empty

Figura 5.1: Simular un directorio vaco con un chero oculto Otra forma de abordar la necesidad de un directorio vaco es simplemente crear uno en sus guiones de construcci n o antes de que lo necesiten. 50

5.2.

C mo dejar de hacer seguimiento a un chero o

Si decide que un chero no pertenece a su repositorio, use la orden hg remove; se borrar el chero y le a indicar a Mercurial que deje de hacerle seguimiento. Los cheros eliminados se representan con R al usar hg a status.
1 2 3 4 5 6 7 8 9 10 11 12 13

$ hg init remove-example $ cd remove-example $ echo a > a $ mkdir b $ echo b > b/b $ hg add a b adding b/b $ hg commit -m Small example for file removal $ hg remove a $ hg status R a $ hg remove b removing b/b Despu s de hacer hg remove a un chero, Mercurial dejar de hacer seguimiento al mismo, incluso si recrea el e a chero con el mismo nombre en su directorio de trabajo. Si decide recrear un chero con el mismo nombre y desea que Mercurial le haga seguimiento, basta con hacerle hg add. Mercurial sabr que el chero recientemente adicionado a no est relacionado con el chero anterior que tena el mismo nombre. a

5.2.1.

Al eliminar un chero no se afecta su historial

Es preciso tener en cuenta que eliminar un chero tiene s lo dos efectos. o Se elimina la versi n actual del chero del directorio de trabajo. o Mercurial deja de hacer seguimiento a los cambios del chero desde la pr xima consignaci n. o o Al eliminar un chero no se altera de ninguna manera el historial del mismo. Si actualiza su directorio de trabajo a un conjunto de cambios en el cual el chero que elimin a n era tenido en o u cuenta, este reaparecer en el directorio de trabajo, con los contenidos que este tena cuando se consign tal conjunto a o de cambios. Si usted actualiza el directorio de trabajo a un conjunto de cambios posterior en el cual el chero haba sido eliminado, Mercurial lo eliminar de nuevo del directorio de trabajo. a

5.2.2.

Ficheros perdidos

Mercurial considera como perdido un chero que usted borr , pero para el que no se us hg remove. Los o o cheros perdidos se representan con ! al visualizar hg status. Las ordenes de Mercurial generalmente no har n a nada con los cheros perdidos.
1 2 3 4 5 6 7 8

$ $ $ $ $ $ $ !

hg init missing-example cd missing-example echo a > a hg add a hg commit -m File about to be missing rm a hg status a 51

Si su repositorio contiene un chero que hg status reporta como perdido, y desea que el mismo se vaya, se puede usar hg remove --after posteriormente para indicarle a Mercurial que usted deseaba borrar tal chero.
1 2 3

$ hg remove --after a $ hg status R a Por otro lado, si borr un chero perdido por accidente, puede usar hg revert nombre de fichero para o recuperar el chero. Reaparecer , sin modicaciones. a

1 2 3 4

$ hg revert a $ cat a a $ hg status

5.2.3.

Nota al margen: Por qu decirle explcitamente a Mercurial que elimine un chero? e

Es posible que se haya preguntado por qu Mercurial exige que usted le indique explcitamente que est borrando e a un chero. Al principio del desarrollo de Mercurial, este permita que usted borrara el chero sin m s; Mercurial se a dara cuenta de la ausencia del chero autom ticamente despu s de la ejecuci n de hg commit, y dejara de hacer a e o seguimiento al chero. En la pr ctica, resultaba muy sencillo borrar un chero accidentalmente sin darse cuenta. a

5.2.4.

Atajo utilagregar y eliminar cheros en un solo paso

Mercurial ofrece una orden combinada, hg addremove, que agrega los cheros que no tienen seguimiento y marca los cheros faltantes como eliminados.
1 2 3 4 5 6 7

$ hg init addremove-example $ cd addremove-example $ echo a > a $ echo b > b $ hg addremove adding a adding b La orden hg commit se puede usar con la opci n -A que aplica el mismo agregar-eliminar, seguido inmediatamente o de una consignaci n. o

1 2 3

$ echo c > c $ hg commit -A -m Commit with addremove adding c

5.3.

Copiar cheros

Mercurial ofrece la orden hg copy para hacer una copia nueva de un chero. Cuando se copia un chero con esta orden, Mercurial lleva un registro indicando que el nuevo chero es una copia del chero original. Los cheros copiados se tratan de forma especial cuando usted hace una fusi n con el trabajo de alguien m s. o a

52

5.3.1.

Resultados de copiar un chero durante una fusi n o

Durante una fusi n los cambios siguen una copia. Para ilustrar lo que esto signica, haremos un ejemplo. Comeno zaremos con el mini repositorio usual que contiene un solo chero
1 2 3 4 5

$ $ $ $ $

hg init my-copy cd my-copy echo line > file hg add file hg commit -m Added a file

Debemos hacer algo de trabajo en paralelo, de forma que tengamos algo para fusionar. Aqu clonamos el repositorio.
1 2 3 4

$ cd .. $ hg clone my-copy your-copy updating working directory 1 files updated, 0 files merged, 0 files removed, 0 files unresolved De vuelta en el repositorio inicial, usemos la orden hg copy para hacer una copia del primer chero que creamos.

1 2

$ cd my-copy $ hg copy file new-file Si vemos la salida de la orden hg status, el chero copiado luce tal como un chero que se ha a adido n normalmente.

1 2

$ hg status A new-file Pero si usamos la opci n -C de la orden hg status, se imprimir otra lnea: el chero desde el cual fue copiado o a nuestro chero reci n a adido. e n

1 2 3 4

$ hg status -C A new-file file $ hg commit -m Copied file Ahora, en el repositorio que clonamos, hagamos un cambio en paralelo. Adicionaremos una lnea de contenido al chero original que creamos.

1 2 3

$ cd ../your-copy $ echo new contents >> file $ hg commit -m Changed file Hemos modicado el chero file en este repositorio. Cuando jalemos los cambios del primer repositorio y fusionemos las dos cabezas, Mercurial propagar los cambios que hemos hecho localmente en file a su copia, new-file. a

1 2 3 4 5 6

$ hg pull ../my-copy pulling from ../my-copy searching for changes adding changesets adding manifests adding file changes 53

7 8 9 10 11 12 13 14 15

added 1 changesets with 1 changes to 1 files (+1 heads) (run hg heads to see heads, hg merge to merge) $ hg merge merging file and new-file 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, dont forget to commit) $ cat new-file line new contents

5.3.2.

Por qu los cambios se reejan en las copias? e

Este comportamiento de cambios en cheros que se propagan a las copias de los cheros parecera esot rico, pero e en la mayora de casos es absolutamente deseable. Es indispensable recordar que esta propagaci n solamente sucede o cuando fusionamos. Por lo tanto si sobre un chero se usa hg copy, y se modica el chero original durante el curso normal de su trabajo, nada pasar . a Lo segundo a tener en cuenta es que las modicaciones solamente se propagar n en las copias unicamente si los a repositorios de los cuales est jalando los cambios no saben de la copia. a Explicaremos a continuaci n la raz n de este comportamiento de Mercurial. Digamos que yo he aplicado un o o arreglo de un fallo importante a un chero fuente y consign los cambios. Por otro lado, usted decidi hacer hg e o copy sobre el chero en su repositorio, sin saber acerca del fallo o sin ver el arreglo, y ha comenzado a trabajar sobre su copia del chero. Si jala y fusiona mis cambios y Mercurial no hubiera propagado los cambios en las copias, su chero fuente tendra el fallo, a menos que usted haya recordado propagar el arreglo del fallo a mano, el mismo permanecera en su copia del chero. Mercurial previene esta clase de problemas, gracias a la propagaci n autom tica del cambio que arregl el fallo o a o del chero original. Hasta donde s , Mercurial es el unico sistema de control de revisiones que propaga los cambios e en las copias de esta forma. Cuando su historial de cambios tiene un registro de la copia y la subsecuente fusi n, usualmente no es necesario o propagar los cambios el chero original a las copias del mismo, y por esta raz n Mercurial propaga unicamente los o cambios en las copias hasta este punto y no m s all . a a

5.3.3.

C mo hacer que los cambios no sigan a la copia? o

Si por alg n motivo usted decide que esta caracterstica de propagaci n autom tica de cambios en las copias u o a no es para usted, simplemente use la orden usual de su sistema para copiar cheros (en sistemas tipo Unix, es cp), y posteriormente use hg add sobre la nueva copia hecha a mano. Antes de hacerlo, de todas maneras, relea la secci n 5.3.2, y tome una decisi n asegur ndose que este comportamiento no es el apropiado para su caso especco. o o a

5.3.4.

Comportamiento de la orden hg copy

Cuando usa la orden hg copy, Mercurial hace una copia de cada chero fuente tal como se encuentra en el directorio actual. Esto signica que si usted hace modicaciones a un chero, y le aplica hg copy sin haber consignado primero los cambios, la nueva copia contendr tambi n las modicaciones que haya hecho hasta ese punto. (Este a e comportamiento me parece poco intuitivo, y por tal motivo lo menciono.) La orden hg copy act a de forma parecida a la orden cp de Unix (puede usar el alias hg cp si le es m s u a c modo). El ultimo argumento es el destino, y todos los argumentos previos son las fuentes. Si solamente indica un o chero como la fuente, y el destino no existe, se crea un chero nuevo con ese nombre.
1 2

$ mkdir k $ hg copy a k 54

3 4

$ ls k a Si el destino es un directorio, Mercurial copia las fuentes en este.

1 2 3 4

$ mkdir d $ hg copy a b d $ ls d a b La copia de un directorio es recursiva, y preserva la estructura del directorio fuente.

1 2

$ hg copy c e copying c/a/c to e/a/c Si tanto la fuente como el destino son directorios, la estructura de la fuente se recrea en el directorio destino.

1 2

$ hg copy c d copying c/a/c to d/c/a/c De la misma forma que la orden hg rename, si copia un chero manualmente y desea que Mercurial sepa que ha copiado un chero, basta con aplicar la opci n --after a la orden hg copy. o

1 2

$ cp a z $ hg copy --after a z

5.4.

Renombrar cheros

La necesidad de renombrar un chero es m s com n que hacer una copia del mismo. La raz n por la cual discut la a u o orden hg copy antes de hablar acerca de cambiar el nombre de los cheros, es que Mercurial trata el renombrar un chero de la misma forma que una copia. Por lo tanto, saber lo que hace Mercurial cuando usted copia un chero le indica qu esperar cuando renombra un chero. e Cuando usa la orden hg rename, Mercurial hace una copia de cada chero fuente, lo borra y lo marca como chero eliminado.
1

$ hg rename a b La orden hg status muestra la nueva copia del chero como a adida y el chero inicial de la copia, como elimin nado.

1 2 3

$ hg status A b R a De la misma forma en que se usa la orden hg copy, debemos usar la opci n -C de la orden hg status para o vericar que el chero a adido realmente comienza a ser seguido por Mercurial como una copia del chero original, n ahora eliminado.

1 2 3 4

$ hg status -C A b a R a 55

Igual que con hg remove y hg copy, puede indic rsele a Mercurial acerca de un renombramiento inmediato a con la opci n --after. El comportamiento de la orden hg rename y las opciones que acepta, son similares a la o orden hg copy en casi todo.

5.4.1.

Renombrar cheros y fusionar cambios

Dado que el renombrado de Mercurial se implementa como un copiar-y-eliminar, la misma propagaci n de cambios o ocurre cuando usted fusiona despu s de renombrar como despu s de hacer una copia. e e Si yo modico un chero y usted lo renombra a un nuevo chero, y posteriormente fusionamos nuestros respectivos cambios, mi modicaci n al chero bajo su nombre original se propagar en el chero con el nuevo nombre. (Es lo o a que se esperara que simplemente funcione, pero, no todos los sistemas de control de revisiones hacen esto.) Aunque el hecho de que los cambios sigan la copia es una caracterstica respecto a la cual usted puede estar de acuerdo y decir si, puede ser util, debera ser claro que el seguimiento de cambios de un renombramiento es denitivamente importante. Sin esto, sera muy sencillo que los cambios se quedaran atr s cuando los cheros se a renombran.

5.4.2.

Cambios de nombre divergentes y fusi n o

El caso de renombramiento con nombres divergentes ocurre cuando dos desarrolladores comienzan con un chero llam moslo fooen sus repositorios respectivos. e
1 2 3 4 5 6

$ hg clone orig anne updating working directory 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg clone orig bob updating working directory 1 files updated, 0 files merged, 0 files removed, 0 files unresolved Anne renombra el chero a bar.

1 2 3

$ cd anne $ hg mv foo bar $ hg ci -m Rename foo to bar Mientras que Bob lo renombra como quux.

1 2 3

$ cd ../bob $ hg mv foo quux $ hg ci -m Rename foo to quux Veo esto como un conicto porque cada desarrollador ha expresado intenciones diferentes acerca de c mo consido era debera haberse nombrado el chero. Qu cree que debera pasar cuando fusionen su trabajo? El comportamiento de Mercurial es que siempre preserva e ambos nombres cuando fusiona los conjuntos de cambios que contienen nombres divergentes.

1 2 3 4 5 6 7

# See http://www.selenic.com/mercurial/bts/issue455 $ cd ../orig $ hg pull -u ../anne pulling from ../anne searching for changes adding changesets adding manifests 56

8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

adding file changes added 1 changesets with 1 changes to 1 files 1 files updated, 0 files merged, 1 files removed, 0 files unresolved $ hg pull ../bob pulling from ../bob searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files (+1 heads) (run hg heads to see heads, hg merge to merge) $ hg merge warning: detected divergent renames of foo to: bar quux 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, dont forget to commit) $ ls bar quux Tenga en cuenta que Mercurial le advierte acerca de nombres divergentes, pero deja que usted decida qu hacer e con la divergencia despu s de la fusi n. e o

5.4.3.

Cambios de nombre convergentes y fusi n o

Otra clase de conicto al cambiar el nombre de cheros ocurre cuando dos personas eligen renombrar diferentes cheros fuente al mismo destino. En este caso Mercurial aplica su maquinaria de fusi n usual, y le permite a usted o guiar la situaci n a una resoluci n adecuada. o o

5.4.4.

Otros casos lmite relacionados con renombramientos

Mercurial tiene un fallo de mucho tiempo en el cual no es capaz de fusionar cuando por un lado hay un chero con un nombre dado, mientras que en otro hay un directorio con el mismo nombre. Esto est documentado como Fallo de a Mercurial No. 29.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

$ hg init issue29 $ cd issue29 $ echo a > a $ hg ci -Ama adding a $ echo b > b $ hg ci -Amb adding b $ hg up 0 0 files updated, 0 files merged, 1 files removed, 0 files unresolved $ mkdir b $ echo b > b/b $ hg ci -Amc adding b/b created new head $ hg merge abort: Is a directory: /tmp/issue29HYiaCx/issue29/b 57

5.5.

Recuperarse de equivocaciones

Mercurial tiene unas ordenes poderosas que le ayudar n a recuperarse de equivocaciones comunes. a La orden hg revert le permite deshacer cambios que haya hecho a su directorio de trabajo. Por ejemplo, si aplic hg add a un chero por accidente, ejecute hg revert con el nombre del chero que a adi , y en tanto o n o que el chero no haya sido tocado de forma alguna, no ser adicionado, ni seguido por Mercurial. Tambi n puede usar a e hg revert para deshacerse de cambios err neos a un chero. o Tenga en cuenta que la orden hg revert se usa para cambios que no han sido consignados. Cuando haya consignado un cambio, si decide que era un error, puede hacer algo todava, pero sus opciones pueden estar m s a limitadas. Para obtener informaci n acerca de la orden hg revert y detalles de c mo tratar con cambios consignados, vea o o el captulo 9.

58

Captulo 6

Colaborar con otros


Debido a su naturaleza descentralizada, Mercurial no impone poltica alguna de c mo deben trabajar los grupos o de personas. Sin embargo, si el control distribuido de versiones es nuevo para usted, es bueno tener herramientas y ejemplos a la mano al pensar en posibles modelos de ujo de trabajo.

6.1.

La interfaz web de Mercurial

Mercurial tiene una poderosa interfaz web que provee bastantes capacidades utiles. Para uso interactivo, la interfaz le permite visualizar uno o varios repositorios. Puede ver el historial de un repositorio, examinar cada cambio (comentarios y diferencias), y ver los contenidos de cada directorio y chero. Adicionalmente la interfaz provee noticaciones RSS de los cambios del repositorio. Esto le permite subscribirsea un repositorio usando su herramienta de lectura de noticaciones favorita, y ser noticado autom ticamente de la aca tividad en el repositorio tan pronto como sucede. Me gusta mucho m s este modelo que el estar suscrito a una lista de a correo a la cual se envan las noticaciones, dado que no requiere conguraci n adicional de parte de quien sea que o est administrando el repositorio. a La interfaz web tambi n permite a los usuarios remotos clonar repositorios, jalar cambios, y (cuando el servidor e est congurado para permitirlo) empujar cambios al mismo. El protocolo de entunelamiento HTTP de Mercurial a comprime datos agresivamente, de forma que trabaja ecientemente incluso en conexiones de red con poco ancho de banda. La forma m s sencilla de empezar a trabajar con la interfaz web es usar su navegador para visitar un repositorio a existente, como por ejemplo el repositorio principal de Mercurial en http://www.selenic.com/repo/hg?style= gitweb. Si est interesado en proveer una interfaz web a sus propios repositorios, Mercurial ofrece dos formas de hacerlo. a La primera es usando la orden hg serve, que est enfocada a servir de forma liviana y por intervalos cortos. Para a m s detalles de c mo usar esta orden vea la secci n 6.4 m s adelante. Si tiene un repositorio que desea hacer disponible a o o a de forma permanente, Mercurial tiene soporte embebido para el est ndar CGI (Common Gategay Interface), que es a manejado por todos los servidores web comunes. Vea la secci n 6.6 para los detalles de la conguraci n a trav s de o o e CGI.

6.2.

Modelos de colaboraci n o

Con una herramienta adecuadamente exible, tomar decisiones acerca del ujo de trabajo es mucho m s un reto a de ingeniera social que un problema t cnico. Mercurial impone pocas limitaciones sobre c mo puede estructurar el e o ujo de trabajo en un proyecto, as que depende de usted y de su grupo denir y trabajar con un modelo que se ajuste a sus necesidades particulares.

59

6.2.1.

Factores a tener en cuenta

El aspecto m s importante que usted debe considerar de cualquier modelo es qu tan bien se ajusta a las necesidades a e y capacidades de la gente que lo usar . Esto puede parecer auto-evidente; a n as, usted no puede permitirse olvidarlo a u ni por un momento. Una vez den un modelo de ujo de trabajo que pareca ser perfectamente adecuado para m, pero que caus una o cantidad considerable de consternaci n y fricci n dentro de mi equipo de desarrollo. A pesar de mis intentos de exo o plicar porqu necesit bamos un conjunto complejo de ramas, y de c mo deban uir los cambios entre ellas, algunos e a o miembros del equipo se molestaron. Aunque ellos eran personas inteligentes, no queran prestar atenci n a las lim o itaciones bajo las cuales est bamos operando, o comparar las consecuencias de esas limitaciones con los detalles del a modelo que yo estaba proponiendo. No esconda bajo la alfombra los problemas sociales o t cnicos que usted pueda preveer. Sin importar el esquema e que usted use, debe hacer planes para enfrentar posibles errores o problemas. Considere a adir procedimientos automn atizados para prevenir, o recuperarse r pidamente de, los problemas que usted pueda anticipar. A manera de ejemplo, a si usted planea tener una rama en la vayan los cambios que no est n listos para producci n, hara bien en pensar en la e o posibilidad de que alguien fusione accidentalmente dichos cambios en una rama para publicaci n. Usted podra evitar o este problema en particular escribiendo un gancho que evite que se fusionen cambios desde ramas inapropiadas.

6.2.2.

Anarqua informal

No sugerira un enfoque de todo vale como algo sostenible, pero es un modelo que es f cil de entender, y que a funciona perfectamente bien en unas cuantas situaciones inusuales. Como un ejemplo, muchos proyectos tienen un grupo informal de colaboradores que rara vez se re nen fsicau mente. A algunos grupos les gusta evitar el aislamiento de trabajar a distancia organizando sprints ocasionales. En un sprint, una cantidad de gente se re ne en un mismo sitio (el cuarto de conferencias de una empresa, el cuarto de u reuniones de un hotel, ese tipo de lugares) y pasar varios das m s o menos encerrados all, trabajando intensamente a en un pu ado de proyectos. n Un sprint es el lugar perfecto para usar el comando hg serve, ya que hg serve no requiere una infraestructura especial de servidores. Usted puede empezar a trabajar con hg serve en momentos, leyendo la secci n 6.4 m s o a abajo. Luego simplemente dgale a las personas cerca suyo que usted est ejecutando un servidor, enveles la URL a a trav s de un mensaje instant neo, y tendr de inmediato una forma r pida de trabajar juntos. Ellos pueden escribir su e a a a URL en un navegador web y revisar sus cambios r pidamente; o ellos pueden jalar un arreglo de fallo que usted haya a hecho y vericarlo; o pueden clonar una rama que contiene una nueva caracterstica y probarla. Lo bueno, y lo malo, de hacer cosas de manera ad hoc como aqu, es que s lo las personas que saben de sus o cambios, y d nde est n, pueden verlos. Un enfoque tan informal sencillamente no puede escalarse m s all de un o a a a pu ado de personas, porque cada individuo tiene que saber de n repositorios diferentes de los cuales jalar. n

6.2.3.

Un repositorio central unico

Para proyectos peque os migrando desde una herramienta centralizada de control de revisiones, tal vez la forma n m s f cil de empezar es hacer que los cambios vayan a trav s de un repositorio central compartido. Este es tambi n el a a e e bloque base para esquemas m s ambiciosos de ujo de trabajo. a Los colaboradores empiezan clonando una copia de este repositorio. Ellos pueden jalar cambios de el siempre que lo necesiten, y algunos (o tal vez todos los) desarrolladores tienen permiso para empujar cambios de vuelta cuando est n listos para que los dem s los vean. e a Bajo este modelo, para los usuarios tiene sentido jalar cambios directamente entre ellos, sin ir a trav s del reposie torio central. Considere un caso en el que yo tengo un arreglo tentativo de fallo, pero me preocupa que al publicarlo en el repositorio central rompa los arboles de todos los dem s cuando lo jalen. Para reducir el potencial de da o, puedo a n pedirle a usted que clone mi repositorio en un repositorio personal suyo y lo pruebe. Esto nos permite aplazar este cambio potencialmente inseguro hasta que haya tenido algo de pruebas. En este tipo de escenario, la gente usualmente utiliza el protocolo ssh para empujar cambios de manera segura al repositorio central, como se documenta en la secci n 6.5. Tambi n es usual publicar una copia de s lo lectura del o e o 60

repositorio sobre HTTP usando CGI, como en la secci n 6.6. Publicar a trav s de HTTP satisface las necesidades de o e aquellos que no tienen permiso para empujar, y de aquellos que desean usar navegadores web para explorar el historial del repositorio.

6.2.4.

Trabajo con muchas ramas

Los proyectos de cierta talla tienden de manera natural a progresar de forma simult nea en varios frentes. En el a caso del software, es com n que un proyecto tenga versiones peri dicas ociales. Una versi n puede entrar a modo u o o mantenimiento por un tiempo despu s de su primera publicaci n; las versiones de mantenimiento tienden a contener e o solamente arreglos de fallos, no nuevas caractersticas. En paralelo con las versiones de mantenimiento, puede haber una o varias versiones futuras en desarrollo. La gente usa normalmente la palabra rama para referirse a una de las direcciones ligeramente distintas en las cuales avanza el desarrollo. Mercurial est especialmente preparado para administrar un buen n mero de ramas simult neas pero no id nticas. a u a e Cada direcci n de desarrollo puede vivir en su propio repositorio central, y usted puede mezclar los cambios de una o a otra cuando sea necesario. Dado que los repositorios son independientes entre s, los cambios inestables de una rama de desarrollo nunca afectar n una rama estable a menos que alguien mezcle explcitamente los cambios. a A continuaci n hay un ejemplo de c mo podra hacerse esto en la pr ctica. Digamos que tiene una rama principal o o a en un servidor central.
1 2 3 4 5

$ hg init main $ cd main $ echo This is a boring feature. > myfile $ hg commit -A -m We have reached an important milestone! adding myfile Alguien lo clona, hace cambios locales, los prueba, y los empuja de vuelta. Una vez que la rama principal alcanza un hito de proyecto se puede usar la orden hg tag para dar un nombre permanente a la revisi n del hito. o

1 2 3 4 5 6 7 8 9 10 11

$ hg tag v1.0 $ hg tip changeset: 1:471e84684405 tag: tip user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:16 2009 +0000 summary: Added tag v1.0 for changeset a1e37e7a184f $ hg tags tip v1.0

1:471e84684405 0:a1e37e7a184f

Digamos que en la rama principal ocurre m s desarrollo. a


1 2 3 4 5 6

$ cd ../main $ echo This is exciting and new! >> myfile $ hg commit -m Add a new feature $ cat myfile This is a boring feature. This is exciting and new! Cuando se usa la etiqueta con que se identic la versi n, la gente que clone el repositorio en el futuro puede usar o o hg update para obtener una copia del directorio de trabajo igual a cuando se cre la etiqueta de la revisi n que se o o consign . o 61

1 2 3 4 5 6 7

$ cd .. $ hg clone -U main main-old $ cd main-old $ hg update v1.0 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cat myfile This is a boring feature. Adicionalmente, justo despu s de que la rama principal se etiquete, alguien puede clonarla en el servidor a una e nueva rama estable, tambi n en el servidor. e

1 2 3 4 5 6 7 8 9

$ cd .. $ hg clone -rv1.0 main stable requesting all changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files updating working directory 1 files updated, 0 files merged, 0 files removed, 0 files unresolved Alguien que requiera hacer un cambio en la rama estable puede clonar ese repositorio, hacer sus cambios, consignarlos, y empujarlos de vuelta.

1 2 3 4 5 6 7 8 9 10 11 12 13

$ hg clone stable stable-fix updating working directory 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd stable-fix $ echo This is a fix to a boring feature. > myfile $ hg commit -m Fix a bug $ hg push pushing to /tmp/branchingOpMbpu/stable searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files Puesto que los repositorios de Mercurial son independientes, y que Mercurial no mueve los cambios de un lado a otro autom ticamente, las ramas estable y principal est n aisladas la una de la otra. Los cambios que haga en la rama a a principal no se ltran a la rama estable y viceversa. Es usual que los arreglos de fallos de la rama estable deban hacerse en la rama principal tambi n. En lugar de e reescribir el arreglo del fallo en la rama principal, usted puede jalar y mezclar los cambios de la rama estable a la principal, y Mercurial traer tales arreglos por usted. a

1 2 3 4 5 6

$ cd ../main $ hg pull ../stable pulling from ../stable searching for changes adding changesets adding manifests 62

7 8 9 10 11 12 13 14 15 16 17

adding file changes added 1 changesets with 1 changes to 1 files (+1 heads) (run hg heads to see heads, hg merge to merge) $ hg merge merging myfile 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, dont forget to commit) $ hg commit -m Bring in bugfix from stable branch $ cat myfile This is a fix to a boring feature. This is exciting and new! La rama principal a n contendr los cambios que no est n en la estable y contendr adem s todos los arreglos de fallos u a a a a de la rama estable. La rama estable permanece inc lume a tales cambios. o

6.2.5.

Ramas de caractersticas

En proyectos grandes, una forma efectiva de administrar los cambios es dividir el equipo en grupos m s peque os. a n Cada grupo tiene una rama compartida, clonada de una rama principal que conforma el proyecto completo. Aquellos que trabajan en ramas individuales usualmente est n aislados de los desarrollos de otras ramas. a

maestro

cripto

sistemadearchivos

ipc

memoria

red

seguridad

Figura 6.1: Ramas de Caractersticas Cuando se considera que una caracterstica particular est en buena forma, alguien de ese equipo de caractersticas a jala y fusiona de la rama principal a la rama de caractersticas y empuja de vuelta a la rama principal.

6.2.6.

El tren de publicaci n o

Algunos proyectos se organizan al estilotren: una versi n se planica para ser liberada cada cierto tiempo, y las o caractersticas que est n listas cuando ha llegado el tren, se incorporan. e Este modelo tiene cierta similitud a las ramas de caractersticas. La diferencia es que cuando una caracterstica pierde el tren, alguien en el equipo de caractersticas jala y fusiona los cambios que se fueron en la versi n liberada o hacia la rama de caracterstica, y el trabajo contin a sobre lo fusionado para que la caracterstica logre estar en la u pr xima versi n. o o

6.2.7.

El modelo del kernel Linux

El desarrollo del kernel Linux tiene una estructura jer rquica bastante horizontal, rodeada de una nube de caos a aparente. Dado que la mayora de los desarrolladores de Linux usan git, una herramienta de control de versiones distribuida con capacidades similares a Mercurial, resulta de utilidad describir la forma en que el trabajo uye en tal ambiente; si le gustan estas ideas, la aproximaci n se traduce bien de Git a Mercurial. o En el centro de la comunidad est Linus Torvalds, el creador de Linux. El publica un unico repositorio que es a considerado el arbol ocial actual por la comunidad completa de desarrolladores. Cualquiera puede clonar el arbol de Linus, pero el es muy selectivo respecto a los arboles de los cuales jala. 63

Linus tiene varios lugartenientes de conanza. Como regla, el jala todos los cambios que ellos publican, en la mayora de los casos sin siquiera revisarlos. Algunos de sus lugartenientes generalmente aceptan ser los mantene dores, responsables de subsistemas especcos dentro del kernel. Si un hacker cualquiera desea hacer un cambio a un subsistema y busca que termine en el arbol de Linus, debe encontrar qui n es el mantenedor del subsistema y solicie tarle que tome su cambio. Si el mantenedor revisa los cambios y est de acuerdo en tomarlos, estos pasar n al arbol de a a Linus a su debido tiempo. Cada lugarteniente tiene su forma particular de revisar, aceptar y publicar los cambios; y para decidir cuando presentarlos a Linus. Adicionalmente existen varias ramas conocidas que mucha gente usa para prop sitos distintos. o Por ejemplo, algunas personas mantienen repositorios estables de versiones anteriores del kernel, a los cuales aplican arreglos de fallos crticos cuando es necesario. Algunos mantenedores publican varios arboles: uno para cambios experimentales; uno para cambios que van a ofrecer al mantenedor principal; y as sucesivamente. Otros publican solo un arbol. Este modelo tiene dos caractersticas notables. La primera es que es de jalar exclusivamente. Usted debe solicitar, convencer o incluso rogar a otro desarrollador para que tome sus cambios, porque casi no hay arboles en los cuales m s de una persona pueda publicar, y no hay forma de publicar cambios en un arbol que alguien m s controla. a a La segunda es que est basado en reputaci n y meritocracia. Si usted es un desconocido, Linus probablemente a o ignorar sus cambios, sin siquiera responderle. Pero el mantenedor de un subsistema probablemente los revisara, y a los acoger en caso de que aprueben su criterio de aplicabilidad. A medida que usted ofrezca mejores cambios a a un mantenedor, habr m s posibilidad de que se confe en su juicio y se acepten los cambios. Si usted es reconocido a a y mantiene una rama durante bastante tiempo para algo que Linus no ha aceptado, personas con intereses similares pueden jalar sus cambios regularmente para estar al da con su trabajo. La reputaci n y meritocracia no necesariamente son transversales entre personas de diferentes subsistemas. Si o usted es un hacker respetado pero especializado en almacenamiento, y trata de arreglar un fallo de redes, tal cambio puede recibir un nivel de escrutinio de un mantenedor de redes comparable con el que se le hara a un completo extra o. n Personas que vienen de proyectos con un ordenamiento distinto, sienten que el proceso comparativamente ca tico o del Kernel Linux es completamente lun tico. Es objeto de los caprichos individuales; la gente desecha cambios cuando a lo desea; y el ritmo de desarrollo es alucinante. A pesar de eso Linux es una pieza de software exitosa y bien reconocida.

6.2.8.

Solamente jalar frente a colaboraci n publica o

Una fuente perpetua de discusiones en la comunidad de c digo abierto yace en la armaci n de que el modelo de o o desarrollo en el cual la gente solamente jala cambios de otros es mejor que uno en el cual muchas personas pueden publicar cambios a un repositorio compartido. Tpicamente los partidarios del modelo de publicar usan las herramientas que se apegan a este modelo. Si usted usa una herramienta centralizada de control de versiones como Subversion, no hay forma de elegir qu modelo va a e usar: la herramienta le ofrece publicaci n compartida, y si desea hacer cualquier otra cosa, va a tener que tomar una o aproximaci n articial (tal como aplicar parches a mano). o Una buena herramienta de control de versiones distribuida, tal como Mercurial, soportar los dos modelos. Usted a y sus colaboradores pueden estructurar c mo trabajar n juntos basados en sus propias necesidades y preferencias, sin o a tener que llevar a cabo las peripecias que la herramienta les obligue a hacer.

6.2.9.

Cuando la colaboraci n encuentra la administraci n ramicada o o

Una vez que usted y su equipo conguren algunos repositorios compartidos y comiencen a propagar cambios entre sus repositorios locales y compartidos, usted comenzar a encarar un reto relacionado, pero un poco distinto: a administrar las direcciones en las cuales su equipo puede moverse. A pesar de que est ntimamente ligado acerca a de c mo interact a su equipo, este es un tema lo sucientemente denso para ameritar un tratamiento aparte, en el o u captulo 8.

64

6.3.

Aspectos t cnicos de la colaboraci n e o

Lo que resta del captulo lo dedicamos a las cuestiones de servir datos a sus colaboradores.

6.4.

Compartir informalmente con hg serve

La orden hg serve de Mercurial satisface de forma espectacular las necesidades de un grupo peque o, acoplado n y agil. Tambi n sirve como una demostraci n de c mo se siente usar los comandos usando la red. e o o Ejecute hg serve dentro de un repositorio, y en pocos segundos se iniciar un servidor HTTP especializado; a aceptar conexiones desde cualquier cliente y servir datos de este repositorio mientras lo mantenga funcionando. a a Todo el que conozca la URL del servidor que usted ha iniciado, y que pueda comunicarse con su computador a trav s e de la red, puede usar un navegador web o Mercurial para leer datos del repositorio. Un URL para una instancia de hg serve ejecut ndose en un port til debera lucir similar a http://my-laptop.local:8000/. a a La orden hg serve no es un servidor web de prop sito general. Solamente puede hacer dos cosas: o Permitir la visualizaci n del historial del repositorio que est sirviendo, desde un navegador web. o a Hablar el protocolo de conexi n de Mercurial, para que la gente pueda hacer hg clone o hg pull (jalar) o cambios desde tal repositorio. En particular, hg serve no permitir que los usuarios remotos modiquen su repositorio. Es de tipo s lo lectura. a o Si est familiariz ndose con Mercurial, no hay nada que le impida usar hg serve para servir un repositorio en a a su propio computador, y posteriormente usar ordenes como hg clone, hg incoming, para comunicarse con el servidor como si el repositorio estuviera alojado remotamente. Esto puede ayudarle a adecuarse r pidamente a usar a comandos en repositorios alojados en la red.

6.4.1.

Cuestiones adicionales para tener en cuenta

Dado que permite lectura sin autenticaci n a todos sus clientes, debera usar hg serve exclusivamente en amo bientes en los cu les esto no sea importante, o en los cuales tenga control completo acerca de qui n puede acceder a a e su red y jalar cambios de su repositorio. La orden hg serve no tiene conocimiento acerca de programas cortafuegos que puedan estar instalados en su sistema o en su red. No puede detectar o controlar sus cortafuegos. Si otras personas no pueden acceder a su instancia de hg serve, lo siguiente que debera hacer (despu s de asegurarse que tienen el URL correcto) es vericar su e conguraci n de cortafuegos. o De forma predeterminada, hg serve escucha conexiones entrantes en el puerto 8000. Si otro proceso est esa cuchando en tal puerto, usted puede especicar un puerto distinto para escuchar con la opci n -p. o Normalmente, cuando se inicia hg serve, no muestra ning n mensaje, lo cual puede ser algo desconcertante. u Si desea conrmar que en efecto est ejecut ndose correctamente, y averiguar qu URL debera enviar a sus colaboa a e radores, incielo con la opci n -v. o

6.5.

Uso del protocolo Secure Shell (ssh)

Usted puede publicar y jalar cambios en la red de forma segura usando el protocolo Secure Shell (ssh). Para usarlo exitosamente, tendr que hacer algo de conguraci n a nivel de cliente o de servidor. a o Si no est familiarizado con ssh, es un protocolo de red que le permite comunicarse de manera segura con otro a computador. Para usarlo con Mercurial, deber crear una o m s cuentas de usuario en un servidor de forma tal que los a a usuarios remotos puedan entrar y ejecutar ordenes. (Si ssh le es familiar, probablemente encontrar elemental una porci n del material a continuaci n.) a o o

65

6.5.1.
1

C mo leer y escribir URLs de ssh o

Los URLs de ssh tienden a lucir de la siguiente forma: ssh://bos@hg.serpentine.com:22/hg/hgbook 1. La parte ssh:// le indica a Mercurial que use el protocolo ssh. 2. El componente bos@ indica el nombre del usuario que est entrando al servidor. Puede omitirlo si el usuario a remoto coincide con el usuario local. 3. hg.serpentine.com es el nombre del servidor al cual se desea entrar. 4. El :22 identica el n mero del puerto en el servidor al cual se conectar . El predeterminado es el 22, as que u a solamente necesitar especicar esa porci n si no est usando el puerto 22. a o a 5. La ultima porci n del URL es la ruta local del repositorio en el servidor. o El componente de la ruta del URL para ssh es una fuente de confusi n, puesto que no hay una forma est ndar o a para que las herramientas puedan interpretarlo. Algunos programas se comportan de manera distinta a otros cuando manipulan estas rutas. No es la situaci n ideal, pero es muy poco probable que vaya a cambiar. Por favor lea los o p rrafos siguientes cuidadosamente. a Mercurial trata la ruta al repositorio en el servidor como relativa al directorio personal del usuario remoto. Por ejemplo, si el usuario foo en el servidor tiene el directorio personal /home/foo, entonces un URL ssh que tenga como ruta a bar realmente se reere al directorio /home/foo/bar. Si desea especicar una ruta relativa a otro directorio de usuario, puede usar una ruta que comience con una virgulilla, seguida del nombre del usuario (llam mosle otrousuario), as e
1

ssh://server/otheruser/hg/repo Y si realmente desea especica una ruta absoluta en el servidor, comience con el componente de la ruta con dos barras, como en el siguiente ejemplo:

ssh://server//absolute/path

6.5.2.

Encontrar un cliente ssh para su sistema

Casi todos los sistemas tipo Unix vienen con OpenSSH preinstalado. Si usted est usando un sistema de estos, ejea cute which ssh para identicar d nde est instalada la orden ssh (usualmente estar en /usr/bin). Si por casualidad o a a no est presente, vea la documentaci n de sus sistema para averiguar c mo instalarlo. a o o En Windows, primero tendr que descargar un cliente adecuado. Hay dos alternativas: a El excelente paquete PuTTY [Tat] de Simon Tatham, que ofrece un conjunto completo de ordenes de cliente ssh. Si tiene alta tolerancia al dolor, puede usar el porte de Cygwin para OpenSSH. En cualquier caso, tendr que editar su chero Mercurial.ini para indicarle a Mercurial d nde encontrar la orden a o real del cliente. Por ejemplo, si est usando PuTTY, tendr que usar la orden plink como un cliente de lnea de a a comandos para ssh.
1 2

[ui] ssh = C:/ruta/a/plink.exe -ssh -i "C:/ruta/a/mi/llave/privada" Nota: La ruta a plink no debera contener espacios o caracteres en blanco, o Mercurial no podr encontrarlo correctamente (por lo tanto, probablemente no sera a buena idea colocarlo en C:\Program Filesa
a N.

del T. Ubicarlo en C:\Archivos de Programa tampoco lo sera.

66

6.5.3.

Generar un par de llaves

Para evitar la necesidad de teclear una clave de forma repetitiva cada vez que necesita usar el cliente, recomiendo generar un par de llaves. En un sistema tipo Unix, la orden ssh-keygen se encargar de la tarea. En Windows, si a est usando PuTTY, necesitar la orden puttygen. a a Cuando genera un par de llaves, se aconseja comedidamente protegerlas con una frase clave. (La unica oportunidad en la cual usted no querra hacerlo, es cuando est usando el protocolo ssh para tareas automatizadas en una red segura.) a No basta con generar un par de llaves. Se requiere adicionar la llave p blica al conjunto de llaves autorizadas u del usuario que usted usa para acceder a la m quina remota. Para aquellos servidores que usen OpenSSH (la gran a mayora), signicar a adir la llave p blica a la lista en el chero llamado authorized keys en su directorio .ssh. a n u En sistemas tipo Unix, su llave p blica tendr la extensi n .pub. Si usa puttygen en Windows, puede guardar la u a o llave p blica en un chero de su elecci n, o pegarla desde la ventana en la cual se despliega directamente en el chero u o authorized keys.

6.5.4.

Uso de un agente de autenticaci n o

Un agente de autenticaci n es un demonio que almacena frases clave en memoria (olvidar las frases clave si sale o a de su sesi n y vuelve a entrar). Un cliente ssh notar si el agente est corriendo, y le solicitar una frase clave. Si o a a a no hay un agente de autenticaci n corriendo, o el agente no almacena la frase clave necesaria, tendr que teclear su o a frase clave cada vez que Mercurial intente comunicarse con un servidor para usted (p.e. cada vez que jale o publique cambios). El problema de almacenar frases claves en un agente es que es posible para un atacante bien preparado recuperar el texto plano de su frase clave, en algunos casos incluso si su sistema ya ha sido reiniciado. Es su decisi n si es un o riesgo aceptable. Lo que s es seguro es que evita reteclear. En sistemas tipo Unix, el agente se llama ssh-agent, y usualmente se ejecuta autom ticamente cuando usted inicia a sesi n. Tendr que usar la orden ssh-add para a adir frases claves al agente. En Windows, si est usando PuTTY, la o a n a n orden pageant act a como el agente. El a ade un icono a su barra del sistema que le permitir administrar las frases u a clave almacenadas.

6.5.5.

Congurar el lado del servidor apropiadamente

Dado que puede ser dispendioso congurar ssh si es algo nuevo para usted, hay una variedad de cosas que podran ir mal. A ada a eso Mercurial y hay mucho m s en qu pensar. La mayor parte de estos problemas potenciales ocurren en n a e el lado del servidor, no en el cliente. Las buenas noticias es que una vez tiene una conguraci n funcional, usualmente o esta continuar trabajando indenidamente. a Antes de intentar que Mercurial hable con un servidor ssh, es mejor asegurarse de que puede usar la orden normal ssh o putty para comunicarse primero con el servidor. Si tiene problemas usando estas ordenes directamente, de seguro Mercurial no funcionar . Pero a n, esto esconder el problema subyacente. Cuando desee revisar un problema a u a relacionado con ssh y Mercurial, debera asegurarse primero que las ordenes de ssh en el lado del cliente funcionan primero, antes de preocuparse por si existe un problema con Mercurial. Lo primero para asegurar en el lado del servidor es que usted pueda iniciar sesi n desde otra m quina. Si no puede o a entrar usando ssh o putty, el mensaje de error que obtenga le puede dar pistas de qu ha ido mal. Los problemas m s e a comunes son los siguientes: Si obtiene un error de conexi n rehusada, es posible que no haya un demonio SSH corriendo en el servidor o o que no pueda accederse a el debido a la conguraci n de cortafuegos. o Si obtiene un error de no hay ruta hasta el servidor, puede tener una direcci n incorrecta para el servidor o un o cortafuegos con bloqueo agresivo que negar la existencia del servidor. a Si obtiene un mensaje de permiso denegado, puede que haya tecleado mal el usuario en el servidor, o que haya tecleado incorrectamente la frase clave de su llave o la clave del usuario remoto.

67

En resumen, si tiene problemas al comunicarse con el demonio ssh del servidor, primero aseg rese de que se est ejeu e cutando. En muchos sistemas estar instalado, pero deshabilitado de forma predeterminada. Una vez que haya hecho a esto tendr que revisar si el cortafuegos del servidor est congurado para recibir conexiones entrantes en el puerto a a en el cual est escuchando el demonio de ssh (usualmente el 22). No trate de buscar otras posibilidades ex ticas o a o conguraciones erradas hasta que haya revisado primero estas dos. Si est usando un agente de autenticaci n en el lado del cliente para almacenar las frase claves de sus contrase as, a o n debera poder entrar al servidor sin necesidad de que se le soliciten frases claves o contrase as. Si se le pregunta n alguna, a continuaci n algunas posibilidades: o Puede haber olvidado usar ssh-add o pageant para guardar la frase clave. Puede haber almacenado una frase clave para una llave distinta. Si se le solicita la clave del usuario remoto, hay otras posibilidades que deben revisarse: O bien el directorio del usuario o su directorio .ssh tiene permisos excesivamente abiertos. Como resultado el demonio ssh no conar ni leer su chero authorized keys. Por ejemplo, un directorio personal o .ssh con a a permisos de escritura para grupo mostrar a veces este sntoma. a El chero authorized keys del usuario puede tener un problema. Si alguien distinto al usuario es due o del n mismo o puede escribir en el chero, el demonio ssh no conar en el y no lo leer . a a En un mundo ideal, debera poder ejecutar la siguiente orden exitosamente, y debera imprimir exactamente una lnea de salida, la fecha y hora actual.
1

ssh miservidor date Si en su servidor tiene gui n que se ejecuta a la entrada e imprime letreros o cualquier otra cosa, incluso cuando se o ejecutan ordenes no interactivas como esta, debera arreglarlo antes de continuar, de forma que solamente imprima algo si se ejecuta interactivamente. De otra forma estos letreros al menos llenar n la salida de Mercurial. Incluso podran a causar problemas potenciales cuando se ejecuten ordenes de forma remota. Mercurial intenta detectar e ignorar los letreros en sesiones no interactivas de ssh, pero no es a prueba de tontos. (Si edita sus guiones de entrada en el servidor, la forma usual de ver si un gui n de lnea de comandos se ejecuta en un int rprete interactivo es vericar el o e c digo de retorno de la orden tty -s.) o Cuando verique que el venerado ssh funciona en su servidor, el siguiente paso es asegurarse de que Mercurial corre en el servidor. La siguiente orden debera ejecutarse satisfactoriamente:

ssh miservidor hg version Si ve un mensaje de error en lugar de la salida usual de hg version, ser porque Mercurial no fue instalado en a /usr/bin. Si este es el caso, no se preocupe; no necesita hacerlo. Pero debera revisar los posibles problemas: Est instalado Mercurial en el servidor? S que suena trivial pero es mejor revisar! a e Tal vez la ruta de b squeda de la interfaz de ordenes (normalmente va la variable de entorno PATH) simplemente u est mal congurada. a Puede ser que su variable de ambiente PATH solamente apunte al lugar en el cual est el ejecutable hg si la sesi n a o de entrada es interactiva. Esto puede suceder si establece la ruta en el gui n de lnea de comandos de entrada o incorrecto. Consulte la documentaci n de su int rprete de ordenes. o e La variable de ambiente PYTHONPATH puede requerir contener la ruta a los m dulos de Mercurial en Python. o Puede que ni siquiera est establecida; podra estar incorrecta; o puede ser que se establezca unicamente cuando a hay entradas interactivas. Si puede ejecutar hg version sobre una conexi n ssh, felicitaciones! Ha logrado la interacci n entre el cliente o o y el servidor. Ahora debera poder acceder a los repositorios de Mercurial que tiene el usuario en el servidor. Si tiene problemas con Mercurial y ssh en este punto, intente usar la opci n --debug para tener informaci n m s clara de lo o o a que est sucediendo. a 68

6.5.6.

Compresi n con ssh o

Mercurial no comprime datos cuando usa el protocolo ssh, dado que el protocolo puede comprimir datos transparentemente. Pero el comportamiento predeterminado del cliente ssh es no utilizar compresi n. o Sobre cualquier red distinta a una LAN r pida (incluso con una red inal mbrica), hacer uso de compresi n puede a a o mejorar el rendimiento de las operaciones de Mercurial que involucren la red. Por ejemplo, sobre WAN, alguien ha medido que la compresi n reduce la cantidad de tiempo requerido para clonar un repositorio particularmente grande o de 51 minutos a 17 minutos. Tanto ssh como plink aceptan la opci n -C para activar la compresi n. Puede editar f cilmente su hgrc para o o a habilitar la compresi n para todos los usos de Mercurial con el protocolo ssh. o
1 2

[ui] ssh = ssh -C Si usa ssh, puede recongurarlo para que siempre use compresi n cuando se comunique con su servidor. Para o hacerlo, edite su chero .ssh/config (que puede no existir a n), de la siguiente forma: u

1 2 3

Host hg Compression yes HostName hg.ejemplo.com Que dene un alias, hg. Cuando lo usa con la orden ssh o con una URL de Mercurial con protocolo ssh, har que a ssh se conecte a hg.ejemplo.com usando compresi n. Esto le brindar un nombre m s corto para teclear, junto con o a a compresi n, los cuales por derecho propio son buenos. o

6.6.

Servir sobre HTTP usando CGI

Dependiendo de qu tan ambicioso sea, congurar la interfaz CGI de Mercurial puede tomar desde unos minutos e hasta varias horas. Comenzaremos con el ejemplo m s sencillo, y nos dirigiremos hacia conguraciones m s complejas. Incluso para a a el caso m s b sico necesitar leer y modicar la conguraci n de su servidor web. a a a o Nota: Congurar un servidor web es una actividad compleja, engorrosa y altamente dependiente del sistema. De ninguna manera podremos cubrir todos los casos posibles con los cuales pueda encontrarse. Use su discreci n y juicio respecto o a las siguientes secciones. Prep rese para cometer muchas equivocaciones, y ema plear bastante tiempo leyendo las bit coras de error de su servidor. a

6.6.1.

Lista de chequeo de la conguraci n del servidor web o

Antes de continuar, t mese un tiempo para revisar ciertos aspectos de la conguraci n de su sistema: o o 1. Tiene un servidor web? Mac OS X viene con Apache, pero otros sistemas pueden no tener un servidor web instalado. 2. Si tiene un servidor web instalado, Est ejecut ndose? En la mayora de sistemas, aunque est presente, puede a a e no estar habilitado de forma predeterminada. 3. Est congurado su servidor para permitir ejecutar programas CGI en el directorio donde planea hacerlo? Casi a todos los servidores de forma predeterminada deshabilitan explcitamente la habilidad de ejecutar programas CGI.

69

Si no tiene un servidor web instalado, y no tiene experiencia congurando Apache, debera considerar usar el servidor web lighttpd en lugar de Apache. Apache tiene una reputaci n bien ganada por su conguraci n barroca o o y confusa. A pesar de que lighttpd tiene menos caractersticas que Apache en ciertas areas, muchas de ellas no son relevantes para servir repositorios de Mercurial. Y denitivamente es mucho m s sencillo comenzar con lighttpd a que con Apache.

6.6.2.

Conguraci n b sica de CGI o a

En sistemas tipo Unix es com n que los usuarios tengan un subdirectorio con un nombre como public html en u su directorio personal, desde el cual pueden servir p ginas web. Un chero llamado foo en este directorio ser visible a a en una URL de la forma http://www.example.com/username/foo. Para comenzar, encuentre el gui n hgweb.cgi que debera estar presente en su instalaci n de Mercurial. Si no o o puede encontrar r pidamente una copia local en su sistema, puede descargarlo del repositorio principal de Mercurial a en http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi. Tendr que copiar este gui n en su directorio public html, y asegurarse que sea ejecutable. a o
1 2

cp .../hgweb.cgi /public_html chmod 755 /public_html/hgweb.cgi El argumento 755 de la orden chmod es un poco m s general que hacerlo ejecutable: asegura que el gui n sea ejecutable a o por cualquiera, y que el grupo y los otros no tengan permiso de escritura. Si dejara los permisos de escritura abiertos, el subsistema suexec de Apache probablemente se negara a ejecutar el gui n. De hecho, suexec tambi n o e insiste en que el directorio en el cual reside el gui n no tenga permiso de escritura para otros. o

chmod 755 /public_html

Qu podra resultar mal? e Cuando haya ubicado el CGI en el sitio correspondiente, abra un navegador e intente visitar el URL http:// myhostname/myuser/hgweb.cgi, sin dejarse abatir por un error. Hay una alta probabilidad de que esta primera visita al URL sea fallida, y hay muchas razones posibles para este comportamiento. De hecho, podra toparse con cada uno de los errores que describimos a continuaci n, as que no deje de leerlos cuidadosamente. A continuaci n presento o o los problemas que yo tuve en un sistema con Fedora 7, con una instalaci n nueva de Apache, y una cuenta de usuario o que cre especcamente para desarrollar este ejercicio. e Su servidor web puede tener directorios por usuario deshabilitados. Si usa Apache, busque el chero de conguraci n que contenga la directiva UserDir. Si no est presente en sitio alguno, los directorios por usuario est n o a a deshabilitados. Si la hay, pero su valor es disabled, los directorios por usuario estar n deshabilitados. En caso cona trario, la directiva UserDir tendr el nombre del subdirectorio bajo el cual Apache mirar en el directorio de cada a a usuario, por ejemplo public html. Los permisos de sus cheros pueden ser demasiado restrictivos. El servidor web debe poder recorrer su directorio personal y los directorios que est n bajo public html, adem s de tener permiso para leer aquellos que est n adentro. e a e A continuaci n una receta r pida para hacer que sus permisos est n acordes con las necesidades b sicas. o a e a
1 2 3

chmod 755 find /public_html -type d -print0 | xargs -0r chmod 755 find /public_html -type f -print0 | xargs -0r chmod 644 Otra posibilidad con los permisos es que obtenga una ventana completamente en blanco cuando trata de cargar el gui n. En este caso, es posible que los permisos que tiene son demasiado permisivos. El subsistema suexec de o Apache no ejecutar un gui n que tenga permisos de escritura para el grupo o el planeta, por ejemplo. a o Su servidor web puede estar congurado para evitar la ejecuci n de programas CGI en los directorios de usuario. o A continuaci n presento una conguraci n predeterminada por usuario en mi sistema Fedora. o o 70

1 2 3 4 5 6 7 8 9 10 11 12

<Directory /home/*/public_html> AllowOverride FileInfo AuthConfig Limit Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec <Limit GET POST OPTIONS> Order allow,deny Allow from all </Limit> <LimitExcept GET POST OPTIONS> Order deny,allow Deny from all </LimitExcept> </Directory> Si encuentra un grupo de instrucciones de Directory similares en su conguraci n de Apache, la directiva a revisar o es Options. Adicione ExecCGI al nal de esta lista en caso de que haga falta y reinicie su servidor web. Si resulta que Apache le muestra el texto del gui n CGI en lugar de ejecutarlo, necesitar o bien descomentar (si o a se encuentra presente) o adicionar una directiva como la siguiente:

AddHandler cgi-script .cgi Otra posibilidad es que observe una traza de Python en colores informando que no puede importar un m dulo o relacionado con mercurial. Esto es un gran progreso! El servidor es capaz de ejecutar su gui n CGI. Este error o solamente ocurrir si est ejecutando una instalaci n privada de Mercurial en lugar de una instalaci n para todo el a a o o sistema. Recuerde que el servidor que ejecuta el programa CGI no cuenta con variables de entorno de las cuales usted s dispone en una sesi n interactiva. Si este error le ocurre, edite su copia de hgweb.cgi y siga las indicaciones dentro o del mismo para establecer de forma adecuada su variable de entorno PYTHONPATH. Finalmente, puede que se encuentre con otra traza a todo color de Python al visitar el URL: esta seguramente se referir a que no puede encontrar /path/to/repository1 . Edite su gui n hgweb.cgi y reemplace la cadena a o /path/to/repository con la ruta completa al repositorio que desea servir. En este punto, cuando trate de recargar la p gina, deber tener una linda vista HTML del historial de su repositorio. a a Uff! Conguraci n de lighttpd o En mi intenci n de ser exhaustivo, intent congurar lighttpd, un servidor web con creciente aceptaci n, para o e o servir los repositorios de la misma forma en que lo describ anteriormente con Apache. Ya super los problemas que e mostr con Apache, muchos de los cu les no son especcos del servidor. Por lo tanto estaba seguro de que mis e a permisos para directorios y cheros eran correctos y que mi gui n hgweb.cgi tambi n lo era. o e Dado que ya Apache estaba en ejecuci n correctamente, lograr que lighttpd sirviera mi repositorio fue r pido (en o a otras palabras, si est tratando de usar lighttpd, deber leer la secci n de Apache). Primero tuve que editar la secci n a a o o mod access para habilitar mod cgi y mod userdir, los cuales estaban inhabilitados en mi instalaci n predeterminada. o A ad posteriormente unas lneas al nal del chero de conguraci n, para hacer lo propio con los m dulos. n o o

1 2

userdir.path = "public_html" cgi.assign = ( ".cgi" => "" ) Hecho esto, lighttpd funcion inmediatamente para m. Si hubiera congurado lighttpd antes que Apache, habra o tenido casi los mismos problemas a nivel de conguraci n del sistema que con Apache. De todas maneras, considero o que lighttpd es bastante m s sencillo de congurar que Apache, a pesar de haber usado Apache por lo menos por a una d cada, y de que esta fue mi primera experiencia con lighttpd. e
1 N.

del T. Ruta al repositorio.

71

6.6.3.

Compartir varios repositorios con un gui n CGI o

El gui n hgweb.cgi permite publicar unicamente un repositorio, una restricci n frustrante. Si desea publicar m s o o a de uno sin complicarse con varias copias del mismo gui n, cada una con un nombre distinto, resulta mucho mejor usar o el gui n hgwebdir.cgi. o El procedimiento para congurar hgwebdir.cgi tiene una porci n adicional respecto al trabajo requerido con o hgweb.cgi. Primero se debe obtener una copia del gui n. Si no tiene una a mano, puede descargarla del ftp principal o del repositorio de Mercurial en http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi. Necesitar una copia del gui n en su directorio public html, y debe asegurarse de que tenga permisos de ejecua o ci n. o
1 2

cp .../hgwebdir.cgi /public_html chmod 755 /public_html /public_html/hgwebdir.cgi Con la conguraci n b sica, intente visitar en su navegador http://myhostname/myuser/hgwebdir.cgi. Debera o a mostrar una lista vaca de repositorios. Si obtiene una ventana en blanco o un mensaje de error, verique la lista de problemas potenciales en la secci n 6.6.2. o El gui n hgwebdir.cgi se apoya en un chero externo de conguraci n. De forma predeterminada, busca un o o chero llamado hgweb.config en el mismo directorio. Tendr que crear el chero, y permitir lectura de todo el a mundo. El formato del chero es similar a un chero ini de Windows, que puede ser interpretado por el m dulo o ConfigParser [Pyt] de Python. La forma m s sencilla de congurar hgwebdir.cgi es mediante una secci n llamada collections. Esta puba o licar autom ticamente todos los repositorios en los directorios que usted especique. La secci n debera lucir as: a a o

1 2

[collections] /mi/ruta = /mi/ruta Mercurial lo interpreta buscando el nombre del directorio que est a la derecha del smbolo =; ubicando repositorios e en la jerarqua de directorios; y usando el texto a la izquierda para eliminar el texto de los nombres que mostrar en la a interfaz web. El componente restante de la ruta despu s de esta eliminaci n usualmente se llama ruta virtual. e o Dado el ejemplo de arriba, si tenemos un repositorio cuya ruta local es /mi/ruta/este/repo, el gui n CGI o eliminar la porci n inicial /mi/ruta del nombre y publicar el repositorio con una ruta virtual este/repo. Si el a o a URL base de nuestro gui n CGI es http://myhostname/myuser/hgwebdir.cgi, el URL completo al repositorio o ser http://myhostname/myuser/hgwebdir.cgi/this/repo. a Si reemplazamos /mi/ruta en el lado izquierdo de este ejemplo con /mi, hgwebdir.cgi eliminar solamente a /mi del nombre del repositorio, y nos ofrecer la ruta virtual ruta/este/repo en lugar de este/repo. a El gui n hgwebdir.cgi buscar recursivamente en cada directorio listado en la secci n collections de su chero o a o de conguraci n, pero no har el recorrido recursivo dentro de los repositorios que encuentre. o a El mecanismo de collections permite publicar f cilmente repositorios de una forma hacer y olvidar. Solaa mente requiere congurar el gui n CGI y el chero de conguraci n una vez. Despu s de eso puede publicar y sacar o o e de publicaci n un repositorio en cualquier momento incluy ndolo o excluy ndolo de la jerarqua de directorios en la o e e cual le haya indicado a hgwebdir.cgi que mirase. Especicaci n explcita de los repositorios a publicar o Adem s del mecanismo collections, el gui n hgwebdir.cgi le permite publicar una lista especca de reposia o torios. Para hacerlo, cree una secci n paths, con los contenidos de la siguiente forma: o

1 2 3

[paths] repo1 = /mi/ruta/a/un/repo repo2 = /ruta/a/otro/repo

72

En este caso, la ruta virtual (el componente que aparecer en el URL) est en el lado derecho de cada denici n, a a o mientras que la ruta al repositorio est a la derecha. Note que no tiene que haber relaci n alguna entre la ruta virtual a o que elija y el lugar del repositorio en su sistema de cheros. Si lo desea, puede usar tanto collections como paths simult neamente en un solo chero de conguraci n. a o Nota: Si varios repositorios tienen la misma ruta virtual, hgwebdir.cgi no reportar ning n error. Pero se comportar de manera impredecible. a u a

6.6.4.

Descarga de cheros fuente

La interfaz web de Mercurial permite a los usuarios descargar un conjunto de cualquier revisi n. Este conjunto o contendr una r plica del directorio de trabajo en la revisi n en cuesti n, pero no contendr una copia de los datos del a e o o a repositorio. Esta caracterstica no est habilitada de forma predeterminada. Para habilitarla adicione un allow archive a la a secci n [web] de su chero hgrc. o

6.6.5.

Opciones de conguraci n en Web o

Las interfaces web de Mercurial (la orden hg serve, y los guiones hgweb.cgi y hgwebdir.cgi) tienen varias opciones de conguraci n disponibles. Todas ellas van en la secci n [web]. o o e a allow archive Determina qu mecanismos de descarga soportar Mercurial. Si habilita esta caracterstica, los usuarios de la interfaz web podr n descargar una copia de la revisi n del repositorio que est n viendo. Para activar la a o e caracterstica de descarga de conjunto, el valor tendr una secuencia de palabras extradas de la lista de abajo. a bz2 Un chero tar con el m todo de compresi n bzip2. Tiene la mejor tasa de compresi n, pero usa m s e o o a tiempo de procesamiento en el servidor. gz Un chero tar, comprimido con gzip. zip Un chero zip, comprimido con LZW. Este formato posee la peor tasa de compresi n, pero es muy usado o en el mundo Windows. Si da una lista vaca o no tiene la entrada allow archive, esta caracterstica se deshabilitar . A continuaci n se a o presenta un ejemplo de c mo habilitar los tres formatos soportados. o
1 2

[web] allow_archive = bz2 gz zip

allowpull Booleano. Determina si la interfaz web permite a los usuarios remotos emplear hg pull y hg clone sobre el repositorio HTTP. Si se coloca no o false, solamente se habilita la porci n de los procesos orientados-ao humanos de la interfaz web. contact Cadena. Una cadena en forma libre (pero preferiblemente corta) que identica a la persona o grupo a cargo del repositorio. Usualmente contiene el nombre y la direcci n de correo electr nico de una persona o de una o o lista de correo. A veces tiene sentido colocar esta opci n en el chero .hg/hgrc del repositorio, pero en otras o oportunidades es mejor hacerlo en el hgrc global si todos los repositorios tienen un unico mantenedor. maxchanges Entero. La cantidad m xima de conjuntos de cambios a mostrar de forma predeterminada en cada p gina. a a maxfiles Entero. La cantidad m xima predeterminada de cheros modicados a desplegar en una p gina. a a stripes Entero. Si la interfaz web despliega franjas para facilitar la visualizaci n alineada de las cuando se ve una o tabla, este valor controla la cantidad de las en cada franja. style Controla la plantilla que Mercurial usa para desplegar la interfaz web. Mercurial viene con dos plantillas web, llamadas default y gitweb (La primera es m s atractiva visualmente). Puede especicar una plantilla propia; a consulte el captulo 11. A continuaci n mostramos c mo habilitar el estilo gitweb. o o 73

1 2

[web] style = gitweb

templates Ruta. Directorio en el que se buscar n los cheros plantilla. De forma predeterminada, el gui n busca en el a o directorio en el cual fue instalado. Si usa hgwebdir.cgi, puede a adir otras opciones de conguraci n en la secci n [web] del chero hgweb.config n o o en lugar del chero hgrc si lo considera m s conveniente. Estas opciones son motd y style. a Opciones especcas para repositorios individuales Ciertas opciones de conguraci n de [web] deben estar ubicadas en el .hg/hgrc de un repositorio en lugar del o chero del usuario o el hgrc global. description Cadena. Una cadena de forma libre (preferiblemente corta) que describa los contenidos o el prop sito del reposo itorio. name Cadena. El nombre para visualizar en la interfaz web del repositorio. Sustituye el nombre predeterminado, el cual es el ultimo componente de la ruta del repositorio. Opciones especcas a la orden hg serve Algunas opciones en la secci n [web] de un chero hgrc son de uso exclusivo de la orden hg serve. o accesslog Ruta. El nombre del chero en el cual se escribe la bit cora de acceso. En principio, la orden hg serve a escribe esta informaci n a la salida est ndar, no a un chero. Las lneas de la bit cora se escriben en un formato o a a de chero combinado est ndar, usado por casi todos los servidores web. a address Cadena. La direcci n local en la cual el servidor debe escuchar peticiones entrantes. De forma predeterminada, o el servidor escucha en todas las direcciones. errorlog Ruta. El nombre de un chero en el cual escribir la bit cora de error. En principio, la orden hg serve escribe a esta informaci n en la salida de error est ndar, no a un chero. o a ipv6 Booleano. Si se usa o no el protocolo IPv6. IPv6 no se usa de manera predeterminada. port Entero. El n mero del puerto TCP en el cu l el servidor esperar conexiones. El puerto predeterminado es u a a el 8000. Elegir el chero hgrc correcto para las conguraciones de [web] Es importante recordar que un servidor web como Apache o lighttpd se ejecutar bajo un ID de usuario que a generalmente no es el suyo Los guiones CGI ejecutados por su servidor, tales como hgweb.cgi, se ejecutar n tambi n a e con ese ID de usuario. Si a ade opciones [web] a su chero personal hgrc los guiones CGI no leer n tal chero hgrc. Tales congun a raciones solamente afectar n el comportamiento de la orden hg serve cuando usted la ejecuta. Para logar que los a guiones CGI vean sus conguraciones, o bien cree un chero hgrc en el directorio personal del usuario bajo cuyo ID se ejecuta su servidor web, o a ada tales opciones al chero global hgrc. n

74

Captulo 7

Nombres de cheros y asociaci n de o patrones


Mercurial provee mecanismos que le permiten trabajar con nombres de cheros en una manera consistente y expresiva.

7.1.

Nombrado de cheros simple

Mercurial usa un mecanismo unicado bajo el cap para manejar nombres de cheros. Cada comando se como porta de manera uniforme con respecto a los nombres de chero. La manera en que los comandos operan con nombres de chero es la siguiente. Si usted especica explcitamente nombres reales de cheros en la lnea de comandos, Mercurial opera unicamente sobre dichos cheros, como usted esperara.
1

$ hg add COPYING README examples/simple.py Cuando usted provee el nombre de un directorio, Mercurial interpreta eso como opere en cada chero en este directorio y sus subdirectorios. Mercurial va por todos los cheros y subdirectorios de un directorio en orden alfab tico. e Cuando encuentra un subdirectorio, lo recorrer antes de continuar con el directorio actual. a

1 2 3 4 5

$ ? ? ? ?

hg status src src/main.py src/watcher/_watcher.c src/watcher/watcher.py src/xyzzy.txt

7.2.

Ejecuci n de comandos sin ningun nombre de chero o

Los comandos de Mercurial que trabajan con nombres de chero tienen comportamientos por defecto adecuados cuando son utilizados sin pasar ning n patr n o nombre de chero. El tipo de comportamiento depende de lo que u o haga el comando. Aqu presento unas cuantas reglas generales que usted puede usar para que es lo que probablemente har un comando si usted no le pasa ning n nombre de chero con el cual trabajar. a u Muchos comandos operar n sobre el directorio de trabajo completo. Por ejemplo, esto es lo que hace el comando a hg add,

75

Si el comando tiene efectos difciles o incluso imposibles de revertir, se le obligar a usted a proveer explcita a mente al menos un nombre o patr n (ver m s abajo). Esto lo proteje a usted de, por ejemplo, borrar cheros o a accidentalmente al ejecutar hg remove sin ning n argumento. u Es f cil evitar este comportamiento por defecto, si no es el adecuado para usted. Si un comando opera normalmente a en todo el directorio de trabajo, usted puede llamarlo para que trabaje s lo en el directorio actual y sus subdirectorio o pas ndole el nombre .. a
1 2 3 4 5 6 7 8 9 10 11 12 13 14

$ cd src $ hg add -n adding ../MANIFEST.in adding ../examples/performant.py adding ../setup.py adding main.py adding watcher/_watcher.c adding watcher/watcher.py adding xyzzy.txt $ hg add -n . adding main.py adding watcher/_watcher.c adding watcher/watcher.py adding xyzzy.txt Siguiendo la misma lnea, algunos comandos normalmente imprimen las rutas de cheros con respecto a la raz del repositorio, a n si usted los llama dentro de un subdirectorio. Dichos comandos imprimir n las rutas de los cheros u a respecto al directorio en que usted se encuentra si se les pasan nombres explcitos. Vamos a ejecutar el comando hg status desde un subdirectorio, y a hacer que opere en el directorio de trabajo completo, a la vez que todas las rutas de cheros se imprimen respecto a nuestro subdirectorio, pas ndole la salida del comando hg root. a

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

$ A A A ? ? ? ? ? ? ? $ A A A ? ? ? ? ? ? ?

hg status COPYING README examples/simple.py MANIFEST.in examples/performant.py setup.py src/main.py src/watcher/_watcher.c src/watcher/watcher.py src/xyzzy.txt hg status hg root ../COPYING ../README ../examples/simple.py ../MANIFEST.in ../examples/performant.py ../setup.py main.py watcher/_watcher.c watcher/watcher.py xyzzy.txt

76

7.3.

Reportar que est pasando a

El ejemplo con el comando hg add en la secci n anterior ilustra algo m s que es util acerca de los comandos de o a Mercurial. Si un comando opera en un chero que usted no pas explcitamente en la lnea de comandos, usualmente o se imprimir el nombre del chero, para que usted no sea sorprendido por lo que sucede. a Esto es el principio de mnima sorpresa. Si usted se ha referido explcitamente a un chero en la lnea de comandos, no tiene mucho sentido repetir esto de vuelta a usted. Si Mercurial est actuando en un chero implcitamente, porque a usted no pas nombres, ni directorios, ni patrones (ver m s abajo), lo m s seguro es decirle a usted qu se est haciendo. o a a e a Usted puede silenciar a los comandos que se comportan de esta manera usando la opci n -q. Tambi n puede hacer o e que impriman el nombre de cada chero, a n aquellos que usted indic explcitamente, usando la opci n -v. u o o

7.4.

Uso de patrones para identicar cheros

Adem s de trabajar con nombres de cheros y directorios, Mercurial le permite usar patrones para identicar a cheros. El manejo de patrones de Mercurial es expresivo. En sistemas tipo Unix (Linux, MacOS, etc.), el trabajo de asociar patrones con nombres de cheros recae sobre el int rprete de comandos. En estos sistemas, usted debe indicarle explcitamente a Mercurial que el nombre que se le e pasa es un patr n. En Windows, el int rprete no expande los patrones, as que Mercurial identicar autom ticamente o e a a los nombres que son patrones, y har la expansi n necesaria. a o Para pasar un patr n en vez de un nombre normal en la lnea de comandos, el mecanismo es simple: o
1

syntax:patternbody Un patr n es identicado por una cadena de texto corta que indica qu tipo de patr n es, seguido por un dos puntos, o e o seguido por el patr n en s. o Mercurial soporta dos tipos de sintaxis para patrones. La que se usa con m s frecuencia se denomina glob1 ; es el a mismo tipo de asociaci n de patrones usado por el int rprete de Unix, y tambi n debera ser familiar para los usuarios o e e de la lnea de comandos de Windows. Cuando Mercurial hace asociaci n autom tica de patrones en Windows, usa la sintaxis glob. Por esto, usted puede o a omitir el prejo glob: en Windows, pero tambi n es seguro usarlo. e La sintaxis re2 es m s poderosa; le permite especicar patrones usando expresiones regulares, tambi n conocidas a e como regexps. A prop sito, en los ejemplos siguientes, por favor note que yo tengo el cuidado de rodear todos mis patrones con o comillas sencillas, para que no sean expandidos por el int rprete antes de que Mercurial pueda verlos. e

7.4.1.

Patrones glob estilo int rprete e

Este es un vistazo general de los tipos de patrones que usted puede usar cuando est usando asociaci n con patrone a o glob. La secuencia * se asocia con cualquier cadena, dentro de un unico directorio.
1 2

$ hg add glob:*.py adding main.py La secuencia ** se asocia con cualquier cadena, y cruza los lmites de los directorios. No es una elemento est ndar de los tokens de glob de Unix, pero es aceptado por varios int rpretes Unix populares, y es muy util. a e

1 2

$ cd .. $ hg status glob:**.py
1 N. 2 N.

del T. Grupo, colecci n, aglomeraci n. o o del T. Expresiones regulares.

77

3 4 5 6 7

A A ? ? ?

examples/simple.py src/main.py examples/performant.py setup.py src/watcher/watcher.py La secuencia ? se asocia con cualquier caracter sencillo.

1 2

$ hg status glob:**.? ? src/watcher/_watcher.c El caracter [ marca el inicio de una clase de caracteres. Ella se asocia con cualquier caracter sencillo dentro de la clase. La clase se naliza con un caracter ]. Una clase puede contener m ltiples rangos de la forma a-f, que u en este caso es una abreviaci n para abcdef. o

1 2 3

$ hg status glob:**[nr-t] ? MANIFEST.in ? src/xyzzy.txt Si el primer caracter en aparecer despu s de [ en la clase de caracteres es un !, se niega la clase, haciendo que se e asocie con cualquier caracter sencillo que no se encuentre en la clase. Un { marca el inicio de un grupo de subpatrones, en donde todo el grupo es asociado si cualquier subpatr n en o el grupo puede ser asociado. El caracter , separa los subpatrones, y el } naliza el grupo.

1 2 3

$ hg status glob:*.{in,py} ? MANIFEST.in ? setup.py Cuidado! No olvide que si usted desea asocia un patr n con cualquier directorio, no debera usar el elemento para asociar o con cualquier cadena *, ya que este s lo generar asociaciones dentro de un solo directorio. En vez de eso, use el o a caracter para asociar con cualquier cadena **. Este peque o ejemplo ilustra la diferencia entre los dos. n

1 2 3 4 5 6 7 8

$ ? $ A A ? ? ?

hg status glob:*.py setup.py hg status glob:**.py examples/simple.py src/main.py examples/performant.py setup.py src/watcher/watcher.py

7.4.2.

Asociaci n con patrones de expresiones regulares re o

Mercurial acepta la misma sintaxis para expresiones regulares del lenguaje de programaci n Python (internamente o se usa el motor de expresiones regulares de Python). Esta sintaxis est basada en la misma del lenguaje Perl, que es el a dialecto m s popular en uso (por ejemplo, tambi n se usa en Java). a e No discutir el dialecto de expresiones regulares de Mercurial en detalle aqu, ya que las mismas no son usadas e frecuentemente. Las expresiones regulares al estilo Perl se encuentran documentadas exhaustivamente en una multitud de sitios web, y en muchos libros. En vez de eso, me enfocar en unas cuantas cosas que usted debera conocer si tiene e la necesidad de usar expresiones regulares en Mercurial. 78

Una expresi n regular es comparada contra un nombre de chero completo, relativo a la raz del repositorio. En o otras palabras, a n si usted se encuentra en un subdirectorio foo, si desea asociar cheros en este directorio, su patr n u o debe empezar con foo/. Un detalle a tener en cuenta es que, si le son familiares las expresiones regulares al estilo Perl, las de Mercurial est n enrazadas. Esto es, que la asociaci n de una expresi n se hace desde el inicio de la cadena; no se buscan a o o coincidencias dentro de la cadena. Para buscar coincidencias en cualquier sitio dentro de una cadena, empiece su patr n con un .*. o

7.5.

Filtrado de cheros

Mercurial no s lo le provee una variedad de formas para especicar cheros; le permite limitar a n m s dichos o u a cheros mediante el uso de ltros. Los comandos que operan con nombres de chero aceptan dos opciones de ltrado. -I, o --include, le permite especicar un patr n con el que deben coincidir los cheros para ser procesados. o -X, o --exclude, le brinda una manera de evitar procesar cheros, si coinciden con este patr n. o Usted puede pasar m ltiples veces las opciones -I y -X en la lnea de comandos, e intercalarlos como desee. Por u defecto, Mercurial interpreta los patrones que usted pase usando la sintaxis glob (pero usted puede usar expresiones regulares si lo necesita). El ltro -I puede verse como un procese todos los cheros que coincidan con este ltro.
1 2

$ hg status -I *.in ? MANIFEST.in El ltro -X puede verse como procese unicamente los cheros que no coincidan con este patr n. o

1 2 3

$ hg status -X **.py src ? src/watcher/_watcher.c ? src/xyzzy.txt

7.6.

Ignorar cheros y directorios no deseados

XXX.

7.7.

Sensibilidad a mayusculas

Si usted est trabajando en un ambiente de desarrollo mixto que contiene tanto sistemas Linux (u otro Unix) y a sistemas Mac o Windows, debera tener en mente el hecho de que ellos tratan case (N versus n) of le names in incompatible ways. This is not very likely to affect you, and its easy to deal with if it does, but it could surprise you if you dont know about it. Operating systems and lesystems differ in the way they handle the case of characters in le and directory names. There are three common ways to handle case in names. Completely case insensitive. Uppercase and lowercase versions of a letter are treated as identical, both when creating a le and during subsequent accesses. This is common on older DOS-based systems. Case preserving, but insensitive. When a le or directory is created, the case of its name is stored, and can be retrieved and displayed by the operating system. When an existing le is being looked up, its case is ignored. This is the standard arrangement on Windows and MacOS. The names foo and FoO identify the same le. This treatment of uppercase and lowercase letters as interchangeable is also referred to as case folding. 79

Case sensitive. The case of a name is signicant at all times. The names foo and FoO identify different les. This is the way Linux and Unix systems normally work. On Unix-like systems, it is possible to have any or all of the above ways of handling case in action at once. For example, if you use a USB thumb drive formatted with a FAT32 lesystem on a Linux system, Linux will handle names on that lesystem in a case preserving, but insensitive, way.

7.7.1.

Almacenamiento portable y seguro de repositorios

El mecanismo de almacenamiento de los repositorios en Mercurial es robusto frente a sensibilidad/insensibilidad u a may sculas. Los nombres de chero son traducidos para que puedan ser almacenados de manera segura tanto en sistemas sensibles como insensibles a may sculas. Esto signica que usted puede usar herramientas normales de u copia de cheros para transferir un repositorio Mercurial a, por ejemplo, una memoria USB, y trasladar de manera segura la memoria y el repositorio de ida y vuelta entre un Mac, un PC ejecutando Windows, y un sistema Linux

7.7.2.

Detecci n de conictos de mayusculas/minusculas o

Al operar en el directorio de trabajo, Mercurial respeta la poltica de nombrado del sistema de cheros en que se encuentre el directorio de trabajo. Si el sistema de cheros conserva las diferencias entre may sculas, pero no es u sensible a ellas, Mercurial tratar los nombres que s lo dieren en may sculas como uno solo y el mismo. a o u Un aspecto importante de este enfoque es que es posible consignar un conjunto de cambios en un sistema de cheros sensible a may sculas (tpicamente Linux o Unix) que terminar causando problemas para usuarios en sisu a temas insensibles a may sculas (usualmente en Windows o MacOS). Si un usuario de Linux consigna cambios a dos u cheros, uno de ellos llamado myfile.c y el otro llamado MyFile.C, ambos ser n almacenados correctamente en a el repositorio. Y ser n representados correctamente como cheros separados, en los directorios de trabajo de otros a usuarios de Linux. Si un usuario de Windows o Mac jalan este cambio, no tendr n problemas inicialmente, porque el mecanismo de a almacenamiento de Mercurial es seguro frente a sensibilidad/insensibilidad a may sculas. Sin embargo, una vez que u ellos traten de actualizar (hg update) el directorio de trabajo con ese conjunto de cambios, o hagan fusi n (hg o merge) con ese conjunto de cambios, Mercurial ver el conicto entre los dos nombres de chero que el sistema de a cheros tratara como el mismo, e impedir que ocurra la actualizaci n o fusi n. a o o

7.7.3.

Arreglar un conicto de mayusculas/minusculas

Si usted est usando Windows o Mac en un entorno mixto donde algunos de sus colaboradores est n usando Linux a a o Unix, y Mercurial reporta un conicto de may sculas/min sculas cuando usted trata de actualizar (hg update) o u u fusionar (hg merge), el procedimiento para arreglar el problema es simple. S lo busque un sistema Linux o Unix cercano, clone el repositorio problema all, y use el comando hg rename o de Mercurial para cambiar los nombres de cualquiera de los cheros o directorios problem ticos para que no causen a m s conictos. Consigne este cambio, y j lelo (hg pull) o emp jelo (hg push) a su sistema Windows o MacOS, a a u y actualcelo (hg update) a la revisi n con los nombres que ya no generan conictos. o El conjunto de cambios con los nombres con conictos de may sculas/min sculas permanecer en el historial de u u a su proyecto, y usted no podr actualizar (hg update) su directorio de trabajo a dicho conjunto de cambios en un a sistema Windows o MacOS, pero puede continuar el desarrollo sin impedimentos. Nota: Antes de la versi n 0.9.3, Mercurial no usaba un mecanismos seguro frente o a sensibilidad/insensibilidad a may sculas o min sculas, y no detectaba los conu u ictos con nombres de cheros. Si usted est usando una versi n m s antigua de a o a Mercurial en Windows o MacOS, le recomiendo en rgicamente que se actualice. e

80

Captulo 8

Administraci n de versiones y desarrollo o ramicado


Mercurial ofrece varios mecanismos que le permiten administrar un proyecto que avanza en m ltiples frentes u simult neamente. Para entender estos mecanismos, demos un vistazo a la estructura usual de un proyecto de software. a Muchos proyectos de software liberan una versi n mayor que contiene nuevas caractersticas substanciales. En o paralelo, pueden liberar versiones menores. Usualmente estas son id nticas a las versiones mayores en las cuales e est n basadas, pero con arreglos para algunos fallos. a En este captulo, comenzaremos hablando de c mo mantener registro de etapas del proyecto como las liberaciones o de una versi n. Continuaremos hablando del ujo de trabajo entre las diferentes fases de un proyecto, y c mo puede o o ayudar Mercurial a aislar y administrar tal trabajo.

8.1.

Dar un nombre persistente a una revisi n o

Cuando usted decide otorgar a una revisi n el nombre particular de una versi n, es buena idea grabar la identidad o o de tal revisi n. Esto le permitir reproducir dicha versi n en una fecha posterior, para cualquiera que sea el prop sito o a o o que se tenga en ese momento (reproducir un fallo, portar a una nueva plataforma, etc).
1 2 3 4 5

$ hg init mytag $ cd mytag $ echo hello > myfile $ hg commit -A -m Initial commit adding myfile Mercurial le permite dar un nombre permanente a cualquier revisi n usando la orden hg tag. Sin causa de o sorpresa, esos nombres se llaman tags (etiquetas).

$ hg tag v1.0 Una etiqueta no es m s que un nombre simb lico para una revisi n. Las etiquetas existen unicamente para su a o o conveniencia, brind ndole una forma permanente y sencilla de referirse a una revisi n; Mercurial no interpreta de a o ninguna manera los nombres de las etiquetas que usted use. Mercurial tampoco impone restricci n alguna al nombre o de una etiqueta, m s all de lo necesario para asegurar que una etiqueta pueda procesarse sin ambig edades. El nombre a a u de una etiqueta no puede tener ninguno de los siguientes caracteres: Dos puntos (ASCII 58, :) Retorno de carro (return) (ASCII 13, \r) 81

Nueva lnea (ASCII 10, \n) Puede usar la orden hg tags para ver las etiquetas presentes en su repositorio. Al desplegarse, cada revisi n o marcada se identica primero con su nombre, despu s con el n mero de revisi n y nalmente con un hash unico de la e u o revisi n. o
1 2 3

$ hg tags tip v1.0

1:515e5c86f496 0:1d3fd3640aaa

Note que tip aparece en en listado generado por hg tags. La etiqueta tip es una etiqueta otante especial, que identica siempre la revisi n m s reciente en el repositorio. o a Al desplegar la orden hg tags, las etiquetas se listan en orden inverso, por n mero de revisi n. Lo que signica u o usualmente que las etiquetas m s recientes se listan antes que las m s antiguas. Tambi n signica que la etiqueta tip a a e siempre aparecer como primera etiqueta listada al desplegar la orden hg tags. a Cuando usted ejecuta hg log, si se muestra una revisi n que tenga etiquetas asociadas a ella, se imprimir n o a tales etiquetas.
1 2 3 4 5 6 7 8 9 10 11 12 13

$ hg log changeset: tag: user: date: summary: changeset: tag: user: date: summary:

1:515e5c86f496 tip Bryan OSullivan <bos@serpentine.com> Tue Feb 10 18:23:29 2009 +0000 Added tag v1.0 for changeset 1d3fd3640aaa 0:1d3fd3640aaa v1.0 Bryan OSullivan <bos@serpentine.com> Tue Feb 10 18:23:29 2009 +0000 Initial commit

Siempre que requiera indicar un ID de revisi n a una orden de Mercurial, aceptar un nombre de etiqueta en su o a lugar. Internamente, Mercurial traducir su nombre de etiqueta en el ID de revisi n correspondiente, y lo usar . a o a
1 2 3 4 5 6 7 8 9 10

$ echo goodbye > myfile2 $ hg commit -A -m Second commit adding myfile2 $ hg log -r v1.0 changeset: 0:1d3fd3640aaa tag: v1.0 user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:29 2009 +0000 summary: Initial commit

No hay lmites en la cantidad de etiquetas por repositorio, o la cantidad de etiquetas que una misma revisi n pueda o tener. Siendo pr cticos, no es muy buena idea tener demasiadas (la cantidad variar de un proyecto a otro), debido a a a que la intenci n es ayudarle a encontrar revisiones. Si tiene demasiadas etiquetas, la facilidad de usarlas para identicar o revisiones disminuir r pidamente. a a Por ejemplo, si su proyecto tiene etapas (milestones) frecuentes, de pocos das, es perfectamente razonable asig narle una etiqueta a cada una de ellas. Pero si tiene un sistema de construcci n autom tica de binarios que asegura o a 82

que cada revisi n puede generarse limpiamente, estara introduciendo mucho ruido si se usara una etiqueta para cao da generaci n exitosa. M s bien, podra usar tags para generaciones fallidas (en caso de que estas sean raras!), o o a simplemente evitar las etiquetas para llevar cuenta de la posibilidad de generaci n de binarios. o Si quiere eliminar una etiqueta que no desea, use hg tag --remove.
1 2 3

$ hg tag --remove v1.0 $ hg tags tip

3:31eda97c4db9

Tambi n puede modicar una etiqueta en cualquier momento, para que identique una revisi n distinta, simplemente e o usando una nueva orden hg tag. Deber usar la opci n -f para indicarle a Mercurial que realmente desea actualizar a o la etiqueta.
1 2 3 4 5 6 7 8 9 10

$ hg tag -r 1 v1.1 $ hg tags tip 4:eb33d1c642f4 v1.1 1:515e5c86f496 $ hg tag -r 2 v1.1 abort: tag v1.1 already exists (use -f to force) $ hg tag -f -r 2 v1.1 $ hg tags tip 5:b26c4daf4a9d v1.1 2:55d99d62d333 De todas maneras habr un registro permanente de la antigua identidad de la etiqueta, pero Mercurial no la usar . a a Por lo tanto no hay problema al marcar con una etiqueta una revisi n incorrecta; lo unico que debe hacer es mover la o etiqueta hacia la revisi n correcta tan pronto como localice el error. o Mercurial almacena las etiquetas en un chero controlado por revisiones en su repositorio. Si ha creado etiquetas, las encontrar en un chero llamado .hgtags. Cuando invoca la orden hg tag, Mercurial modica este chero, a y hace la consignaci n del cambio al mismo autom ticamente. Esto signica que cada vez que ejecuta hg tag, o a ver un conjunto de cambios correspondiente en la salida de hg log. a

1 2 3 4 5 6 7

$ hg tip changeset: tag: user: date: summary:

5:b26c4daf4a9d tip Bryan OSullivan <bos@serpentine.com> Tue Feb 10 18:23:30 2009 +0000 Added tag v1.1 for changeset 55d99d62d333

8.1.1.

Manejo de conictos entre etiquetas durante una fusi n o

Usualmente no tendr que preocuparse por el chero .hgtags, pero a veces hace su aparici n durante una fusi n. a o o El formato del chero es sencillo: Consiste de una serie de lneas. Cada lnea comienza con un hash de conjunto de cambios, seguido por un espacio, seguido por el nombre de una etiqueta. Si est resolviendo un conicto en el chero .hgtags durante una fusi n, hay un detalle para tener en cuenta al a o modicar el chero .hgtags: cuando Mercurial procesa las etiquetas en el repositorio, nunca lee la copia de trabajo del chero .hgtags. En cambio, lee la versi n consignada m s reciente del chero. o a Una consecuencia desafortunada de este dise o es que usted no puede vericar que su chero .hgtags fusionn ado sea correcto hasta despu s de haber consignado un cambio. As que si se encuentra resolviendo un conicto en e .hgtags durante una fusi n, aseg rese de ejecutar la orden hg tags despu s de consignar. Si encuentra un error o u e en el chero .hgtags, la orden reportar el lugar del error, que podr arreglar y despu s consignar. Posteriormente a a e ejecute de nuevo la orden hg tags para asegurarse de que su arreglo fue aplicado correctamente . 83

8.1.2.

Etiquetas y clonado

Puede haber notado que la orden hg clone tiene la opci n -r que le permite clonar una copia exacta del o repositorio hasta un conjunto de cambios especco. El nuevo clon no tendr historial posterior a la revisi n que usted a o haya especicado. Esto tiene una interacci n con etiquetas que puede sorprender a los desprevenidos. o Recuerde que una etiqueta se almacena como una revisi n al chero .hgtags, as que cuando usted crea una etio queta, el conjunto de cambios en el cual esta se almacena necesariamente se reere a un conjunto de cambios anterior. Cuando ejecuta hg clone -r foo para clonar un repositorio hasta la etiqueta foo, el nuevo clon no contendr el a historial que creo la etiqueta que us para clonar el repositorio. El resultado es que tendr exactamente el subconjunto o a correcto del historial del proyecto en el nuevo repositorio, pero, no la etiqueta que podra haber esperado.

8.1.3.

Cuando las etiquetas permanentes son demasiado

Dado que las etiquetas de Mercurial est n controladas por revisiones y se llevan en el historial del proyecto, todas a las personas involucradas ver n las etiquetas que usted haya creado. El hecho de dar nombres a las revisiones tiene a usos m s all que simplemente hacer notar que la revisi n 4237e45506ee es realmente v2.0.2. Si est tratando de a a o a encontrar un fallo sutil, posiblemente deseara colocar una etiqueta record ndole algo como Ana vio los sntomas en a esta revisi n. o Para estos casos, lo que usted posiblemente deseara seran etiquetas locales. Puede crear una etiqueta local con la opci n -l de la orden hg tag. Esto guardar la etiqueta en un chero llamado .hg/localtags. A diferencia de o a .hgtags, .hg/localtags no est controlado por revisiones. Cualquier etiqueta que usted cree usando -l se mantena dr local al repositorio en el que est trabajando en ese momento. a e

8.2.

El ujo de cambiosEl gran cuadro vs. el pequeno

Retomando lo mencionado en el comienzo de un captulo, pensemos en el hecho de que un proyecto tiene muchas piezas concurrentes de trabajo en desarrollo al mismo tiempo. Puede haber prisa por una nueva versi n principal; una nueva versi n con un arreglo de fallo a la ultima versi n; o o o y una versi n de mantenimiento correctivo a una versi n antigua que ha entrado en modo de mantenimiento. o o Usualmente la gente se reere a esas direcciones concurrentes de desarrollo como ramas. Sin embargo, ya hemos visto que en varias ocasiones Mercurial trata a todo el historial como una serie de ramas y fusiones. Realmente lo que tenemos aqu es dos ideas que se relacionan perif ricamente, pero que en esencia comparten un nombre. e El gran cuadro Las ramas representan un barrido de la evoluci n del proyecto; la gente les da nombres y o hablan acerca de ellas en sus conversaciones. El cuadro peque o Las ramas son artefactos de las actividades diarias de desarrollar y fusionar cambios. n Exponen la narrativa de c mo se desarroll el c digo. o o o

8.3.

Administrar ramas en repositorios estilo gran cuadro

En Mercurial la forma m s sencilla de aislar una rama del gran cuadro es a trav s de un repositorio dedicaa e do. Si cuenta con un repositorio compartido existente llam moslo myprojectque alcanz la etapa 1.0, puede e o comenzar a prepararse para versiones de mantenimiento futuras a partir de la versi n 1.0 marcando con una etiqueta o la revisi n con la cual prepar la versi n 1.0. o o o
1 2

$ cd myproject $ hg tag v1.0 Ahora puede clonar un repositorio compartido nuevo myproject-1.0.1 con tal etiqueta.

84

1 2 3 4

$ cd .. $ hg clone myproject myproject-1.0.1 updating working directory 2 files updated, 0 files merged, 0 files removed, 0 files unresolved Posteriormente, si alguien necesita trabajar en la reparaci n de un fallo debera dirigirse a la liberaci n de vero o si n 1.0.1 que viene en camino, ellos clonaran el repositorio myproject-1.0.1, haran sus cambios y los empujaran o de vuelta.

1 2 3 4 5 6 7 8 9 10 11 12 13

$ hg clone myproject-1.0.1 my-1.0.1-bugfix updating working directory 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd my-1.0.1-bugfix $ echo I fixed a bug using only echo! >> myfile $ hg commit -m Important fix for 1.0.1 $ hg push pushing to /tmp/branch-repo07QkL5/myproject-1.0.1 searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files Mientras tanto, el desarrollo para la siguiente versi n mayor puede continuar aislado e inc lume, en el repositorio o o myproject.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

$ cd .. $ hg clone myproject my-feature updating working directory 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd my-feature $ echo This sure is an exciting new feature! > mynewfile $ hg commit -A -m New feature adding mynewfile $ hg push pushing to /tmp/branch-repo07QkL5/myproject searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files

8.4.

No repita trabajo: fusi n entre ramas o

En muchos casos, cuando tiene un fallo para arreglar en una rama de mantenimiento, es muy probable que el fallo tambi n est en la rama principal (y posiblemente en otras ramas de mantenimiento tambi n). Solamente un e e e desarrollador extra o deseara corregir el mismo fallo muchas veces, por tanto, veremos varias alternativas con las que n Mercurial puede ayudarle a administrar tales arreglos de fallo sin duplicar su trabajo. En el caso m s sencillo, basta con jalar los cambios de la rama de mantenimiento a la rama objetivo en su clon a local. 85

1 2 3 4 5 6 7 8 9 10 11 12 13

$ cd .. $ hg clone myproject myproject-merge updating working directory 3 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd myproject-merge $ hg pull ../myproject-1.0.1 pulling from ../myproject-1.0.1 searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files (+1 heads) (run hg heads to see heads, hg merge to merge) A continuaci n deber mezclar las cabezas de las dos ramas, y empujar de nuevo a la rama principal. o a

1 2 3 4 5 6 7 8 9 10 11

$ hg merge 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, dont forget to commit) $ hg commit -m Merge bugfix from 1.0.1 branch $ hg push pushing to /tmp/branch-repo07QkL5/myproject searching for changes adding changesets adding manifests adding file changes added 2 changesets with 1 changes to 1 files

8.5.

Nombrar ramas dentro de un repositorio

La aproximaci n correcta en casi todas las oportunidades es aislar las ramas en los repositorios. Es f cil de entender o a gracias a su simplicidad; y es difcil cometer errores. Hay una relaci n uno a uno entre las ramas y los directorios con o los que est trabajando en su sistema. Esto le permite usar emplear herramientas usuales (que no son conscientes de a Mercurial) para trabajar con los cheros dentro de una rama/repositorio. Si se encuentra m s en la categora usuario diestro (y sus colaboradores tambi n), puede considerar otra altera e nativa para administrar las ramas. He mencionado con anterioridad la distinci n a nivel humano entre las ramas estilo o cuadro peque o y gran cuadro. Mientras que Mercurial trabaja con muchas ramas del estilo cuadro peque o n n en el repositorio todo el tiempo (por ejemplo cuando usted jala cambios, pero antes de fusionarlos), tambi n puede e trabajar con varias ramas del cuadro grande. El truco para trabajar de esta forma en Mercurial se logra gracias a que puede asignar un nombre persistente a una rama. Siempre existe una rama llamada default. Incluso antes de que empiece a nombrar ramas por su cuenta, puede encontrar indicios de la rama default si los busca. Por ejemplo, cuando invoca la orden hg commit, y se lanza su editor para introducir el mensaje de la consignaci n, o busque la lnea que contiene el texto HG: branch default al nal. Le est indicando que su consignaci n ocur a o rir en la rama llamada default. a Use la orden hg branches para empezar a trabajar con ramas nombradas. Esta orden mostrar las ramas prea sentes en su repositorio, indic ndole qu conjunto de cambios es la punta de cada una. a e
1 2

$ hg tip changeset:

0:c54ce9a68981 86

3 4 5 6 7 8 9

tag: user: date: summary:

tip Bryan OSullivan <bos@serpentine.com> Tue Feb 10 18:23:16 2009 +0000 Initial commit

$ hg branches default

0:c54ce9a68981

Dado que todava no ha creado ramas nombradas, la unica que ver ser default. a a Para hallar cu l es la rama actual, invoque la orden hg branch, sin argumento alguno. Le informar en qu raa a e ma se encuentra el padre del conjunto de cambios actual.
1 2

$ hg branch default Para crear una nueva rama, invoque la orden hg branch de nuevo. En esta oportunidad, ofrezca un argumento: el nombre de la rama que desea crear.

1 2 3 4

$ hg branch foo marked working directory as branch foo $ hg branch foo Despu s de crear la rama, usted podra desear ver el efecto que tuvo la orden hg branch. Qu reportan las e e ordenes hg status y hg tip?

1 2 3 4 5 6 7 8

$ hg status $ hg tip changeset: 0:c54ce9a68981 tag: tip user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:16 2009 +0000 summary: Initial commit

Nada cambia en el directorio actual, y no se ha a adido nada al historial. Esto sugiere que al ejecutar la orden hg n branch no hay un efecto permanente; solamente le indica a que nombre de rama usar la pr xima vez que consigne a o un conjunto de cambios. Cuando consigna un cambio, Mercurial almacena el nombre de la rama en la cual consign . Una vez que haya o cambiado de la rama default y haya consignado, ver que el nombre de la nueva rama se mostrar cuando use la a a orden hg log, hg tip, y otras ordenes que desplieguen la misma clase de informaci n. o
1 2 3 4 5 6 7 8 9 10

$ echo hello again >> myfile $ hg commit -m Second commit $ hg tip changeset: 1:b108bc883cbc branch: foo tag: tip user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:17 2009 +0000 summary: Second commit

87

Las ordenes del tipo hg log imprimir n el nombre de la rama de cualquier conjunto de cambios que no est en la a e rama default. Como resultado, si nunca usa ramas nombradas, nunca ver esta informaci n. a o Una vez que haya nombrado una rama y consignado un cambio con ese nombre, todas las consignaciones subsecuentes que desciendan de ese cambio heredar n el mismo nombre de rama. Puede cambiar el nombre de una rama en a cualquier momento con la orden hg branch.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

$ hg branch foo $ hg branch bar marked working directory as branch bar $ echo new file > newfile $ hg commit -A -m Third commit adding newfile $ hg tip changeset: 2:7f37f4b1f9a3 branch: bar tag: tip user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:17 2009 +0000 summary: Third commit

Esto es algo que no har muy seguido en la pr ctica, debido que los nombres de las ramas tienden a tener vidas largas. a a (Esto no es una regla, solamente una observaci n.) o

8.6.

Tratamiento de varias ramas nombradas en un repositorio

Si tiene m s de una rama nombrada en un repositorio, Mercurial recordar la rama en la cual est su directorio de a a a trabajo cuando invoque una orden como hg update o hg pull -u. Se actualizar su directorio de trabajo actual a a la punta de esta rama, sin importar cu l sea la punta a lo largo del repositorio. Para actualizar a una revisi n que a o est en una rama con distinto nombre, puede necesitar la opci n -C de hg update. a o Este comportamiento puede ser sutil, as que ve moslo en acci n. Primero, recordemos en qu rama estamos a o e trabajando, y qu ramas est n en nuestro repositorio. e a
1 2 3 4 5 6 7 8 9 10 11 12

$ hg parents changeset: 2:7f37f4b1f9a3 branch: bar tag: tip user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:17 2009 +0000 summary: Third commit $ hg branches bar foo default

2:7f37f4b1f9a3 1:b108bc883cbc (inactive) 0:c54ce9a68981 (inactive)

Estamos en la rama bar, pero existe otra rama m s antigua llamada hg foo. a Podemos hacer hg update entre los tipos de las ramas foo y bar sin necesidad de usar la opci n -C, puesto que o esto solamente implica ir linealmente hacia adelante y atr s en nuestro historial de cambios. a

88

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

$ hg update foo 0 files updated, 0 files merged, 1 files removed, 0 files unresolved $ hg parents changeset: 1:b108bc883cbc branch: foo user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:17 2009 +0000 summary: Second commit $ hg update bar 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg parents changeset: 2:7f37f4b1f9a3 branch: bar tag: tip user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:17 2009 +0000 summary: Third commit

Si volvemos a la rama foo e invocamos la orden hg update, nos mantendr en foo, sin movernos a la punta de a bar.
1 2 3 4

$ 0 $ 0

hg update foo files updated, 0 files merged, 1 files removed, 0 files unresolved hg update files updated, 0 files merged, 0 files removed, 0 files unresolved Al consignar un cambio a la rama foo se introducir una nueva cabeza. a

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

$ echo something > somefile $ hg commit -A -m New file adding somefile created new head $ hg heads changeset: 3:1ca81328634a branch: foo tag: tip parent: 1:b108bc883cbc user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:17 2009 +0000 summary: New file changeset: branch: user: date: summary: 2:7f37f4b1f9a3 bar Bryan OSullivan <bos@serpentine.com> Tue Feb 10 18:23:17 2009 +0000 Third commit

89

8.7.

Nombres de ramas y fusiones

Posiblemente ha notado que las fusiones en Mercurial no son sim tricas. Supongamos que su repositorio tiene dos e cabezas, 17 y 23. Si yo invoco hg update a 17 y aplico hg merge a 23, Mercurial almacena 17 como el primer padre de la fusi n, y 23 como el segundo. Mientras que si hago hg update a 23 y despu s aplico hg merge con o e 17, grabar a 23 como el primer padre, y 17 como el segundo. a Esto afecta el c mo elige Mercurial el nombre de la rama cuando usted hace la fusi n. Despu s de una fusi n, o o e o Mercurial mantendr el nombre de la rama del primer padre cuando consigne el resultado de la fusi n. Si el primer a o nombre de su padre es foo, y fusiona con bar, el nombre de la rama continuar siendo foo despu s de fusionar. a e No es inusual que un repositorio contenga varias cabezas, cada una con el mismo nombre de rama. Digamos que estoy trabajando en la rama foo, y usted tambi n. Consignamos cambios distintos; yo jalo sus cambios; Ahora tengo e dos cabezas, cada una armando estar en la rama foo. El resultado de una fusi n ser una unica cabeza en la rama foo o a como usted esperara. Pero si estoy trabajando en la rama bar, y fusiono el trabajo de la rama foo, el resultado permanecer en la rama a bar.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

$ hg branch bar $ hg merge foo 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, dont forget to commit) $ hg commit -m Merge $ hg tip changeset: 4:a6a8b6aebf33 branch: bar tag: tip parent: 2:7f37f4b1f9a3 parent: 3:1ca81328634a user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:17 2009 +0000 summary: Merge

En un ejemplo m s concreto, si yo estoy trabajando en la rama bleeding-edge, y deseo traer los arreglos m s a a recientes de la rama estable, Mercurial elegir el nombre de rama correcto (bleeding-edge) cuando yo jale una a fusi n desde estable. o

8.8.

Normalmente es util nombrar ramas

No debera considerar que las ramas nombradas son aplicables unicamente en situaciones con muchas ramas de larga vida cohabitando en un mismo repositorio. Son muy utiles incluso en los casos de una rama por repositorio. En el caso m s sencillo, dar un nombre a cada rama ofrece un registro permanente acerca de en qu conjunto de a e cambios se gener la rama. Esto le ofrece m s contexto cuando est tratando de seguir el historial de un proyecto o a e ramicado de larga vida. Si est trabajando con repositorios compartidos, puede congurar el gancho pretxnchangegroup para que cada a uno bloquee los cambios con nombres de rama incorrectos que est n por adicionarse. Este provee una defensa a sencilla, pero efectiva, para evitar que la gente publique accidentalmente cambios de una rama super nueva a la rama estable. Tal gancho podra verse de la siguiente forma dentro de un repositorio compartido de hgrc.
1 2

[hooks] pretxnchangegroup.branch = hg heads --template branches | grep mybranch

90

Captulo 9

Encontrar y arreglar sus equivocaciones


Errar es humano, pero tratar adecuadamente las consecuencias requiere un sistema de control de revisiones de primera categora. En este captulo, discutiremos algunas t cnicas que puede usar cuando encuentra que hay un prob e lema enraizado en su proyecto. Mercurial tiene unas caractersticas poderosas que le ayudar n a isolar las fuentes de a los problemas, y a dar cuenta de ellas apropiadamente.

9.1.
9.1.1.

Borrar el historial local


La consignaci n accidental o

Tengo el problema ocasional, pero persistente de teclear m s r pido de lo que pienso, que aveces resulta en a a consignar un conjunto de cambios incompleto o simplemente malo. En mi caso, el conjunto de cambios incompleto consiste en que cre un nuevo chero fuente, pero olvid hacerle hg add. Un conjunto de cambiossimplemente e e malo no es tan com n, pero s resulta muy molesto. u

9.1.2.

Hacer rollback una transacci n o

En la secci n 4.2.2, mencion que Mercurial trata modicaci n a un repositorio como una transacci n. Cada vez o e o o que consigna un conjunto de cambios o lo jala de otro repositorio, Mercurial recuerda lo que hizo. Puede deshacer, o hacer roll back1 , exactamente una de tales acciones usando la orden hg rollback. (Ver en la secci n 9.1.4 una o anotaci n importante acerca del uso de esta orden.) o A continuaci n una equivocaci n que me sucede frecuentemente: consignar un cambio en el cual he creado un o o nuevo chero, pero he olvidado hacerle hg add.
1 2 3 4

$ M $ $

hg status a echo b > b hg commit -m Add file b

La salida de hg status despu s de la consignaci n conrma inmediatamente este error. e o


1 2 3 4 5

$ hg status ? b $ hg tip changeset: 1:be1cdd4c4fea tag: tip


1 N. del T. El signicado igual que en los ambientes de sistemas manejadores de bases de datos se reere a la atomicidad e integridad al devolver un conjunto de acciones que permitan dejar el repositorio en un estado consistente previo

91

6 7 8 9

user: date: summary:

Bryan OSullivan <bos@serpentine.com> Tue Feb 10 18:23:29 2009 +0000 Add file b

La consignaci n captur los cambios en el chero a, pero no el nuevo chero b. Si yo publicara este conjunto de o o cambios a un repositorio compartido con un colega, es bastante probable que algo en a se reriera a b, el cual podra no estar presente cuando jalen mis cambios del repositorio. Me convertira el sujeto de cierta indignaci n. o Como sea, la suerte me acompa aEncontr mi error antes de publicar el conjunto de cambios. Uso la orden hg n e rollback, y Mercurial hace desaparecer el ultimo conjunto de cambios.
1 2 3 4 5 6 7 8 9 10 11 12

$ hg rollback rolling back last transaction $ hg tip changeset: 0:c40e0a2ea41e tag: tip user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:29 2009 +0000 summary: First commit $ hg status M a ? b El conjunto de cambios ya no est en el historial del repositorio, y el directorio de trabajo cree que el chero a ha a sido modicado. La consignaci n y el roll back dejaron el directorio de trabajo exactamente como estaba antes de la o consignaci n; el conjunto de cambios ha sido eliminado totlamente. Ahora puedo hacer hg add al chero b, y hacer o de nuevo la consignaci n. o

1 2

$ hg add b $ hg commit -m Add file b, this time for real

9.1.3.

Erroneamente jalado

Mantener ramas de desarrollo separadas de un proyecto en distintos repositorios es una pr ctica com n con Mercua u rial. Su equipo de desarrollo puede tener un repositorio compartido para la versi n 0.9 y otra con cambios distintos o para la versi n 1.0. o Con este escenario, puede imaginar las consecuencias si tuviera un repositorio local 0.9, y jalara accidentalmente los cambios del repositorio compartido de la versi n 1.0 en este. En el peor de los casos, por falta de atenci n, es o o posible que publique tales cambios en el arbol compartido 0.9, confundiendo a todo su equipo de trabajo (pero no se preocupe, volveremos a este terrorco escenario posteriormente). En todo caso, es muy probable que usted se de cuenta inmediatamente, dado que Mercurial mostrar el URL de donde est jalando, o que vea jalando una sospechosa a a gran cantidad de cambios en el repositorio. La orden hg rollback excluir ecientemente los conjuntos de cambios que haya acabado de jalar. Mercurial a agrupa todos los cambios de un hg pull a una unica transacci n y bastar con un hg rollback para deshacer o a esta equivocaci n. o

9.1.4.

Despu s de publicar, un roll back es futil e

El valor de hg rollback se anula cuando ha publicado sus cambios a otro repositorio. Un cambio desaparece totalmente al hacer roll back, pero solamente en el repositorio en el cual aplica hg rollback. Debido a que un roll back elimina el historial, no hay forma de que la desaparici n de un cambio se propague entre repositorios. o 92

Si ha publicado un cambio en otro repositorioparticularmente si es un repositorio p blicoesencialmente u est en terreno agreste, y tendr que reparar la equivocaci n de un modo distinto. Lo que pasar si publica un a a o a conjunto de cambios en alg n sitio, hacer rollback y despu s volver a jalar del repositorio del cual haba publicado, es u e que el conjunto de cambios reaparecer en su repositorio. a (Si est absolutamente segruro de que el conjunto de cambios al que desea hacer rollback es el cambio m s reciente a a del repositorio en el cual public , y sabe que nadie m s pudo haber jalado de tal repositorio, puede hacer rollback del o a conjunto de cambios all, pero es mejor no conar en una soluci n de este estilo. Si lo hace, tarde o temprano un o conjunto de cambios lograr colarse en un repositorio que usted no controle directamente (o del cual se ha olvidado), a y volver a hostigarle.) a

9.1.5.

Solamente hay un roll back

Mercurial almacena exactamente una transacci n en su bit cora de transacciones; tal transacci n es la m s reciente o a o a de las que haya ocurrido en el repositorio. Esto signica que solamente puede hacer roll back a una transacci n. Si o espera poder hacer roll back a una transacci n despu s al antecesor, observar que no es el comportamiento que o e a obtendr . a
1 2 3 4

$ hg rollback rolling back last transaction $ hg rollback no rollback information available Una vez que haya aplicado un rollback en una transacci n a un repositorio, no podr volver a hacer rollback hasta que o a haga una consignaci n o haya jalado. o

9.2.

Revertir un cambio equivocado

Si modica un chero y se da cuenta que no quera realmente cambiar tal chero, y todava no ha consignado los cambios, la orden necesaria es hg revert. Observa el conjunto de cambios padre del directorio y restaura los contenidos del chero al estado de tal conjunto de cambios. (Es una forma larga de decirlo, usualmente deshace sus modicaciones.) Ilustremos como act a la orden hg revert con un ejemplo peque o. Comenzaremos modicando un chero al u n cual Mercurial ya est siguiendo. a
1 2 3 4 5 6 7 8 9 10

$ cat file original content $ echo unwanted change >> file $ hg diff file diff -r f8694d2c79ed file --- a/file Tue Feb 10 18:23:21 2009 +0000 +++ b/file Tue Feb 10 18:23:21 2009 +0000 @@ -1,1 +1,2 @@ original content +unwanted change Si no queremos ese cambio, podemos aplicar hg revert al chero.

1 2 3 4 5

$ hg status M file $ hg revert file $ cat file original content 93

La orden hg revert nos brinda un grado adicional de seguridad guardando nuestro chero modicado con la extensi n .orig. o
1 2 3 4 5

$ hg status ? file.orig $ cat file.orig original content unwanted change Este es un resumen de casos en los cuales la orden hg revert es de utilidad. Describiremos cada uno de ellos con m s detalle en la secci n siguiente. a o Si usted modica un chero, lo restaurar a su estado sin modicaci n previo. a o Si usted hace hg add a un chero, revertir el estado de adicionado del chero, pero no lo tocar a a Si borra un chero sin decirle a Mercurial, restaurar el chero con sus contenidos sin modicaci n. a o Si usa la orden hg remove para eliminar un chero, deshar el estado removido del chero, y lo restaua rar con sus contenidos sin modicaci n. a o

9.2.1.

Errores al administrar cheros

La orden hg revert es util para m s que cheros modicados. Le permite reversar los resultados de todas las a ordenes de administraci n de cheros que provee Mercurialhg add, hg remove, y las dem s. o a Si usted hace hg add a un chero, y no deseaba que Mercurial le diera seguimiento, use hg revert para deshacer la adici n. No se preocupe; Mercurial no modicar de forma alguna el chero. Solamente lo desmarcar . o a a
1 2 3 4 5 6 7

$ $ $ A $ $ ?

echo oops > oops hg add oops hg status oops oops hg revert oops hg status oops

De forma similar, Si le solicita a Mercurial hacer hg remove a un chero, puede usar hg revert para restarurarlo a los contenidos que tena la revisi n padre del directorio de trabajo. o
1 2 3 4 5 6 7

$ hg remove file $ hg status R file $ hg revert file $ hg status $ ls file file Funciona de la misma manera para un chero que usted haya eliminado manualmente, sin decirle a Mercurial (recuerde que en la terminologa de Mercurial esta clase de chero se llama faltante).

1 2 3 4

$ $ ! $

rm file hg status file hg revert file 94

5 6

$ ls file file Si usted revierte un hg copy, el chero a donde se copi permanece en su directorio de trabajo, pero sin o seguimiento. Dado que una copia no afecta el chero fuente de copiado de ninguna maner, Mercurial no hace nada con este.

1 2 3 4

$ $ $ ?

hg copy file new-file hg revert new-file hg status new-file

Un caso ligeramente especial:revertir un renombramiento Si hace hg rename a un chero, hay un detalle que debe tener en cuenta. Cuando aplica hg revert a un cambio de nombre, no es suciente proveer el nombre del chero destino, como puede verlo en el siguiente ejemplo.
1 2 3 4

$ $ $ ?

hg rename file new-file hg revert new-file hg status new-file

Como puede ver en la salida de hg status, el chero con el nuevo nombre no se identica m s como agregado, a pero el chero con el nombre-inicial se elimna! Esto es contra-intuitivo (por lo menos para m), pero por lo menos es f cil arreglarlo. a
1 2 3 4

$ hg revert file no changes needed to file $ hg status ? new-file Por lo tanto, recuerde, para revertir un hg rename, debe proveer ambos nombres, la fuente y el destino. (A prop sito, si elimina un chero, y modica el chero con el nuevo nombre, al revertir ambos componentes o del renombramiento, cuando Mercurial restaure el chero que fue eliminado como parte del renombramiento, no ser modicado. Si necesita que las modicaciones en el chero destino del renombramiento se muestren, no olvide a copiarlas encima.) Estos aspectos engorrosos al revertir un renombramiento se constituyen discutiblemente en un fallo de Mercurial.

9.3.

Tratar cambios consignados

Considere un caso en el que ha consignado el cambio a, y otro cambio b sobre este; se ha dado cuenta que el cambio a era incorrecto. Mercurial le permite retroceder un conjunto de cambios completo autom ticamente, y a construir bloques que le permitan revertir parte de un conjunto de cambios a mano. Antes de leer esta secci n, hay algo para tener en cuenta: la orden hg backout deshace cambios adicionando o al historial, sin modicar o borrar. Es la herramienta correcta si est arreglando fallos, pero no si est tratando de a a deshacer alg n cambio que tiene consecuencias catastr cas. Para tratar con esos, vea la secci n 9.4. u o o

9.3.1.

Retroceder un conjunto de cambios

La orden hg backout le permite deshacer los efectos de todo un conjunto de cambios de forma automatizada. Dado que el historial de Mercurial es inmutable, esta orden no se deshace del conjunto de cambios que usted desea deshacer. En cambio, crea un nuevo conjunto de cambios que reversa el conjunto de cambios que usted indique. 95

La operaci n de la orden hg backout es un poco intrincada, y lo ilustraremos con algunos ejemplos. Primero o crearemos un repositorio con algunos cambios sencillos.
1 2 3 4 5 6 7

$ $ $ $ $ $ $

hg init myrepo cd myrepo echo first change >> myfile hg add myfile hg commit -m first change echo second change >> myfile hg commit -m second change

La orden hg backout toma un ID de conjunto de cambios como su argumento; el conjunto de cambios a retroceder. Normalmente hg backout le ofrecer un editor de texto para escribir el mensaje de la consignaci n, a o para dejar un registro de por qu est retrocediendo. En este ejemplo, colocamos un mensaje en la consignaci n e a o usando la opci n -m. o

9.3.2.

Retroceder el conjunto de cambios punta

Comenzamos retrocediendo el ultimo conjunto de cambios que consignamos.


1 2 3 4 5

$ hg backout -m back out second change tip reverting myfile changeset 2:1d9ee76a7513 backs out changeset 1:cab6a78bf14b $ cat myfile first change Puede ver que la segunda lnea de myfile ya no est presente. La salida de hg log nos da una idea de lo que la a orden hg backout ha hecho.

1 2 3 4 5 6 7 8 9 10

$ hg log --style compact 2[tip] 1d9ee76a7513 2009-02-10 18:23 +0000 back out second change 1 cab6a78bf14b second change 60b8d10ede6c first change 2009-02-10 18:23 +0000 bos

bos

2009-02-10 18:23 +0000

bos

Vea que el nuevo conjunto de cambios que hg backout ha creado es un hijo del conjunto de cambios que retrocedimos. Es m s sencillo de ver en la gura 9.1, que presenta una vista gr ca del historial de cambios. Como puede ver, a a el historial es bonito y lineal.

9.3.3.

Retroceso de un cambio que no es la punta

Si desea retrocede un cambio distinto al ultimo que ha consignado, use la opci n --merge a la orden hg backout. o
1 2 3 4

$ cd .. $ hg clone -r1 myrepo non-tip-repo requesting all changes adding changesets 96

primer cambio

segundo cambio

reversar segundo cambio


Figura 9.1: Retroceso de un cambio con la orden hg backout
5 6 7 8 9 10

adding manifests adding file changes added 2 changesets with 2 changes to 1 files updating working directory 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd non-tip-repo Que resulta en un retroceso de un conjunto de cambios en un s lo tiro, una operaci n que resulta normalmente o o r pida y sencilla. a

1 2 3 4 5 6 7 8 9 10

$ echo third change >> myfile $ hg commit -m third change $ hg backout --merge -m back out second change 1 reverting myfile created new head changeset 3:688f1a6067e5 backs out changeset 1:cab6a78bf14b merging with changeset 3:688f1a6067e5 merging myfile 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, dont forget to commit) Si ve los contenidos del chero myfile despu s de nalizar el retroceso, ver que el primer y el tercer cambio e a est n presentes, pero no el segundo. a

1 2 3

$ cat myfile first change third change Como lo muestra el historial gr co en la gura 9.2, Mercurial realmente consigna dos cambios en estas situaciones a (los nodos encerrados en una caja son aquellos que Mercurial consigna automaticamente). Antes de que Mercurial comience el proceso de retroceso, primero recuerda cu l es el padre del directorio de trabajo. Posteriormente hace un a 97

retroceso al conjunto de cambios objetivo y lo consigna como un conjunto de cambios. Finalmente, fusiona con el padre anterior del directorio de trabajo, y consigna el resultado de la fusi n. o

primer cambio

automatizar fusin

segundo cambio

tercer cambio

reversar segundo cambio

fusin
Figura 9.2: Retroceso automatizado de un cambio a algo que no es la punta con la orden hg backout El resultado es que usted termina donde estaba, solamente con un poco de historial adicional que deshace el efecto de un conjunto de cambios que usted quera evitar. Use siempre la opci n --merge o De hecho, dado que la opci n --merge siempre hara lo correcto est o no retrocediendo el conjunto de cambios o e punta (p.e. no tratar de fusionar si est retrocediendo la punta, dado que no es necesario), usted debera usar siempre a a esta opci n cuando ejecuta la orden hg backout. o

9.3.4.

M s control sobre el proceso de retroceso a

A pesar de que recomiendo usar siempre la opci n --merge cuando est retrocediendo un cambio, la orden hg o a backout le permite decidir c mo mezclar un retroceso de un conjunto de cambios. Es muy extra o que usted necestite o n tomar control del proceso de retroceso de forma manual, pero puede ser util entender lo que la orden hg backout est haciendo autom ticamente para usted. Para ilustrarlo, clonemos nuestro primer repositorio, pero omitamos el a a retroceso que contiene.
1 2 3 4 5 6 7

$ cd .. $ hg clone -r1 myrepo newrepo requesting all changes adding changesets adding manifests adding file changes added 2 changesets with 2 changes to 1 files 98

8 9 10

updating working directory 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd newrepo Como en el ejemplo anterior, consignaremos un tercer cambio, despu s haremos retroceso de su padre, y veremos e qu pasa. e

1 2 3 4 5 6 7 8

$ echo third change >> myfile $ hg commit -m third change $ hg backout -m back out second change 1 reverting myfile created new head changeset 3:688f1a6067e5 backs out changeset 1:cab6a78bf14b the backout changeset is a new head - do not forget to merge (use "backout --merge" if you want to auto-merge) Nuestro nuevo conjunto de cambios es de nuevo un descendiente del conjunto de cambio que retrocedimos; es por lo tanto una nueva cabeza, no un descendiente del conjunto de cambios que era la punta. La orden hg backout fue muy explcita dici ndolo. e

1 2 3 4 5 6 7 8 9 10 11 12 13

$ hg log --style compact 3[tip]:1 688f1a6067e5 2009-02-10 18:23 +0000 back out second change 2 72a18afb4ae5 third change cab6a78bf14b second change 60b8d10ede6c first change 2009-02-10 18:23 +0000 bos

bos

2009-02-10 18:23 +0000

bos

2009-02-10 18:23 +0000

bos

De nuevo, es m s sencillo lo que pas viendo una gr ca del historial de revisiones, en la gura 9.3. Esto nos a o a aclara que cuando usamos hg backout para retroceder un cambio a algo que no sea la punta, Mercurial a ade una n nueva cabeza al repositorio (el cambio que consign est encerrado en una caja). o a Despu s de que la orden hg backout ha terminado, deja un nuevo conjunto de cambios de retroceso como el e padre del directorio de trabajo.
1 2 3 4 5 6

$ hg parents changeset: 2:72a18afb4ae5 user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:13 2009 +0000 summary: third change

Ahora tenemos dos conjuntos de cambios aislados.


1 2 3

$ hg heads changeset: 3:688f1a6067e5 tag: tip 99

primer cambio

segundo cambio

tercer cambio

reversar segundo cambio

Figura 9.3: Retroceso usando la orden hg backout


4 5 6 7 8 9 10 11 12 13

parent: user: date: summary: changeset: user: date: summary:

1:cab6a78bf14b Bryan OSullivan <bos@serpentine.com> Tue Feb 10 18:23:13 2009 +0000 back out second change 2:72a18afb4ae5 Bryan OSullivan <bos@serpentine.com> Tue Feb 10 18:23:13 2009 +0000 third change

Reexionemos acerca de lo que esperamos ver como contenidos de myfile. El primer cambio debera estar pre sente, porque nunca le hicimos retroceso. El segundo cambio debi desaparecer, puesto que es el que retrocedimos. o Dado que la gr ca del historial muestra que el tercer camlio es una cabeza separada, no esperamos ver el tercer a cambio presente en myfile.
1 2 3 4

$ cat myfile first change second change third change Para que el tercer cambio est en el chero, hacemos una fusi n usual de las dos cabezas. e o

1 2 3 4 5 6 7 8

$ hg merge merging myfile 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, dont forget to commit) $ hg commit -m merged backout with previous tip $ cat myfile first change third change Despu s de eso, el historial gr ca de nuestro repositorio luce como la gura 9.4. e a 100

primer cambio

segundo cambio

tercer cambio

reversar segundo cambio

fusin manual
Figura 9.4: Fusi n manual de un retroceso o

9.3.5.

Por qu hg backout hace lo que hace e

Esta es una descripci n corta de c mo trabaja la orden hg backout. o o 1. Se asegura de que el directorio de trabajo es limpio, esto es, que la salida de hg status debera ser vaca. 2. Recuerda el padre actual del directorio de trabajo. A este conjunto de cambio lo llamaremos orig 3. Hace el equivalente de un hg update para sincronizar el directorio de trabajo con el conjunto de cambios que usted quiere retroceder. Lo llamaremos backout 4. Encuentra el padre del conjunto de cambios. Lo llamaremos parent. 5. Para cada chero del conjunto de cambios que el retroceso afecte, har el equivalente a hg revert -r a parent sobre ese chero, para restaurarlo a los contenidos que tena antes de que el conjunto de cambios fuera consignado. 6. Se consigna el resultado como un nuevo conjunto de cambios y tiene a backout como su padre. 7. Si especica --merge en la lnea de comandos, se fusiona con orig, y se consigna el resultado de la fusi n. o Una va alternativa de implementar la orden hg backout sera usar hg export sobre el conjunto de cambios a retroceder como un diff y despu s usar laa opci n --reverse de la orden patch para reversar el efecto del cambio e o sin molestar el directorio de trabajo. Suena mucho m s simple, pero no funcionara bien ni de cerca. a La raz n por la cual hg backout hace una actualizaci n, una consignaci n, una fusi n y otra consignaci n es o o o o o para dar a la maquinaria de fusi n la mayor oportunidad de hacer un buen trabajo cuando se trata con todos los cambios o entre el cambio que est retrocediendo y la punta actual. a 101

Si est retrocediendo un conjunto de cambios que est a unas 100 atr s en su historial del proyecto, las posibilia a a dades de que una orden patch sea capaz de ser aplicada a un diff reverso, claramente no son altas, porque los cambios que intervienen podran no coincidir con el contexto que patch usa para determinar si puede aplicar un parche (si esto suena como ch chara, vea una discusi n de la orden patch en 12.4). Adicionalmente, la maquinaria de fusi n a o o de Mercurial manejar cheros y directorios renombrados, cambios de permisos, y modicaciones a cheros binarios, a nada de lo cual la orden patch puede manejar.

9.4.

Cambios que nunca debieron ocurrir

En la mayora de los casos, la orden hg backout es exactamente lo que necesita para deshacer los efectos de un cambio. Deja un registro permanente y exacto de lo que usted hizo, cuando se consign el conjunto de cambios o original y cuando se hizo la limpieza. En ocasiones particulares, puede haber consignado un cambio que no debera estar de ninguna forma en el repos itorio. Por ejemplo, sera muy inusual, y considerado como una equivocaci n, consignar los cheros objeto junto con o el c digo fuente. Los cheros objeto no tienen valor intrnseco y son grandes, por lo tanto aumentan el tama o del o n repositorio y la cantidad de tiempo que se emplea al clonar o jalar cambios. Antes de discutir las opciones que tiene si consign cambio del tipo bolsa de papel deschable (el tipo que es o tan malo que le gustara colocarse una bolsa de papel desechable en su cabeza), permtame discutir primero unas aproximaciones que probablemente no funcionen. Dado que Mercurial trata de forma acumulativa al historialcada cambio se coloca encima de todos los cambios que le precedenusualmente usted no puede hacer que unos cambios desastrosos desaparezcan. La unica excepci n o es cuando usted ha acabado de consignar un cambio y este no ha sido publicado o jalado en otro repositorio. Ah es cuando puede usar la orden hg rollback con seguridad, como detall en la secci n 9.1.2. e o Despu s de que usted haya publicado un cambio en otro repositorio, usted podra usar la orden hg rollback e para hacer que en su copia local desaparezca el cambio, pero no tendr las consecuencias que desea. El cambio a estar presente en un repositorio remoto, y reaparecer en su repositorio local la pr xima vez que jale a a o Si una situaci n como esta se presenta, y usted sabe en qu repositorios su mal cambio se ha propagado, puede o e intentar deshacerse del conjunto de cambios de todos los repositorios en los que se pueda encontrar. Esta por supuesto, no es una soluci n satisfactoria: si usted deja de hacerlo en un solo repositorio, mientras est elimin ndolo, el cambio o e a todava estar all afuera, y podra propagarse m s tarde. a a Si ha consignado uno o m s cambios despu s del cambio que desea desaparecer, sus opciones son a n m s reducia e u a das. Mercurial no provee una forma de cabar un hueco en el historial, dejando los conjuntos de cambios intactos. XXX This needs lling out. The hg-replay script in the examples directory works, but doesnt handle merge changesets. Kind of an important omission.

9.4.1.

C mo protegerse de cambios que han escapado o

Si ha consignado cambios a su repositorio local y estos han sido publicados o jalados en cualquier otro sitio, no es necesariamente un desastre. Puede protegerse de antemano de ciertas clases de conjuntos de cambios malos. Esto es particularmente sencillo si su equipo de trabajo jala cambios de un repositorio central. Al congurar algunos ganchos en el repositorio central para validar conjuntos de cambios (ver captulo 10), puede prevenir la publicaci n autom ticamente de cierta clase de cambios malos. Con tal conguraci n, cierta clase de o a o conjuntos de cambios malos tender n naturalmente amorir debido a que no pueden propagarse al repositorio central. a Esto suceder sin necesidad de intervenci n explcita. a o Por ejemplo, un gancho de cambios de entrada que verique que un conjunto de cambios compila, puede prevenir que la gente rompa la compilaci n inadvertidamente. o

9.5.

Al encuentro de la fuente de un fallo

Aunque es muy bueno poder retroceder el conjunto de cambios que origin un fallo, se requiere que usted sepa o cual conjunto de cambios retroceder. Mercurial brinda una orden invaluable, llamada hg bisect, que ayuda a 102

automatizar este proceso y a alcanzarlo muy ecientemente. La idea tras la orden hg bisect es que el conjunto de cambios que ha introducido un cambio de comportamiento pueda identicarse con una prueba binaria sencilla. No tiene que saber qu pieza de c digo introdujo el cambio, pero si e o requiere que sepa c mo probar la existencia de un fallo. La orden hg bisect usa su prueba para dirigir su b squeda o u del conjunto de cambios que introdujo el c digo causante del fallo. o A continuaci n un conjunto de escenarios que puede ayudarle a entender c mo puede aplicar esta orden. o o La versi n m s reciente de su programa tiene un fallo que usted recuerda no estaba hace unas semanas, pero no o a sabe cu ndo fue introducido. En este caso, su prueba binaria busca la presencia de tal fallo. a Usted arregl un fallo en un apurto, y es hora de dar por cerrado el caso en la base de datos de fallos de su o equipo de trabajo. La base de datos de fallos requiere el ID del conjunto de cambios que permita dar por cerrado el caso, pero usted no recuerda qu conjunto de cambios arregl tal fallo. De nuevo la prueba binaria revisa la e o presencia del fallo. Su programa funciona correctamente, pero core 15 % m s lento que la ultima vez que lo midi . Usted desea a o saber qu conjunto de cambios introdujo esta disminuci n de desempe o. En este caso su prueba binaria mide e o n el desempe o de su programa, para ver d nde es r pido y d nde es lento. n o a o Los tama os de los componentes del proyecto que usted lleva se expandieron recientemente, y sospecha que n algo cambio en la forma en que se construye su proyecto. Para estos ejemplos debera ser claro que la orden hg bisect es util no solamente para encontrar la fuente de los fallos. Puede usarla para encontrar cualquier propiedad emergente de un repositorio (Cualquier cosa que usted no pueda encontrar con una b squeda de texto sencilla sobre los cheros en el arbol) para la cual pueda escribir una u prueba binaria. A continuaci n introduciremos algo terminologa, para aclarar qu partes del proceso de b squeda son su respono e u sabilidad y cu les de Mercurial. Una prueba es algo que usted ejecuta cuando hg bisect elige un conjunto de a cambios. Un sondeo es lo que hg bisect ejecuta para decidir si una revisi n es buena. Finalmente, usaremos la o palabra biseccionar, en frases como buscar con la orden hg bisect. Una forma sencilla de automatizar el proceso de b squeda sera probar cada conjunto de cambios. Lo cual escala u muy poco. Si le tom diez minutos hacer pruebas sobre un conjunto de cambios y tiene 10.000 conjuntos de cambios o en su repositorio, esta aproximaci n exhaustiva tomara en promedio 35 das para encontrar el conjunto de cambios o que introdujo el fallo. Incluso si supiera que el fallo se introdujo en un de los ultimos 500 conjuntos de cambios y limitara la b squeda a ellos, estara tomabdi m s de 40 horas para encontrar al conjunto de cambios culpable. u a La orden hg bisect usa su conocimiento de la forma del historial de revisiones de su proyecto para hacer una b squeda proporcional al logaritmo del n mero de conjunto de cambios a revisar (el tipo de b squeda que realiza u u u se llama b squeda binaria). Con esta aproximaci n, el buscar entre 10.000 conjuntos de cambios tomar menos de u o a 3 horas, incluso a diez minutos por prueba (La b squeda requerir cerca de 14 pruebas). Al limitar la b squeda a la u a u ultima centena de conjuntos de cambios, tomar a lo sumo una hora (Apenas unas 7 pruebas). a La orden hg bisect tiene en cuenta la naturaleza ramicada del historial de revisiones del proyecto con Mercurial, as que no hay problemas al tratar con ramas, fusiones o cabezas m ltiples en un repositorio. Puede evitar u ramas enteras de historial con un solo sondeo.

9.5.1.

Uso de la orden hg bisect

A continuaci n un ejemplo de hg bisect en acci n. o o Nota: En las versiones 0.9.5 y anteriores de Mercurial, hg bisect no era una orden includa en la distribuci n principal: se ofreca como una extensi n de Mer o o curial. Esta secci n describe la orden embebida y no la extensi n anterior. o o Creamos un repostorio para probar el comando hg bisect de forma aislada
1 2

$ hg init mybug $ cd mybug 103

Simularemos de forma sencilla un proyecto con un fallo: haremos cambios triviales en un ciclo, e indicaremos que un cambio especco sea el fallo. Este ciclo crea 35 conjuntos de cambios, cada uno a ade un unico chero al n repositorio. Representaremos nuestro fallo con un chero que contiene el texto tengo un gub.
1 2 3 4 5 6 7 8 9 10

$ buggy_change=22 $ for (( i = 0; i < 35; i++ )); do > if [[ $i = $buggy_change ]]; then > echo i have a gub > myfile$i > hg commit -q -A -m buggy changeset > else > echo nothing to see here, move along > myfile$i > hg commit -q -A -m normal changeset > fi > done A continuaci n observaremos c mo usar la orden hg bisect. Podemos usar el mecanismo de ayuda embebida o o que trae Mercurial.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

$ hg help bisect hg bisect [-gbsr] [REV] subdivision search of changesets This command helps to find changesets which introduce problems. To use, mark the earliest changeset you know exhibits the problem as bad, then mark the latest changeset which is free from the problem as good. Bisect will update your working directory to a revision for testing. Once you have performed tests, mark the working directory as bad or good and bisect will either update to another candidate changeset or announce that it has found the bad revision. options: -r -g -b -s -U --reset --good --bad --skip --noupdate reset bisect state mark changeset good mark changeset bad skip testing changeset do not update to target

use "hg -v help bisect" to show global options La orden hg bisect trabaja en etapas, de la siguiente forma: 1. Usted ejecuta una prueba binaria. Si la prueba es exitosa, usted se lo indicar a hg bisect ejecutando la orden hg bisect good. a Si falla, ejecutar la orden hg bisect --bad. a 2. La orden usa su informaci n para decidir qu conjuntos de cambios deben probarse a continuaci n. o e o 3. Actualiza el directorio de trabajo a tal conjunto de cambios y el proceso se lleva a cabo de nuevo.

104

El proceso termina cuando hg bisect identica un unico conjunto de cambios que marca el punto donde se encontr la transici n de exitoso a fallido. o o Para comenzar la b squeda, es indispensable ejecutar la orden hg bisect --reset. u
1 2 3 4 5

$ if hg -v | head -1 | grep -e "version 0.*" > then #On mercurial 1.0 --init disappeared > hg bisect --init > fi En nuestro caso, la prueba binaria es sencilla: revisamos si el chero en el repositorio contiene la cadena tengo un gub. Si la tiene, este conjunto de cambios contiene aquel que caus el fallo. Por convenci n, un conjunto de o o cambios que tiene la propiedad que estamos buscando es malo, mientras que el otro que no la tiene es bueno. En la mayora de casos, la revisi n del directorio actual (usualmente la punta) exhibe el problema introducido por o el cambio con el fallo, por lo tanto la marcaremos como mala.

$ hg bisect --bad Nuestra pr xima tarea es nominar al conjunto de cambios que sabemos no tiene el fallo; la orden hg bisect o acotar su b squeda entre el primer par de conjuntos de cambios buenos y malos. En nuestro caso, sabemos que la a u revisi n 10 no tena el fallo. (M s adelante dir un poco m s acerca de la elecci n del conjunto de cambios bueno.) o a e a o

1 2 3

$ hg bisect --good 10 Testing changeset 22:ec1c6526e0eb (24 changesets remaining, 4 tests) 0 files updated, 0 files merged, 12 files removed, 0 files unresolved Note que esta orden mostr algo. o Nos dijo cu ntos conjuntos de cambios debe considerar antes de que pueda identica aquel que introdujo el a fallo, y cu ntas pruebas se requerir n. a a Actualiz el directorio de trabajo al siguiente conjunto de cambios, y nos dijo qu conjunto de cambios est evalo e a uando. Ahora ejecutamos nuestra prueba en el directorio de trabajo. Usamos la orden grep para ver si nuestro chero malo est presente en el directorio de trabajo. Si lo est , esta revisi n es mala; si no esta revisi n es buena. a a o o

1 2 3 4 5 6 7 8 9 10 11

$ if grep -q i have a gub * > then > result=bad > else > result=good > fi $ echo this revision is $result this revision is bad $ hg bisect --$result Testing changeset 16:8fb73e2ea5f9 (12 changesets remaining, 3 tests) 0 files updated, 0 files merged, 6 files removed, 0 files unresolved Esta prueba luce como candidata perfecta para automatizarse, por lo tanto la convertimos en una funci n de interfaz o de comandos.

105

1 2 3 4 5 6 7 8 9 10

$ mytest() { > if grep -q i have a gub * > then > result=bad > else > result=good > fi > echo this revision is $result > hg bisect --$result > } Ahora podemos ejecutar un paso entero de pruebas con un solo comando, mytest.

1 2 3 4

$ mytest this revision is good Testing changeset 19:ffbbdeaade97 (6 changesets remaining, 2 tests) 3 files updated, 0 files merged, 0 files removed, 0 files unresolved Unas invocaciones m s de nuestra prueba, y hemos terminado. a

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

$ mytest this revision is good Testing changeset 20:c0c13593daf1 (3 changesets remaining, 1 tests) 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ mytest this revision is good Testing changeset 21:d70e5938b22b (2 changesets remaining, 1 tests) 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ mytest this revision is good The first bad revision is: changeset: 22:ec1c6526e0eb user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:14 2009 +0000 summary: buggy changeset

Aunque tenamos unos 40 conjuntos de cambios en los cuales buscar, la orden hg bisect nos permiti encontrar o el conjunto de cambios que introdujo el fallo con s lo cinco pruebas. Porque el n mero de pruebas que la orden hg o u bisect ejecuta crece logartmicamente con la cantidad de conjuntos de cambios a buscar, la ventaja que esto tiene frente a la b squeda porfuerza bruta crece con cada conjunto de cambios que usted adicione. u

9.5.2.

Limpieza despu s de la busqueda e

Cuando haya terminado de usar la orden hg bisect en un repositorio, puede usar la orden hg bisect reset para deshacerse de la informaci n que se estaba usando para lograr la b squeda. Lar orden no usa mucho espacio, o u as que no hay problema si olvida ejecutar la orden. En todo caso, hg bisect no le permitir comenzar una nueva a b squeda sobre el repositorio hasta que no aplique hg bisect reset. u
1

$ hg bisect --reset

106

9.6.
9.6.1.

Consejos para encontrar fallos efectivamente


Dar una entrada consistente

La orden hg bisect requiere que usted ofrezca un reporte correcto del resultado de cada prueba que aplique. Si usted le dice que una prueba falla cuando en realidad era acertada, podra detectar la inconsistencia. Si puede identicar una inconsistencia en sus reportes, le dir que un conjunto de cambios particular es a la vez bueno y malo. a Aunque puede no hacerlo; estara tratando de reportar un conjunto de cambios como el responsable de un fallo aunque no lo sea.

9.6.2.

Automatizar tanto como se pueda

Cuando comenc a usar la orden hg bisect, intent ejecutar algunas veces las pruebas a mano desde la lnea e e de comandos. Es una aproximaci n a la cual no esta acostumbrado. Despu s de algunos intentos, me di cuenta que o e estaba cometiendo tantas equivocaciones que tena que comenzar de nuevo con mis b squedas varias veces antes de u llegar a los resultados deseados. Mi problema inicial al dirigir a la orden hg bisect manualmente ocurrieron incluso con b squedas en repositou rios peque os; si el problema que est buscando es m s sutil, o el n mero de pruebas que hg bisect debe aplicar, n a a u la posibilidad de errar es mucho m s alta. Una vez que comenc a automatizar mis pruebas, obtuve mejores resultados. a e La clave para las pruebas automatizadas se puede resumir en: pruebe siempre buscando el mismo sntoma y ofrezca siempre datos consistentes a la orden hg bisect. En mi tutorial de ejemplo anterior, la orden grep busca el sntoma, y la construcci n if toma el resultado de esta o prueba y verica que siempre alimentamos con los mismos datos a la orden hg bisect. La funci n mytest los une o de una forma reproducible, logrando que cada prueba sea uniforme y consistente.

9.6.3.

Vericar los resultados

Dado que la salida de la b squeda de hg bisect es tan buena como los datos ofrecidos por usted, no confe en u esto como si fuera la verdad absoluta. Una forma sencilla de asegurarse es ejecutar manualmente su prueba a cada uno de los siguientes conjuntos de cambios: El conjunto de cambios que se report como la primera versi n erronea. Su prueba debera dar un reporte de o o fallo. El conjunto de cambios padre (cada padre, si es una fusi n). Su prueba debera reportar este(os) conjunto(s) de o cambios como bueno(s). Un hijo del conjunto de cambios. Su prueba debera reportar al conjunto de cambios hijo como malo.

9.6.4.

Tener en cuenta la interferencia entre fallos

Es posible que su b squeda de un fallo pueda viciarse por la presencia de otro. Por ejemplo, digamos que su u programa se revienta en la revisi n 100, y que funcion correctamente en la revisi n 50. Sin su conocimiento, alguien o o o introdujo un fallo con consecuencias grandes en la revisi n 60, y lo arregl en la revisi n 80. Sus resultados estaran o o o distorcionados de una o muchas formas. Es posible que este fallo enmascare completamente al suyo, y que podra haberse revelado antes de que su propio fallo haya tenido oportunidad de manifestarse. Si no puede saltar el otro fallo (por ejemplo, este evita que su proyecto se arme o compile), y de esta forma no se pueda revisar si su fallo est presente en un conjunto particular de cambios, e la orden hg bisect no podr ayudarle directamente. En cambio, puede marcar este conjunto de cambios como al a ejecutar hg bisect --skip. 107

Un problema distinto podra surgir si su prueba de la presencia de un fallo no es sucientemente especca. Si usted busca mi programa se revienta, entonces tanto su fallo como el otro fallo sin relaci n que terminan presentando o sntomas distintos, podra terminar confundiendo a hg bisect. Otra situaci n en la cual sera de mucha utilidad emplear a hg bisect --skip surge cuando usted no puede o probar una revisi n porque su proyecto estaba en una situaci n de rompimiento y por lo tanto en un estado en el o o cual era imposible hacer la prueba en esa revisi n, tal vez porque alguien consign un cambio que haca imposible la o o construcci n del proyecto. o

9.6.5.

Acotar la busqueda perezosamente

Elegir los primeros buenos y malos conjuntos de cambios que marcar n los lmites de su b squeda en general a u es sencillo, pero vale la pena discutirlo. Desde la perspectiva de hg bisect, el conjunto de cambios m s nuevo a por convenci n es el malo, y el otro conjunto de cambios es el bueno. o Si no recuerda cu l podra ser el cambio bueno, para informar a hg bisect, podra hacer pruebas aleatorias a en el peor de los casos. Pero recuerde eliminar aquellos conjuntos de cambios que podran no exhibir el fallo (tal vez porque la caracterstica donde se presenta el fallo todava no est presente) y aquellos en los cuales otro fallo puede a enmascararlo (como se discuti anteriormente). o Incluso si termina muy atr s por miles de conjuntos de cambios o meses de historial, solamente estaa adicioa r nando unas pruebas contadas para hg bisect, gracias al comportamiento logartmico.

108

Captulo 10

Manejo de eventos en repositorios mediante ganchos


Mercurial ofrece un poderoso mecanismo para permitirle a usted automatizar la ejecuci n de acciones en respuesta o a eventos que ocurran en un repositorio. En algunos casos, usted puede controlar incluso la respuesta de Mercurial a dichos eventos. Mercurial usa el t rmino gancho para identicar estas acciones. Los ganchos son conocidos como disparadores e en algunos sistemas de control de revisiones, pero los dos nombres se reeren al mismo concepto.

10.1.

Vistazo general de ganchos en Mercurial

A continuaci n se encuentra una breve lista de los ganchos que Mercurial soporta. Volveremos a cada uno de estos o ganchos con m s detalle despu s, en la secci n 10.8. a e o
changegroup Es ejecutado luego de que un grupo de conjuntos de cambios ha sido trado al repositorio desde alg n otro sitio. u commit Es ejecutado despu s de la creaci n de un conjunto de cambios en el repositorio local. e o incoming Es ejecutado una vez por cada conjunto de cambios trado al repositorio desde otra ubicaci n. Note la diferencia o

respecto al gancho changegroup, que es ejecutado una vez por cada grupo de conjuntos de cambios que se traiga.

outgoing Es ejecutado luego de que un grupo de conjuntos de cambios ha sido transmitido desde el repositorio. prechangegroup Es ejecutado antes de iniciar la recepci n de un grupo de conjuntos de cambios en el repositorio. o precommit De control. Es ejecutado antes de iniciar una consignaci n. o preoutgoing De control. Es ejecutado antes de iniciar la transmisi n de un grupo de conjuntos de cambios desde el repositorio. o pretag De control. Es ejecutado antes de crear una etiqueta. pretxnchangegroup De control. Es ejecutado despu s de haber recibido un grupo de conjuntos de cambios en el repositorio local, e

pero antes de que la transacci n se complete y los cambios sean permanentes dentro del repositorio. o que la transacci n que hace permanente el cambio sea completada. o

pretxncommit De control. Es ejecutado luego de la creaci n de un conjunto de cambios en el repositorio local, pero antes de o preupdate De control. Es ejecutado antes de iniciar una actualizaci n o fusi n en el directorio de trabajo. o o tag Es ejecutado despu s de la creaci n de una etiqueta. e o

109

update Es ejecutado despu s de que termina una actualizaci n o una fusi n. e o o

Cada uno de los ganchos cuya descripci n empieza con la frase de control tiene la facultad de determinar si una o actividad puede continuar. Si el gancho se ejecuta con exito, la actividad puede continuar; si falla, o bien la actividad no es permitida, o se deshacen los cambios que se puedan haber llevado a cabo, dependiendo del gancho involucrado.

10.2.
10.2.1.

Ganchos y seguridad
Los ganchos se ejecutan con sus privilegios de usuario

Cuando usted ejecuta un comando de Mercurial en un repositorio, y el comando causa la ejecuci n de un gancho, o dicho gancho se ejecuta en su sistema, en su cuenta de usuario, con sus privilegios. Ya que los ganchos son elementos arbitrarios de c digo ejecutable, usted debera tratarlos con un nivel adecuado de desconanza. No instale un gancho o a menos en que confe en quien lo cre y en lo que el gancho hace. o En algunos casos, usted puede estar expuesto a ganchos que usted no instal . Si usted usa Mercurial en un sistema o extra o, tenga en cuenta que Mercurial ejecutar los ganchos denidos en el chero hgrc. n a Si est trabajando con un repositorio propiedad de otro usuario, Mercurial podr ejecutar los ganchos denidos a a en el repositorio de dicho usuario, pero los ejecutar como usted. Por ejemplo, si usted jala (hg pull) desde ese a repositorio, y el .hg/hgrc dene un gancho saliente (outgoing), dicho gancho se ejecuta bajo su cuenta de usuario, aun cuando usted no es el propietario del repositorio. Nota: Esto s lo aplica si usted est jalando desde un repositorio en un sistema o a de cheros local o de red. Si est jalando a trav s de http o ssh, cualquier gana e cho saliente (outgoing) se ejecutar bajo la cuenta que est ejecutando el proceso a a servidor, en el servidor. XXX Para ver qu ganchos han sido denidos en un repositorio, use el comando hg config hooks. Si usted e est trabajando en un repositorio, pero comunic ndose con otro que no le pertenece (por ejemplo, usando hg pull a a o hg incoming), recuerde que los ganchos que debe considerar son los del otro repositorio, no los del suyo.

10.2.2.

Los ganchos no se propagan

En Mercurial, no se hace control de revisiones de los ganchos, y no se propagan cuando usted clona, o jala de, un repositorio. El motivo para esto es simple: un gancho es c digo ejecutable arbitrario. Se ejecuta bajo su identidad, con o su nivel de privilegios, en su m quina. a Sera extremadamente descuidado de parte de cualquier sistema distribuido de control de revisiones el implementar control de revisiones para ganchos, ya que esto ofrecera maneras f cilmente aprovechables de subvertir las cuentas a de los usuarios del sistema de control de revisiones. Ya que Mercurial no propaga los ganchos, si usted est colaborando con otras personas en un proyecto com n, a u no debera asumir que ellos est n usando los mismos ganchos para Mercurial que usted usa, o que los de ellos est n a a congurado correctamente. Usted debera documentar los ganchos que usted espera que la gente use. En una intranet corporativa, esto es algo m s f cil de manejar, ya que usted puede, por ejemplo, proveer una a a instalaci n est ndar de Mercurial en un sistema de cheros NFS, y usar un chero hgrc global para denir los o a ganchos que ver n todos los usuarios. Sin embargo, este enfoque tiene sus lmites; vea m s abajo. a a

10.2.3.

Es posible hacer caso omiso de los ganchos

Mercurial le permite hacer caso omiso de la decini n de un gancho, a trav s de la redenici n del mismo. Usted o e o puede deshabilitar el gancho jando su valor como una cadena vaca, o cambiar su comportamiento como desee. Si usted instala un chero hgrc a nivel de sistema o sitio completo que dene algunos ganchos, debe entender que sus usuarios pueden deshabilitar o hacer caso omiso de los mismos.

110

10.2.4.

Asegurarse de que ganchos crticos sean ejecutados

Algunas veces usted puede querer hacer respetar una poltica, y no permitir que los dem s sean capaces de evitarla. a Por ejemplo, usted puede tener como requerimiento que cada conjunto de cambios debe pasar un riguroso conjunto de pruebas. Denir este requerimientos a trav s de un gancho en un chero hgrc global no servir con usuarios remotos e a en computadoras port tiles, y por supuesto que los usuarios locales pueden evitar esto a voluntad haciendo caso omiso a del gancho. En vez de eso, usted puede denir las polticas para usar Mercurial de tal forma que se espere que los usuar ios propaguen los cambios a trav s de un servidor can nico bien conocido que usted ha asegurado y congurado e o apropiadamente. Una manera de hacer esto es a trav s de una combinaci n de ingeniera social y tecnologa. Cree una cuenta de e o acceso restringido; los usuarios pueden empujar cambios a trav s de la red a los repositorios administrados por esta e cuenta, pero no podr n ingresar a dicha cuenta para ejecutar ordenes en el int rprete de comandos. En este escenario, a e un usuario puede enviar un conjunto de cambios que contenga la porquera que el desee. Cuando alguien empuja un conjunto de cambios al servidor del que todos jalan, el servidor probar el conjunto de a cambios antes de aceptarlo como permanente, y lo rechazar si no logra pasar el conjunto de pruebas. Si la gente s lo a o jala cambios desde este servidor de ltro, servir para asegurarse de que todos los cambios que la gente jala han sido a examinados autom ticamente a

10.3.

Precauciones con ganchos pretxn en un repositorio de acceso compartido

Si usted desea usar ganchos para llevar a cabo autom ticamente alg n trabajo en un repositorio al que varias a u personas tienen acceso compartido, debe tener cuidado con la forma de hacerlo. Mercurial s lo bloquea un repositorio cuando est escribiendo al mismo, y s lo las partes de Mercurial que escriben o a o al repositorio le prestan atenci n a los bloqueos. Los bloqueos de escritura son necesarios para evitar que m ltiples o u escritores simult neos intereran entre s, corrompiendo el repositorio. a Ya que Mercurial tiene cuidado con el orden en que lee y escribe datos, no necesita adquirir un bloqueo cuando desea leer datos del repositorio. Las partes de Mercurial que leen del repositorio nunca le prestan atenci n a los o bloqueos. Este esquema de lectura libre de bloqueos incremententa en gran medida el desempe o y la concurrencia. n Sin embargo, para tener un gran desempe o es necesario hacer sacricios, uno de los cuales tiene el potencial de n causarle problemas a menos de que usted est consciente de el. Describirlo requiere algo de detalle respecto a c mo e o Mercurial a ade conjuntos de cambios al repositorio y c mo lee esos cambios de vuelta. n o Cuando Mercurial escribe metadatos, los escribe directamente en el chero de destino. Primero escribe los datos del chero, luego los datos del maniesto (que contienen punteros a los nuevos datos del chero), luego datos de la bit cora de cambios (que contienen punteros a los nuevos datos del maniesto). Antes de la primera escritura a cada a chero, se guarda un registro de d nde estaba el nal de chero en su registro de transacciones. Si la transacci n o o debe ser deshecha, Mercurial simplemente trunca cada chero de vuelta al tama o que tena antes de que empezara la n transacci n. o Cuando Mercurial lee metadatos, lee la bit cora de cambios primero, y luego todo lo dem s. Como un lector s lo a a o acceder a las partes del maniesto o de los metadatos de chero que el puede ver en la bit cora de cambios, nunca a a puede ver datos parcialmente escritos. Algunos ganchos de control (pretxncommit y pretxnchangegroup) se ejecutan cuando una transacci n est casi o a completa. Todos los metadatos han sido escritos, pero Mercurial a n puede deshacer la transacci n y hacer que los u o datos reci n escritos desaparezcan. e Si alguno de estos ganchos permanece en ejecuci n por mucho tiempo, abre una ventana de tiempo en la que un o lector puede ver los metadatos de conjuntos de cambios que a n no son permanentes y que no debera considerarse u que est n realmante ah. Entre m s tiempo tome la ejecuci n del gancho, m s tiempo estar abierta esta ventana. e a o a a

111

10.3.1.

Ilustraci n del problema o

En principio, un buen uso del gancho pretxnchangegroup sera ensamblar y probar autom ticamente todos los a cambios entrantes antes de que sean aceptados en un repositorio central. Esto le permitira a usted garantizar que nadie pueda empujar cambios que rompan el ensamblaje. Pero si un cliente puede jalar cambios mientras est n siendo a probados, la utilidad de esta prueba es nula; alguien conado puede jalar cambios sin probar, lo que potencialmente podra romper su proceso de ensamblaje. La respuesta t cnica m s segura frente a este retos es montar dicho repositorio guardi n como unidireccional. e a a Permita que reciba cambios desde el exterior, pero no permita que nadie jale cambios de el (use el gancho preoutgoing para bloquear esto). Congure un gancho changegroup para que si el ensamblaje o prueba tiene exito, el gancho empuje los nuevos cambios a otro repositorio del que la gente pueda jalar. En la pr ctica, montar un cuello de botella centralizado como este a menudo no es una buena idea, y la visibilidad a de las transacciones no tiene nada que ver con el problema. A medida que el tama o de un proyectoy el tiempo n que toma ensamblarlo y probarlocrece, usted se acerca r pidamente a un lmite con este enfoque pruebe antes de a comprar, en el que tiene m s conjuntos de cambios a probar que tiempo para ocuparse de ellos. El resultado inevitable a es frustraci n para todos los que est n involucrados. o e Una aproximaci n que permite manejar mejor el crecimiento es hacer que la gente ensamble y pruebe antes de o empujar, y ejecutar el ensamble y pruebas autom ticas centralmente despu s de empujar, para asegurarse de que todo a e est bien. La ventaja de este enfoque es que no impone un lmite a la rata en la que un repositorio puede aceptar e cambios.

10.4.

Tutorial corto de uso de ganchos

Escribir un gancho para Mercurial es f cil. Empecemos con un gancho que se ejecute cuando usted termine un a hg commit, y simplemente muestre el hash del conjunto de cambios que usted acaba de crear. El gancho se llamar commit. a
1 2 3 4 5 6 7 8 9 10 11

$ hg init hook-test $ cd hook-test $ echo [hooks] >> .hg/hgrc $ echo commit = echo committed $HG_NODE >> .hg/hgrc $ cat .hg/hgrc [hooks] commit = echo committed $HG_NODE $ echo a > a $ hg add a $ hg commit -m testing commit hook committed 233120f5d09c76e782c6ea86ccee729e735bf48f

Figura 10.1: Un gancho simple que se ejecuta al hacer la consignaci n de un conjunto de cambios o Todos los ganchos siguen el patr n del ejemplo 10.1. Usted puede a adir una entrada a la secci n [hooks] de su o n o chero hgrc. A la izquierda est el nombre del evento respecto al cual dispararse; a la derecha est la acci n a llevar a a o a cabo. Como puede ver, es posible ejecutar cualquier orden de la lnea de comandos en un gancho. Mercurial le pasa informaci n extra al gancho usando variables de entorno (busque HG NODE en el ejemplo). o

10.4.1.

Llevar a cabo varias acciones por evento

A menudo, usted querr denir m s de un gancho para un tipo de evento particular, como se muestra en el ejema a plo 10.2. Mercurial le permite hacer esto a adiendo una extensi n al nal del nombre de un gancho. Usted extiende n o 112

el nombre del gancho poniendo el nombre del gancho, seguido por una parada completa (el caracter .), seguido de algo m s de texto de su elecci n. Por ejemplo, Mercurial ejecutar tanto commit.foo como commit.bar cuando a o a ocurra el evento commit.
1 2 3 4 5

$ echo commit.when = echo -n "date of commit: "; date >> .hg/hgrc $ echo a >> a $ hg commit -m i have two hooks committed df4f3f8972104d2a43d114e51edd05719efccd42 date of commit: Tue Feb 10 18:23:23 GMT 2009

Figura 10.2: Denici n de un segundo gancho commit o Para dar un orden bien denido de ejecuci n cuando hay m ltiples ganchos denidos para un evento, Mercurial o u ordena los ganchos de acuerdo a su extensi n, y los ejecuta en dicho orden. En el ejemplo de arribam commit.bar se o ejecutar antes que commit.foo, y commit se ejecutar antes de ambos. a a Es una buena idea usar una extensi n descriptiva cuando usted dene un gancho. Esto le ayudar a recordar para o a qu se usa el gancho. Si el gancho falla, usted recibir un mensaje de error que contiene el nombre y la extensi n del e a o gancho, as que usar una extensi n descriptiva le dar una pista inmediata de porqu el gancho fall (vea un ejemplo o a e o en la secci n 10.4.2). o

10.4.2.

Controlar cu ndo puede llevarse a cabo una actividad a

En los ejemplos anteriores, usamos el gancho commit, que es ejecutado despu s de que se ha completado una e consignaci n. Este es uno de los varios ganchos que Mercurial ejecuta luego de que una actividad termina. Tales o ganchos no tienen forma de inuenciar la actividad como tal. Mercurial dene un n mero de eventos que ocurren antes de que una actividad empiece; o luego de que empiece, u pero antes de que termine. Los ganchos que se disparan con estos eventos tienen la capacidad adicional de elegir si la actividad puede continuar, o si su ejecuci n es abortada. o El gancho pretxncommit se ejecuta justo antes de que una consignaci n se ejecute. En otras palabras, los metadatos o que representan el conjunto de cambios han sido escritos al disco, pero no se ha terminado la transacci n. El gancho o pretxncommit tiene la capacidad de decidir si una transacci n se completa, o debe deshacerse. o Si el gancho pretxncommit termina con un c digo de salida de cero, se permite que la transacci n se complete; la o o consignaci n termina; y el gancho commit es ejecutado. Si el gancho pretxncommit termina con un c digo de salida o o diferente de cero, la transacci n es revertida; los metadatos representando el conjunto de cambios son borrados; y el o gancho commit no es ejecutado. El gancho en el ejemplo 10.3 revisa si el mensaje de consignaci n contiene el ID de alg n fallo. Si lo contiene, la o u consignaci n puede continuar. Si no, la consignaci n es cancelada. o o

10.5.

Escribir sus propios ganchos

Cuando usted escriba un gancho, puede encontrar util el ejecutar Mercurial o bien pas ndole la opci n -v, o con el a o valor de conguraci n verbose jado en true (verdadero). Cuando lo haga, Mercurial imprimir un mensaje antes o a de llamar cada gancho.

10.5.1.

Escoger c mo debe ejecutarse su gancho o

Usted puede escribir un gancho que funcione como un programa normal tpicamente un gui n de lnea de o comandoso como una funci n de Python que se ejecuta dentro del proceso Mercurial. o Escribir un gancho como un programa externo tiene la ventaja de que no requiere ning n conocimiento del funu cionamiento interno de Mercurial. Usted puede ejecutar comandos Mercurial normales para obtener la informci n o 113

1 2 3 4 5 6 7 8 9 10 11 12 13

$ cat check_bug_id #!/bin/sh # check that a commit comment mentions a numeric bug id hg log -r $1 --template {desc} | grep -q "\<bug *[0-9]" $ echo pretxncommit.bug_id_required = ./check_bug_id $HG_NODE >> .hg/hgrc $ echo a >> a $ hg commit -m i am not mentioning a bug id transaction abort! rollback completed abort: pretxncommit.bug_id_required hook exited with status 1 $ hg commit -m i refer you to bug 666 committed d558e8617cbdf0b482db27a79d17f9a28af4701f date of commit: Tue Feb 10 18:23:23 GMT 2009

Figura 10.3: Uso del gancho pretxncommit para controlar consignaciones extra que pueda necesitar. La contraparte de esto es que los ganchos externos son m s lentos que los ganchos internos a ejecutados dentro del proceso. Un gancho Python interno tiene acceso completo a la API de Mercurial, y no se externaliza a otro proceso, as que es inherentemente m s r pido que un gancho externo. Adicionalmente es m s f cil obtener la mayora de a a a a la informaci n que un gancho requiere a trav s de llamadas directas a la API de Mercurial que hacerlo ejecutando o e comandos Mercurial. Si se siente a gusto con Python, o requiere un alto desempe o, escribir sus ganchos en Python puede ser una buena n elecci n. Sin embargo, cuando usted tiene un gancho bastante directo por escribir y no le importa el desempe o (el o n caso de la mayora de los ganchos), es perfectamente admisible un gui n de lnea de comandos. o

10.5.2.

Par metros para ganchos a

Mercurial llama cada gancho con un conjunto de paametros bien denidos. En Python, un par metro se pasa r a como argumento de palabra clave a su funci n de gancho. Para un programa externo, los par metros son pasados o a como variables de entornos. Sin importar si su gancho est escrito en Python o como gui n de lnea de comandos, los nombres y valores de a o los par metros especcos de los ganchos ser n los mismos. Un par metro booleano ser representado como un valor a a a a booleano en Python, pero como el n mero 1 (para verdadero) o 0 (para falso) en una variable de entorno para un u gancho externo. Si un par metro se llama foo, el argumento de palabra clave para un gancho en Python tambi n se a e llamar foo, mientras que la variable de entorno para un gancho externo se llamar HG FOO. a a

10.5.3.

Valores de retorno de ganchos y control de actividades

Un gancho que se ejecuta exitosamente debe terminar con un c digo de salida de cero, si es externo, o retornar o el valor booleano falso, si es interno. Un fallo se indica con un c digo de salida diferente de cero desde un gancho o externo, o un valor de retorno booleano verdadero. Si un gancho interno genera una excepci n, se considera que el o gancho ha fallado. Para los ganchos que controlan si una actividad puede continuar o no, cero/falso quiere decir permitir, mientras que no-cero/verdadero/excepci n quiere decir no permitir. o

10.5.4.

Escribir un gancho externo

Cuando usted dene un gancho externo en su chero hgrc y el mismo es ejecutado, dicha denici n pasa a su o int rprete de comandos, que hace la interpretaci n correspondiente. Esto signica que usted puede usar elementos e o 114

normales del int rprete en el cuerpo del gancho. e Un gancho ejecutable siempre es ejecutado con su directorio actual jado al directorio raz del repositorio. Cada par metro para el gancho es pasado como una variable de entorno; el nombre est en may sculas, y tiene a a u como prejo la cadena HG . Con la excepci n de los par metros para los ganchos, Mercurial no dene o modica ninguna variable de entorno o a al ejecutar un gancho. Es util recordar esto al escribir un gancho global que podra ser ejecutado por varios usuarios con distintas variables de entorno jadas. En situaciones con m ltiples usuarios, usted no debera asumir la existencia u de ninguna variable de entorno, ni que sus valores sean los mismos que tenan cuando usted prob el gancho en su o ambiente de trabajo.

10.5.5.

Indicar a Mercurial que use un gancho interno

La sintaxis para denir un gancho interno en el chero hgrc es ligeramente diferente de la usada para un gancho externo. El valor del gancho debe comenzar con el texto python:, y continuar con el nombre completamente cualicado de un objeto invocable que se usar como el valor del gancho. a El m dulo en que vive un gancho es importado autom ticamente cuando se ejecuta un gancho. Siempre que usted o a tenga el nombre del m dulo y la variable de entorno PYTHONPATH ajustada adecuadamente, todo debera funcionar sin o problemas. El siguiente fragmento de ejemplo de un chero hgrc ilustra la sintaxis y signicado de los conceptos que acabamos de describir.
1 2

[hooks] commit.example = python:mymodule.submodule.myhook Cuando Mercurial ejecuta el gancho commit.example, importa mymodule.submodule, busca el objeto invocable llamado myhook, y lo invoca (llama).

10.5.6.

Escribir un gancho interno

El gancho interno m s sencillo no hace nada, pero ilustra la estructura b sica de la API1 para ganchos: a a
1 2

def myhook(ui, repo, **kwargs): pass El primer argumento para un gancho Python siempre es un objeto mercurial.ui.ui. El segundo es un objeto repositorio; de momento, siempre es una instancia de mercurial.localrepo.localrepository. Despu s de estos dos e argumentos est n los argumentos de palabra clave. Los argumentos que se pasen depender n del tipo de gancho que se a a est llamando, pero un gancho siempre puede ignorar los argumentos que no le interesen, releg ndolos a un diccionario e a de argumentos por palabras clave, como se hizo arriba con **kwargs.

10.6.
10.6.1.

Ejemplos de ganchos
Escribir mensajes de consignaci n signicativos o

Es difcil de imaginar un mensaje de consignaci n util y al mismo tiempo muy corto. El simple gancho pretxncommit o de la gura 10.4 evitar que usted consigne un conjunto de cambios con un mensaje de menos de 10 bytes de longitud. a
1 N.

del T. Application Progamming Interface, Interfaz para Programaci n de Aplicaciones o

115

1 2 3 4 5 6 7 8 9 10

$ cat .hg/hgrc [hooks] pretxncommit.msglen = test hg tip --template {desc} | wc -c -ge 10 $ echo a > a $ hg add a $ hg commit -A -m too short transaction abort! rollback completed abort: pretxncommit.msglen hook exited with status 1 $ hg commit -A -m long enough

Figura 10.4: Un gancho que prohbe mensajes de consignaci n demasiado cortos o

10.6.2.

Comprobar espacios en blanco nales

Un uso interesante para ganchos relacionados con consignaciones es ayudarle a escribir c digo m s limpio. Un o a ejemplo simple de c digo m s limpio es la regla de que un cambio no debe a adir lneas de texto que contengan o a n espacios en blanco nales. El espacio en blanco nal es una serie de caracteres de espacio y tabulaci n que se o encuentran al nal de una lnea de texto. En la mayora de los casos, el espacio en blanco nal es innecesario, ruido invisible, pero ocasionalmente es problem tico, y la gente en general preere deshacerse de el. a Usted puede usar cualquiera de los ganchos precommit o pretxncommit para revisar si tiene el problema de los espacios en blanco nales. Si usa el gancho precommit, el gancho no sabr qu cheros se est n consignando, por lo a e a que se tendr que revisar cada chero modicado en el repositorio para ver si tiene espacios en blanco nales. Si usted a s lo quiere consignar un cambio al chero foo, y el chero bar contiene espacios en blanco nales, hacer la revisi n o o en el gancho precommit evitar que usted haga la consignaci n de foo debido al problem en bar. Este no parece el a o enfoque adeucado. Si usted escogiera el gancho pretxncommit, la revisi n no ocurrira sino hasta justo antes de que la transacci n o o para la consignaci n se complete. Esto le permitir comprobar por posibles problemas s lo en los cheros que ser n o a o a consignados. Sin embargo, si usted ingres el mensaje de consignaci n de manera interactiva y el gancho falla, la o o transacci n ser deshecha; usted tendr que reingresar el mensaje de consignaci n luego de que corrija el problema o a a o con los espacios en blanco nales y ejecute hg commit de nuevo.
1 2 3 4 5 6 7 8 9 10 11

$ cat .hg/hgrc [hooks] pretxncommit.whitespace = hg export tip | (! egrep -q \+.*[ \t]$) $ echo a > a $ hg commit -A -m test with trailing whitespace adding a transaction abort! rollback completed abort: pretxncommit.whitespace hook exited with status 1 $ echo a > a $ hg commit -A -m drop trailing whitespace and try again

Figura 10.5: Un gancho simple que revisa si hay espacios en blanco nales La gura 10.5 presenta un gancho pretxncommit simple que comprueba la existencia de espacios en blanco nales. Este gancho es corto, pero no brinda mucha ayuda. Termina con un c digo de salida de error si un cambio o a ade una lnea con espacio en blanco nal a cualquier chero, pero no muestra ninguna informaci n que pueda ser n o 116

util para identicar el chero o la lnea de texto origen del problema. Tambi n tiene la agradable propiedad de no e prestar atenci n a las lneas que no sufrieron modicaciones; s lo las lneas que introducen nuevos espacios en blanco o o nales causan problemas.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

$ cat .hg/hgrc [hooks] pretxncommit.whitespace = .hg/check_whitespace.py $ echo a >> a $ hg commit -A -m add new line with trailing whitespace a, line 2: trailing whitespace added commit message saved to .hg/commit.save transaction abort! rollback completed abort: pretxncommit.whitespace hook exited with status 1 $ sed -i s, *$,, a $ hg commit -A -m trimmed trailing whitespace a, line 2: trailing whitespace added commit message saved to .hg/commit.save transaction abort! rollback completed abort: pretxncommit.whitespace hook exited with status 1

Figura 10.6: Un mejor gancho para espacios en blanco nales El ejemplo de la gura 10.6 es mucho m s complejo, pero tambi n m s util. El gancho procesa un diff unicado a e a para revisar si alguna lnea a ade espacios en blanco nales, e imprime el nombre del chero y el n mero de lnea n u de cada ocurrencia. A n mejor, si el cambio a ade espacios en blanco nales, este gancho guarda el mensaje de u n consignaci n e imprime el nombre del chero en el que el mensaje fue guardado, antes de terminar e indicarle a o Mercurial que deshaga la transacci n, para que uste pueda usar hg commit -l nombre fichero para reutilizar o el mensaje de consignaci n guardado anteriormente, una vez usted haya corregido el problema. o Como anotaci n nal, note en la gura 10.6 el uso de la caracterstica de edici n in-situ de perl para eliminar los o o espacios en blanco nales en un chero. Esto es lo sucientemente conciso y poderoso para que lo presente aqu.
1

perl -pi -e s,\s+$,, nombre fichero

10.7.

Ganchos adicionales

Mercurial se instala con varios ganchos adicionales. Usted puede encontrarlos en el directorio hgext del arbol de cheros fuente de Mercurial. Si usted est usando un paquete binario de Mercurial, los ganchos estar n ubicados en el a a directorio hgext en donde su instalador de paquetes haya puesto a Mercurial.

10.7.1.

aclcontrol de acceso a partes de un repositorio

La extensi n acl le permite controlar a qu usuarios remotos les est permitido empujar conjuntos de cambios a o e a un servidor en red. Usted puede proteger cualquier porci n de un repositorio (incluyendo el repositorio completo), de o tal manera que un usuario remoto especco pueda empujar cambios que no afecten la porci n protegida. o Esta extensi n implementa control de acceso basado en la identidad del usuario que empuja los conjuntos de o cambios, no en la identidad de quien hizo la consignaci n de los mismos. Usar este gancho tiene sentido s lo si se o o tiene un servidor adecuadamente asegurado que autentique a los usuarios remotos, y si usted desea segurarse de que s lo se le permita a ciertos usuarios empujar cambios a dicho servidor. o 117

Conguraci n del gancho acl o Para administrar los conjuntos de cambios entrantes, se debe usar el gancho acl como un gancho de tipo pretxnchangegroup. Esto le permite ver qu cheros son modicados por cada conjunto de cambios entrante, y deshacer el efecto de un e grupo de conjuntos de cambios si alguno de ellos modica alg n chero prohibido. Ejemplo: u
1 2

[hooks] pretxnchangegroup.acl = python:hgext.acl.hook La extensi n acl es congurada mediante tres secciones. o La secci n [acl] s lo tiene una entrada, sources2 , que lista las fuentes de los conjuntos de cambios entrantes a o o las que el gancho debe prestar atenci n. Usualmente usted no necesita congurar esta secci n. o o serve Controlar conjuntos de cambios entrantes que est n llegando desde un repositorio a trav s de http o ssh. Este es a e el valor por defecto de sources, y usualmente es el unico valor de conguraci n que necesitar para este tem. o a pull Controlar conjuntos de cambios entrantes que lleguen va un pull (jalado) desde un repositorio local. push Controlar conjuntos de cambios entrantes que lleguen va un push (empuje) desde un repositorio local. bundle Controlar conjuntos de cambios entrantes que lleguen desde otro repositorio a trav s de un paquete. e La secci n [acl.allow] controla los usuarios a los que les est permitido a adir conjuntos de cambios al reposo a n itorio. Si esta secci n no est presente, se le permite acceso a todos los usuarios excepto a los que se les haya negado o a explcitamente el acceso. Si esta secci n no est presente, se niega el acceso a todos los usuarios excepto a todos a los o a que se les haya permitido de manera explcita (as que una secci n vaca implica que se niega el acceso a todos los o usuarios). La secci n [acl.deny] determina a qu usuarios no se les permite a adir conjuntos de cambios al repositorio. Si o e n esta secci n no est presente o est vaca, no se niega el acceso a ning n usuario. o a a u La sintaxis para los cheros [acl.allow] y [acl.deny] es id ntica. A la izquierda de cada entrada se encuentra e un patr n glob que asocia cheros o directorios, respecto a la raz del repositorio; a la derecha, un nombre usuario. o En el siguiente ejemplo, el usuario escritordoc s lo puede empujar cambios al directorio docs del repositorio, o mientras que practicante puede enviar cambios a cualquier chero o directorio excepto fuentes/sensitivo.

1 2 3 4 5

[acl.allow] docs/** = escritordoc [acl.deny] fuentes/sensitivo/** = practicante

Pruebas y resoluci n de problemas o Si usted desea probar el gancho acl, ejec telo habilitando la opci n de salida de depuraci n habilitada. Ya que u o o usted probablemente lo estar ejecutando en un servidor donde no es conveniente (o incluso posible) pasar la opci n a o --debug, no olvide que usted puede habilitar la salida de depuraci n en su hgrc: o
1 2

[ui] debug = true Con esto habilitado, el gancho acl imprimir suciente informaci n para permitirle saber porqu est permitiendo o a o e a denegando la operaci n de empujar a usuarios especcos. o
2 N.

del T. Fuentes.

118

10.7.2.

bugzillaintegraci n con Bugzilla o

La extensi n bugzilla a ade un comentario a un fallo Bugzilla siempre que encuentre una referencia al ID de o n dicho fallo en un mensaje de consignaci n. Usted puede instalar este gancho en un servidor compartido, para que cada o vez que un usuario remoto empuje cambios al servidor, el gancho sea ejecutado. Se a ade un comentario al fallo que se ve as (usted puede congurar los contenidos del comentariovea m s n a abajo):
1 2 3 4 5 6 7 8

Changeset aad8b264143a, made by Joe User <joe.user@domain.com> in the frobnitz repository, refers to this bug. For complete details, see http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a Changeset description: Fix bug 10483 by guarding against some NULL pointers El valor de este gancho se encuentra en que automatiza el proceso de actualizar un fallo cuando un conjunto de cambios se reera a el. Si usted congura este gancho adecuadamente, har f cil para la gente navegar directamente desde un a a fallo Bugzilla a un conjunto de cambios que se reere a ese fallo. Usted puede usar el c digo de este gancho como un punto de partida para otras recetas de integraci n con Bugzilla o o a n m s ex ticas. Ac hay algunas posibilidades: u a o a Requerir que cada conjunto de cambios tenga un ID de fallo en su mensaje de consignaci n. En este caso, usted o querr congurar el gancho como uno de tipo pretxncommit. Esto le permitir al gancho rechazar cambios que a a no contiene IDs de fallos. Permitir a los conjuntos de cambios entrantes modicar autom ticamente el estado de un fallo, as como simplea mente a adir un comentario. Por ejemplo, el gancho podra reconocer la cadena corregido fallo 31337 como n la se al de que debera actualizar el estado del fallo 31337 a requiere pruebas. n Conguraci n del gancho bugzilla o Usted debera congurar este gancho en el hgrc de su servidor como un gancho incoming3 , por ejemplo como sigue:

1 2

[hooks] incoming.bugzilla = python:hgext.bugzilla.hook Debido a la naturaleza especializada de este gancho, y porque Bugzilla no fue escrito con este tipo de integraci n o en mente, congurar este gancho es un proceso algo complejo. Antes de empezar, usted debe instalar la interfaz de Python para MySQL en los sistemas en los que se vaya a ejecutar el gancho. Si no est disponible como paquete binario para su sistema, usted puede descargar el paquete a desde [Dus]. La informaci n para congurar este gancho se ubica en la secci n [bugzilla] de su hgrc. o o

version La versi n de Bugzilla instalada en el servidor. El esquema de base de datos que Bugzilla usa cambia ocasiono almente, as que este gancho debe saber exactamente qu esquema usar. A la fecha, la unica versi n soportada e o es la 2.16. host El nombre de m quina (hostname) del servidor MySQL que almacena sus datos Bugzilla. La base de datos debe a ser congurada para permitir conexiones desde las m quinas en las que usted ejecute el gancho bugzilla. a
3 N.

del T. Entrante.

119

user El nombre de usuario que se usar para conectarse al servidor MySQL. La base de datos debe ser congurada a para permitir a dicho usuario conectarse desde cualquiera de las m quinas en las que se ejecute el gancho a bugzilla. Este usuario debe tener acceso y poder modicar las tablas de Bugzilla. El valor por defecto para este tem es bugs, que es el nombre est ndar del usuario para Bugzilla en una base de datos MySQL. a password La contrase a MySQL para el usuario congurado anteriormente. Esta es almacenada como texto plano, as que n usted deber asegurarse de que los usuarios no autorizados no puedan leer el chero hgrc en donde usted guarda a esta informaci n. o db El nombre de la base de datos Bugzilla en el servidor MySQL. El nombre por defecto para este tem es bugs, que es el nombre est ndar de la base de datos MySQL en donde Bugzilla almacena sus datos. a notify Si usted desea que Bugzilla enve un correo de noticaci n a los suscriptores despu s de que el gancho haya o e a adido un comentario a un fallo, necesitar que este gancho ejecute un comando siempre que actualice la base n a de datos. El comando que se ejecute depende de en d nde haya sido instalado Bugzilla, pero tpicamente se o ver as, si usted ha instalado Bugzilla en /var/www/html/bugzilla: a
1

cd /var/www/html/bugzilla && ./processmail %s nobody@nowhere.com El programa processmail de Bugzilla espera recibir un ID de fallo (el gancho reemplaza %s por el ID del fallo) y una direcci n de correo. Tambi n espera poder escribir a ciertos cheros en el directorio en que se o e ejecuta. Si Bugzilla y este gancho no est n instalados en la misma m quina, usted deber encontrar una manera a a a de ejecutar processmail en el servidor donde est instalado Bugzilla. a

Asociar nombres de consignadores a nombres de usuario Bugzilla Por defecto, el gancho bugzilla trata de usar la direcci n de correo electr nico de la persona que hizo la o o consignaci n del conjunto de cambios como el nombre de usuario Bugzilla con el cual debe actualizar el fallo. Si o esto no se ajusta a sus necesidades, es posible asociar direcciones de correo a nombres de usuario Bugzilla usando una secci n [usermap]. o Cada tem en la secci n [usermap] contiene una direcci n de correo electr nico a la izquierda, y un nombre de o o o usuario Bugzilla a la derecha.
1 2

[usermap] jane.user@example.com = jane Usted puede mantener los datos de [usermap] en un chero hgrc, o decirle al gancho bugzilla que lea la informaci n desde un chero usermap externo. En este caso, usted puede almacenar los datos de usermap en (por ejemplo) un o repositorio modicable por los usuarios. Esto hace posible para sus usuarios mantener sus propias entradas usermap. El chero hgrc principal se vera as:

1 2 3

# fichero hgrc normal se refiere a un fichero usermap externo [bugzilla] usermap = /home/hg/repos/userdata/bugzilla-usermap.conf Mientras que el chero usermap al que se hace referencia se vera as:

1 2 3

# bugzilla-usermap.conf - dentro de un repositorio hg [usermap] stephanie@example.com = steph

120

Congurar el texto que se anade a un fallo Usted puede congurar el texto que este gancho a ade como comentario; usted los especica como una plantilla n Mercurial. Varias entradas hgrc (a n en la secci n [bugzilla]) controlan este comportamiento. u o strip La cantidad de elementos iniciales de ruta a remover de un nombre de ruta del repositorio para construir una ruta parcial para una URL. Por ejemplo, si los repositorios en su servidor se ubican en /home/hg/repos, y usted tiene un repositorio cuya ruta es /home/hg/repos/app/tests, entonces jar strip a 4 resultar en una ruta a parcial de app/tests. El gancho har disponible esta ruta parcial cuando expanda una plantilla, como webroot. a template El texto de la plantilla a usar. En adici n a las variables usuales relacionadas con conjuntos de cambios, esta o plantilla puede usar hgweb (el valor del tem de conguraci n hgweb de arriba) y webroot (la ruta construida o usando strip arriba). Adicionalmente, usted puede a adir un tem baseurl a la secci n [web] de su hgrc. El gancho bugzilla pubn o licar esto cuando expanda una plantilla, como la cadena base a usar cuando se construya una URL que le permita a a los usuarios navegar desde un comentario de Bugzilla a la vista de un conjunto de cambios. Ejemplo:
1 2

[web] baseurl = http://hg.domain.com/ A continuaci n se presenta un ejemplo completo de conguraci n para el gancho bugzilla. o o

1 2 3 4 5 6 7 8 9 10 11 12 13

[bugzilla] host = bugzilla.example.com password = mypassword version = 2.16 # server-side repos live in /home/hg/repos, so strip 4 leading # separators strip = 4 hgweb = http://hg.example.com/ usermap = /home/hg/repos/notify/bugzilla.conf template = Changeset {node|short}, made by {author} in the {webroot} repo, refers to this bug. nFor complete details, see {hgweb}{webroot}?cmd=changeset;node={node|short} nChangeset description: n t{desc|tabindent} Pruebas y resoluci n de problemas o Los problemas m s comunes que aparecen en la conguraci n del gancho bugzilla suelen estar relacionados con a o la ejecuci n del gui n de Bugzilla processmail y la asociaci n de nombres de consignadores a nombres de usuario. o o o Recuerde que en la secci n 10.7.2 arriba el usuario que ejecuta el proceso Mercurial en el servidor es tambi n o e el usuario que ejecutar el gui n processmail. El gui n processmail algunas veces hace que Bugzilla escriba en a o o cheros en su directorio de conguraci n, y los cheros de conguraci n de Bugzilla usualmente son propiedad del o o usuario bajo el cual se ejecuta el servidor web. Usted puede hacer que processmail sea ejecutado con la identidad del usuario adecuado usando el comando sudo. A continuaci n se presenta una entrada de ejemplo para un chero sudoers. o

hg_user = (httpd_user) NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s Esto permite que el usuario hg user ejecute el programa processmail-wrapper con la identidad del usuario httpd user. Esta indirecci n a trav s de un gui n envoltorio es necesaria, porque processmail espera que al ser ejecutado su o e o directorio actual sea aquel en el cual se instal Bugzilla; usted no puede especicar ese tipo de condici n en un chero o o sudoers. Los contenidos del giu n envoltorio son simples: o 121

1 2

#!/bin/sh cd dirname $0 && ./processmail "$1" nobody@example.com No parece importar qu direcci n de correo se le pase a processmail. e o Si su [usermap] no es congurada correctamente, los usuarios ver n un mensaje de error del gancho bugzilla a cuando empujen cambios al servidor. El mensaje de error se ver as: a

cannot find bugzilla user id for john.q.public@example.com Lo que esto quiere decir es que la direcci n del consignador, john.q.public@example.com, no es un nombre de o usuario Bugzilla v lido, ni tiene una entrada en su [usermap] que lo asocie con un nombre de usuario v lido Bugzilla. a a

10.7.3.

notifyenviar noticaciones de correo electr nico o

Aunque el servidor web embebido de Mercurial provee noticaciones de cambios en cada repositorio, muchas personas preeren recibir las noticaciones de cambios va correo electr nico. El gancho notify4 le permite a usted o enviar noticaciones a un conjunto de direcciones de correo cuando lleguen conjuntos de cambios en los que los subscriptores est n interesados. e De la misma forma que con el gancho bugzilla, el gancho notify est orientado a plantillas, as que usted puede a personalizar los contenidos del mensaje de noticaci n que se enva. o Por defecto, el gancho notify incluye un diff de cada conjunto de cambios que se enva; usted puede limitar el tama o del diff, o desactivar completamente esta caracterstica. Es util para permitir a los subscriptores revisar los n cambios inmediatamente, en vez de tener que hacer clic para visitar una URL. Conguraci n del gancho notify o Usted puede congurar el gancho notify para enviar un mensaje de correo por conjunto de cambios entrante, o uno por grupo entrante de conjuntos de cambios (todos los que llegaron en un unico empuje o jalado).
1 2 3 4 5

[hooks] # enviar un correo por grupo de cambios changegroup.notify = python:hgext.notify.hook # enviar un correo por cambio incoming.notify = python:hgext.notify.hook La informaci n para congurar este gancho se ubica en la secci n [notify] de un chero hgrc. o o test Por defecto, este gancho no enva correos en absoluto; en vez de eso, imprime el mensaje que se enviara. Fije este tem en false para permitir el envo de correos. El motivo por el que el envo de correos est desactivado es a que hacen falta varios intentos para congurar esta extensi n exactamente como usted desea, y sera maleducado o enviar a los subscriptores una cantidad de noticaciones rotas mientras usted depura su conguraci n. o config La ruta a un chero de conguraci n que contiene informaci n de subscripci n. Esto se mantiene separado o o o del hgrc principal para que usted pueda mantenerlo en un repositorio. La gente puede clonar ese repositorio, actualizar sus subscripciones, y empujar los cambios de vuelta a su servidor. strip La cantidad de caracteres iniciales de separaci n de ruta a remover de la ruta del repositorio, al decidir si un o repositorio tiene subscriptores. Por ejemplo, si los repositorios en su servidor est n en /home/hg/repos, y a notify est trabajando con un repositorio llamado /home/hg/repos/shared/test, jar strip a 4 har que a a notify elimine las partes iniciales de la ruta hasta shared/test, y asociar los subscriptores frente a dicha a ruta.
4 N.

del T. Noticaci n. o

122

template El texto de plantilla a usar cuando se enven mensajes. Especica los contenidos de la cabecera del mensaje y el cuerpo del mismo. maxdiff El n mero m ximo de lneas de datos de diff a a adir al nal de un mensaje. Si la longitud de un diff es mayor u a n a eso, se trunca. Por defecto, est jado en 300. Fije esto a 0 para omitir los diffs en los correos de noticaci n. a o sources Una lista de fuentes de conjuntos de cambios a considerar. Esto le permite a usted indicar a notify para que s lo enve correos acerca de cambios que usuarios remotos hayan empujado al repositorio va un servidor, por o ejemplo. Vea la secci n 10.8.3 para las fuentes que usted puede especicar aqu. o Si usted ja el tem baseurl en la secci n [web], usted lo puede usar en una plantilla; estar disponible como o a webroot. A continuaci n se presenta un ejemplo completo de conguraci n para el gancho notify. o o
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

[notify] # enviar correo test = false # datos de subscriptores estn en el repositorio notify a config = /home/hg/repos/notify/notify.conf # repos estn en /home/hg/repos on server, as que elimine 4 a # caracteres"/" strip = 4 template = X-Hg-Repo: {webroot} Subject: {webroot}: {desc|firstline|strip} From: {author} changeset {node|short} in {root} details: {baseurl}{webroot}?cmd=changeset;node={node|short} description: {desc|tabindent|strip} [web] baseurl = http://hg.example.com/ Esto producir un mensaje que se ver como el siguiente: a a

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

X-Hg-Repo: tests/slave Subject: tests/slave: Handle error case when slave has no buffers Date: Wed, 2 Aug 2006 15:25:46 -0700 (PDT) changeset 3cba9bfe74b5 in /home/hg/repos/tests/slave details: http://hg.example.com/tests/slave?cmd=changeset;node=3cba9bfe74b5 description: Handle error case when slave has no buffers diffs (54 lines): diff -r 9d95df7cf2ad -r 3cba9bfe74b5 include/tests.h --- a/include/tests.h Wed Aug 02 15:19:52 2006 -0700 +++ b/include/tests.h Wed Aug 02 15:25:26 2006 -0700 @@ -212,6 +212,15 @@ static __inline__ void test_headers(void *h) [...snip...]

123

Pruebas y resoluci n de problemas o No olvide que por defecto, la extensi n notify no enviar ning n correo electr nico hasta que usted la congure o a u o explcitamente para hacerlo, jando el valor de test a false. Hasta que usted haga eso, simplemente se imprimir el a mensaje que se enviara.

10.8.
10.8.1.

Informaci n para escritores de ganchos o


Ejecuci n de ganchos internos o

Un gancho interno es llamado con argumentos de la siguiente forma:


1 2

def myhook(ui, repo, **kwargs): pass El par metro ui es un objeto mercurial.ui.ui. El par metro repo es un objeto mercurial.localrepo.localrepository. a a Los nombres y valores de los par metros en **kwargs dependen del gancho que se invoque, con las siguientes caraca tersticas en com n: u Si hay un par metro llamado node o parentN , contendr un ID hexadecimal de un conjunto de cambios. La a a cadena vaca es usada para representar un ID de conjunto de cambios nulo en vez de una cadena de ceros. Si hay un par metro llamado url, contendr la URL de un repositorio remoto, si puede ser determinada. a a Los par metros booleanos son representados como objetos bool de Python. a Un gancho interno es ejecutado sin cambiar el directorio de trabajo del proceso (a diferencia de los ganchos externos, que son ejecutados desde la raz del repositorio). El gancho no debe cambiar el directorio de trabajo del proceso, porque esto hara que falle cualquier llamada que se haga a la API de Mercurial. Si un gancho retorna el valor booleano false5 , se considera que este tuvo exito. Si retorna true6 o genera una excepci n, se considera que ha fallado. Una manera util de pensar en esta convenci n de llamado es dgame si usted o o fall . o Note que los IDs de conjuntos de cambios son pasados a los ganchos de Python como cadenas hexadecimales, no como los hashes binarios que la API de Mercurial usa normalmente. Para convertir un hash de hexadecimal a binario, use la funci n mercurial.node.bin. o

10.8.2.

Ejecuci n de ganchos externos o

Un gancho externo es pasado al int rprete de comandos del usuario bajo el cual se ejecuta Mercurial. Las care actersticas del int rprete, como sustituci n de variables y redirecci n de comandos, est n disponibles. El gancho es e o o a ejecutado desde el directorio raz del repositorio (a diferencia de los ganchos internos, que se ejecutan desde el mismo directorio en que Mercurial fue ejecutado). Los par metros para el gancho se pasan como variables de entorno. El nombre de cada variable de entorno se pasa a a may sculas y se le a ade el prejo HG . Por ejemplo, si el nombre de un par metro es node, el nombre de la u n a variable de entorno que almacena el par metro se llamar HG NODE. a a Un par metro booleano se representa con la cadena 1 para true, 0 para false. Si una variable se llama a HG NODE, HG PARENT1 o HG PARENT2, contendr un ID de conjunto de cambios representado como una cadena hexa adecimal. La cadena vaca es usada para representar un ID de conjunto de cambios nulo en vez de una cadena de ceros. Si una variable de entorno se llama HG URL, contendr la URL de un repositorio remoto, si puede ser determia nada. Si un gancho termina con un c digo de salida de cero, se considera que tuvo exito. Si termina con un c digo de o o salida diferente de cero, se considera que fall . o
6 N. 5 N.

del T. Falso. del T. Verdadero.

124

10.8.3.

Averiguar de d nde vienen los conjuntos de cambios o

Un gancho que involucra la transferencia de conjuntos de cambios entre un repositorio local y otro puede ser capaz de averiguar informaci n acerca de el otro lado. Mercurial sabe c mo son transferidos los conjuntos de cambios, y o o en muchos casos tambi n desde o hacia donde est n siendo transferidos. e a Fuentes de conjuntos de cambios Mercurial le indicar a un gancho cu les son, o fueron, los medios usados para transferir los conjuntos de cambios a a entre repositorios. Esta informaci n es provista por Mercurial en un par metro Python llamado source7 , o una variable o a de entorno llamada HG SOURCE. serve Los conjuntos de cambios son transferidos desde o hacia un repositorio remoto a trav s de http o ssh. e pull Los conjuntos de cambios son transferidos va una operaci n de jalado de un repositorio a otro. o push Los conjuntos de cambios son transferidos va un empuje de un repositorio a otro. bundle Los conjuntos de cambios son transferidos desde o hacia un paquete. A d nde van los cambiosURLs de repositorios remotos o Cuando es posible, Mercurial le indicar a los ganchos la ubicaci n de el otro lado de una actividad que transera a o datos de conjuntos de cambios entre repositorios. Esto es provisto por Mercurial en un par metro Python llamado url, a o en una variable de entorno llamada HG URL. No siempre esta informaci n est disponible. Si un gancho es invocado un repositorio que es servido a trav s de o a e http o ssh, Mercurial no puede averiguar d nde est el repositorio remoto, pero puede saber desde d nde se conecta el o a o cliente. En esos casos, la URL tendr una de las siguientes formas: a remote:ssh:ip-addresscliente ssh remoto, en la direcci n IP dada. o remote:http:ip-addresscliente remoto http, en la direcci n IP dada. Si el cliente est usando SSL, o a tendr la forma remote:https:ip-address. a Vacono se pudo descubrir informaci n acerca del cliente remoto. o

10.9.
10.9.1.

Referencia de ganchos
changegroupluego de anadir conjuntos de cambios remotos

Este gancho es ejecutado luego de que un grupo de conjuntos de cambios preexistentes ha sido a adido al reposn itorio, por ejemplo va un hg pull o hg unbundle. Este gancho es ejecutado una vez por cada operaci n que o a ade uno o m s conjuntos de cambios. Este gancho se diferencia del gancho incoming, que es ejecutado una vez por n a cada conjunto de cambios, sin importar si los cambios llegan en grupo. Algunos usos posibles para este gancho includen el probar o ensamblar los conjuntos de cambios a adidos, actun alizar una base de datos de fallos, o noticar a subscriptores de que el repositorio contiene nuevos cambios. Par metros para este gancho: a node Un ID de conjunto de cambios. El ID del primer conjunto de cambios que fue a adido en el grupo. Todos los n conjuntos de cambios entre este y la punta (tip), inclusive, fueron a adidos por un unico jalado (hg pull), n empuje (hg push) o hg unbundle. source Una cadena. La fuente de estos cambios. Vea la secci n 10.8.3 para m s detalles. o a url Una URL. La ubicaci n del repositorio remoto, si es conocida. Vea la secci n 10.8.3 para m s informaci n. o o a o Veta tambi n: incoming (secci n 10.9.3), prechangegroup (secci n 10.9.5), pretxnchangegroup (secci n 10.9.9) e o o o
7 N.

del T. Fuente.

125

10.9.2.

commitluego de la creaci n de un nuevo conjunto de cambios o

Este gancho es ejecutado luego de la creaci n de un nuevo conjunto de cambios. o Par metros para este gancho: a node Un ID de conjunto de cambios. El ID de conjunto de cambios del conjunto de cambios que acab de ser o consignado. parent1 Un ID de conjunto de cambios. El ID de conjunto de cambios del primer padre del conjunto de cambios que acaba de ser consignado. parent2 Un ID de conjunto de cambios. El ID de conjunto de cambios del segundo padre del conjunto de cambios que acaba de ser consignado. Vea tambi n: precommit (secci n 10.9.6), pretxncommit (secci n 10.9.10) e o o

10.9.3.

incomingluego de que un conjunto de cambios remoto es anadido

Este gancho es ejecutado luego de que un conjunto de cambios preexistente ha sido a adido al repositorio, por n ejemplo, va un hg push. Si un grupo de conjuntos de cambios fue a adido en una sola operaci n, este gancho es n o ejecutado una vez por cada conjunto de cambios a adido. n Usted puede usar este gancho para los mismos nes que el gancho changegroup (secci n 10.9.1); simplemente o algunas veces es m s conveniente ejecutar un gancho una vez por cada grupo de conjuntos de cambios, mientras que a otras es m s util correrlo por cada conjunto de cambios. a Par metros para este gancho: a node Un ID de conjunto de cambios. El ID del conjunto de cambios reci n a adido. e n source Una cadena. La fuente de estos cambios. Vea la secci n 10.8.3 para m s detalles. o a url Una URL. La ubicaci n del repositorio remoto, si es conocida. Vea la secci n 10.8.3 para m s informaci n. o o a o Vea tambi n: changegroup (secci n 10.9.1) prechangegroup (secci n 10.9.5), pretxnchangegroup (secci n 10.9.9) e o o o

10.9.4.

outgoingluego de la propagaci n de los conjuntos de cambios o

Este gancho es ejecutado luego de que un grupo de conjuntos de cambios ha sido propagado fuera de este repositorio, por ejemplo por un comando hg push o hg bundle. Un uso posible para este gancho es noticar a los administradores que los cambios han sido jalados. Par metros para este gancho: a node Un ID de conjunto de cambios. El ID del primer conjunto de cambios del grupo que fue enviado. source Una cadena. La fuente de la operaci n (vea la secci n 10.8.3). Si un cliente remoto jal cambios de este o o o repositorio, source ser serve. Si el cliente que obtuvo los cambios desde este repositorio era local, source a ser bundle, pull, o push, dependiendo de la operaci n que llev a cabo el cliente. a o o url Una URL. La ubicaci n del repositorio remoto, si es conocida. Vea la secci n 10.8.3 para m s informaci n. o o a o Vea tambi n: preoutgoing (secci n 10.9.7) e o

126

10.9.5.

prechangegroupantes de empezar la adici n de conjuntos de cambios remotos o

Este gancho de control es ejecutado antes de que Mercurial empiece a a adir un grupo de conjuntos de cambios de n otro repositorio. Este gancho no tiene ninguna informaci n acerca de los conjuntos de cambios que van a ser a adidos, porque es o n ejecutado antes de que se permita que empiece la transmisi n de dichos conjuntos de cambios. Si este gancho falla, o los conjuntos de cambios no ser n transmitidos. a Un uso para este gancho es prevenir que se a adan cambios externos a un repositorio. Por ejemplo, usted podra n usarlo para congelar temporal o permanentemente una rama ubicada en un servidor para que los usuarios no puedan empujar cambios a ella, y permitiendo al mismo tiempo modicaciones al repositorio por parte de un administrador local. Par metros para este gancho: a source Una cadena. La fuente de estos cambios. Vea la secci n 10.8.3 para m s detalles. o a url Una URL. La ubicaci n del repositorio remoto, si es conocida. Vea la secci n 10.8.3 para m s informaci n. o o a o Vea tambi n: changegroup (secci n 10.9.1), incoming (secci n 10.9.3), , pretxnchangegroup (secci n 10.9.9) e o o o

10.9.6.

precommitantes de iniciar la consignaci n de un conjunto de cambios o

Este gancho es ejecutado antes de que Mercurial inicie la consignaci n de un nuevo conjunto de cambios. Es o ejecutado antes de que Mercurial tenga cualquier de los metadatos para la consignaci n, como los cheros a ser o consignados, el mensaje de consignaci n, o la fecha de consignaci n. o o Un uso para este gancho es deshabilitar la capacidad de consignar nuevos conjuntos de cambios, pero permitiendo conjuntos de cambios entrantes. Otro es ejecutar un proceso de ensamble/compilaci n o prueba, y permitir la o consignaci n s lo si el ensamble/compilaci n o prueba tiene exito. o o o Par metros para este gancho: a parent1 Un ID de conjunto de cambios. El ID de conjunto de cambios del primer padre del directorio de trabajo. parent2 Un ID de conjunto de cambios. El ID de conjunto de cambios del segundo padre del directorio de trabajo. Si la consignaci n contin a, los padres del directorio de trabajo se convertir n en los padres del nuevo conjunto de o u a cambios. Vea tambi n: commit (secci n 10.9.2), pretxncommit (secci n 10.9.10) e o o

10.9.7.

preoutgoingantes de empezar la propagaci n de conjuntos de cambios o

Este gancho es ejecutado antes de que Mercurial conozca las identidades de los conjuntos de cambios que deben ser transmitidos. Un uso para este gancho es evitar que los cambios sean transmitidos a otro repositorio. Par metros para este gancho: a source Una cadena. La fuente la operaci n que est tratando de obtener cambios de este repositorio (vea la seco a ci n 10.8.3). Revise la documentaci n para el par metro source del gancho outgoing, en la secci n 10.9.4, o o a o para ver los posibles valores de este par metro. a url Una URL. La ubicaci n del repositorio remoto, si es conocida. Vea la secci n 10.8.3 para m s informaci n. o o a o Vea tambi n: outgoing (secci n 10.9.4) e o

127

10.9.8.

pretagantes de etiquetar un conjunto de cambios

Este gancho de control es ejecutado antes de la creaci n de una etiqueta. Si el gancho termina exitosamente, la o creaci n de la etiqueta contin a. Si el gancho falla, no se crea la etiqueta. o u Par metros para este gancho: a local Un booleano. Indica si la etiqueta es local a esta instancia del repositorio (p.e. almacenado en .hg/localtags) o administrado por Mercurial (almacenado en .hgtags). node Un ID de conjunto de cambios. El ID del conjunto de cambios a etiquetar. tag Una cadena. El nombre de la etiqueta por crear. Si la etiqueta que se va a crear se encuentra bajo control de revisiones, los ganchos precommit y pretxncommit (secciones 10.9.2 y 10.9.10) tambi n ser n ejecutados. e a Vea tambi n: tag (secci n 10.9.12) e o

10.9.9.

pretxnchangegroupantes de completar la adici n de conjuntos de cambios o remotos

Este gancho de control es ejecutado antes de una transacci nla que maneja la adici n de un grupo de conjuntos o o de cambios nuevos desde fuera del repositoriose complete. Si el gancho tiene exito, la transacci n se completa, y o todos los conjuntos de cambios se vuelven permanentes dentro de este repositorio. Si el gancho falla, la transacci n es o deshecha, y los datos para los conjuntos de cambios son eliminados. Este gancho puede acceder a los metadatos asociados con los conjuntos de cambios casi a adidos, pero no debe n hacer nada permanente con estos datos. Tampoco debe modicar el directorio de trabajo. Mientras este gancho est corriendo, si otro proceso Mercurial accesa el repositorio, podr ver los conjuntos de a a cambios casi a adidos como si fueran permanentes. Esto puede llevar a condiciones de carrera si usted no toma n precauciones para evitarlas. Este gancho puede ser usado para examinar autom ticamente un grupo de conjuntos de cambios. Si el gancho falla, a todos los conjuntos de cambios son rechazados cuando la transacci n se deshace. o Par metros para este gancho: a node Un ID de conjunto de cambios. El ID del primer conjunto de cambios que fue a adido en el grupo. Todos los n conjuntos de cambios entre este y el tip, inclusive, fueron a adidos por un unico hg pull, hg push o hg n unbundle. source Una cadena. La fuente de estos cambios. Vea la secci n 10.8.3 para m s detalles. o a url Una URL. La ubicaci n del repositorio remoto, si es conocida. Vea la secci n 10.8.3 para m s informaci n. o o a o Vea tambi n: changegroup (secci n 10.9.1), incoming (secci n 10.9.3), prechangegroup (secci n 10.9.5) e o o o

10.9.10.

pretxncommitantes de completar la consignaci n de un nuevo conjunto de o cambios

Este gancho de control es ejecutado antes de que una transacci nque maneja una nueva consignaci nse como o plete. Si el gancho tiene exito, la transacci n se completa y el conjunto de cambios se hace permanente dentro de este o repositorio. Si el gancho falla, la transacci n es deshecha, y los datos de consignaci n son borrados. o o Este gancho tiene acceso a los metadatos asociados con el pr cticamente nuevo conjunto de cambios, pero no a debera hacer nada permanente con estos datos. Tampoco debe modicar el directorio de trabajo. Mientras este gancho est corriendo, si otro proceso Mercurial accesa este repositorio, podr ver el pr cticamente a a a nuevo conjunto de cambios como si fuera permanente. Esto puede llevar a condiciones de carrera si usted no toma precauciones para evitarlas. Par metros para este gancho: a 128

node Un ID de conjunto de cambios. El ID del conjunto de cambios reci n consignado. e parent1 Un ID de conjunto de cambios. El ID de conjunto de cambios del primer padre del conjunto de cambios que acaba de ser consignado. parent2 Un ID de conjunto de cambios. El ID de conjunto de cambios del segundo padre del conjunto de cambios que acaba de ser consignado. Vea tambi n: precommit (secci n 10.9.6) e o

10.9.11. preupdateantes de actualizar o fusionar el directorio de trabajo


Este gancho de control es ejecutado antes de actualizar o fusionar el directorio de trabajo. Es ejecutado s lo si las o revisiones usuales de Mercurial antes de las actualizaciones determinan que la actualizaci n o fusi n pueden proceder. o o Si el gancho termina exitosamente, la actualizaci n o fusi n pueden proceder.; si falla, la actualizaci n o fusi n no o o o o empiezan. Par metros para este gancho: a parent1 Un ID de conjunto de cambios. El ID del padre al que el directorio de trabajo ser actualizado. Si se est fusioa a nando el directorio de trabajo, no cambiar este padre. a parent2 Un ID de conjunto de cambios. S lo est denido si se est fusionando el directorio de trabajo. El ID de la o a a revisi n con la cual est siendo fusionado el directorio de trabajo. o a Vea tambi n: update (secci n 10.9.13) e o

10.9.12.

tagluego de etiquetar un conjunto de cambios

Este gancho es ejecutado luego de la creaci n de una etiqueta. o Par metros para este gancho: a local Un booleano. Indica si la etiqueta es local a esta instancia del repositorio (p.e. almacenado en .hg/localtags) o administrado por Mercurial (almacenado en .hgtags). node Un ID de conjunto de cambios. El ID del conjunto de cambios que fue etiquetado. tag Una cadena. El nombre de la etiqueta que fue creada. Si la etiqueta creada est bajo control de revisiones, el gancho commit (secci n 10.9.2) es ejecutado antes de este a o gancho. Vea tambi n: pretag (secci n 10.9.8) e o

10.9.13.

updateluego de actualizar o fusionar el directorio de trabajo

Este gancho es ejecutado despu s de una actualizaci n o fusi n en el directorio de trabajo. Ya que una fusi n e o o o puede fallar (si el comando externo hgmerge no puede resolver los conictos en un chero), este gancho indica si la actualizaci n o fusi n fueron completados adecuadamente. o o error Un booleano. Indica si la actualizaci n o fusi n fue completada exitosamente. o o parent1 Un ID de conjunto de cambios. El ID del padre al cual fue actualizado el directorio de trabajo. Si se fusion el o directorio de trabajo, no se habr cambiado este padre. a parent2 Un ID de conjunto de cambios. S lo est denido si se fusion el directorio de trabajo. El ID de la revisi n con o a o o la que fue fusionado el directorio de trabajo. Vea tambi n: preupdate (secci n 10.9.11) e o 129

Captulo 11

Personalizar los mensajes de Mercurial


Mercurial provee un poderoso mecanismo que permite controlar como despliega la informaci n. El mecanismo se o basa en plantillas. Puede usar plantillas para generar salida especca para una orden particular o para especicar la visualizaci n completa de la interfaz web embebida. o

11.1.

Usar estilos que vienen con Mercurial

Hay ciertos estilos listos que vienen con Mercurial. Un estilo es simplemente una plantilla predeterminada que alguien escribi e instal en un sitio en el cual Mercurial puede encontrarla. o o Antes de dar un vistazo a los estilos que trae Mercurial, revisemos su salida usual.
1 2 3 4 5 6 7

$ hg log -r1 changeset: 1:522d8d7a8fda tag: mytag user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:30 2009 +0000 summary: added line to end of <<hello>> file.

Es en cierta medida informativa, pero ocupa mucho espaciocinco lneas de salida por cada conjunto de cambios. El estilo compact lo reduce a tres lneas, presentadas de forma suscinta.
1 2 3 4 5 6 7 8 9 10 11 12 13

$ hg log --style compact 3[tip] b638ce454bd0 2009-02-10 18:23 +0000 Added tag v0.1 for changeset 4b75acdd4698 2[v0.1] 4b75acdd4698 2009-02-10 18:23 +0000 Added tag mytag for changeset 522d8d7a8fda 1[mytag] 522d8d7a8fda 2009-02-10 18:23 +0000 added line to end of <<hello>> file. 0 d0c3b909ac1b added hello 2009-02-10 18:23 +0000 bos

bos

bos

bos

El estilo de la bitcora de cambios vislumbra el poder expresivo del sistema de plantillas de Mercurial. Este a estilo busca seguir los est ndares de bit cora de cambios del proyecto GNU[RS]. a a 130

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

$ hg log --style changelog 2009-02-10 Bryan OSullivan <bos@serpentine.com> * .hgtags: Added tag v0.1 for changeset 4b75acdd4698 [b638ce454bd0] [tip] * .hgtags: Added tag mytag for changeset 522d8d7a8fda [4b75acdd4698] [v0.1] * goodbye, hello: added line to end of <<hello>> file. in addition, added a file with the helpful name (at least i hope that some might consider it so) of goodbye. [522d8d7a8fda] [mytag] * hello: added hello [d0c3b909ac1b] No es una sorpresa que el estilo predeterminado de Mercurial se llame default1 .

11.1.1.

Especicar un estilo predeterminado

Puede modicar el estilo de presentaci n que Mercurial usar para toda orden va el chero hgrc indicando el o a estilo que preere usar.
1 2

[ui] style = compact Si escribe un estilo, puede usarlo bien sea proveyendo la ruta a su chero de estilo o copiando su chero de estilo a un lugar en el cual Mercurial pueda encontrarlo (tpicamente el subdirectorio templates de su directorio de instalaci n de Mercurial). o

11.2.

Ordenes que soportan estilos y plantillas

Todas las ordenes de Mercurialrelacionadas con log le permiten usar estilos y plantillas: hg incoming, hg log, hg outgoing y hg tip. Al momento de la escritura del manual estas son las unicas ordenes que soportan estilos y plantillas. Dado que son las ordenes m s importantes que necesitan personalizaci n, no ha habido muchas solicitudes desde la comunidad de a o usuarios de Mercurial para a adir soporte de plantillas y estilos a otras ordenes. n

11.3.

Cuestiones b sicas de plantillas a

Una plantilla de Mercurial es sencillamente una pieza de texto. Cierta porci n nunca cambia, otras partes se o expanden, o reemplazan con texto nuevo cuando es necesario.
1 N.

del T. predeterminado

131

Antes de continuar, veamos de nuevo un ejemplo sencillo de la salida usual de Mercurial:


1 2 3 4 5 6 7

$ hg log -r1 changeset: 1:522d8d7a8fda tag: mytag user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:30 2009 +0000 summary: added line to end of <<hello>> file.

Ahora, ejecutemos la misma orden, pero usemos una plantilla para modicar su salida:
1 2

$ hg log -r1 --template i saw a changeset\n i saw a changeset El ejemplo anterior ilustra la plantilla m s sencilla posible; es solamente una porci n est tica de c digo que se a o a o imprime una vez por cada conjunto de cambios. La opci n --template de la orden hg log indica a Mercurial usar o el texto dado como la plantilla cuando se imprime cada conjunto de cambios. Observe que la cadena de plantilla anterior termina con el texto \n. Es una secuencia de control, que le indica a Mercurial imprimira una nueva lnea al nal de cada objeto de la plantilla. Si omite esta nueva lnea, Mercurial colocar cada pieza de salida seguida. Si desea m s detalles acerca de secuencias de control, vea la secci n 11.5. a a o Una plantilla que imprime una cadena ja de texto siempre no es muy util; intentemos algo un poco m s complejo. a

1 2 3 4 5 6 7

$ i i i

hg log --template i saw a changeset: {desc}\n saw a changeset: Added tag v0.1 for changeset 4b75acdd4698 saw a changeset: Added tag mytag for changeset 522d8d7a8fda saw a changeset: added line to end of <<hello>> file.

in addition, added a file with the helpful name (at least i hope that some might consider it so) of goodby i saw a changeset: added hello Como puede ver, la cadena {desc} en la plantilla ha sido reemplazada en la salida con la descricipci n de cada o conjunto de cambios. Cada vez que Mercurial encuentra texto encerrado entre corchetes ({ y }), intentar reema plazar los corchetes y el texto con la expansi n de lo que sea est adentro. Para imprimir un corchete de forma literal, o a debe escaparlo, como se describe en la secci n 11.5. o

11.4.

Palabras claves m s comunes en las plantillas a

Puede empezar a escribir plantillas sencillas r pidamente con las palabras claves descritas a continuaci n: a o author Cadena. El autor NO modicado del conjunto de cambios. branches Cadena. El nombre de la rama en la cual se consign el conjunto de cambios. Ser vaca si el nombre de la rama o a es default. date Informaci n de fecha. La fecha en la cual se consign el conjunto de cambios. No es legible por un humano, debe o o pasarla por un rltro que la desplegar apropiadamente. En la secci n 11.6 hay m s detalles acerca de ltros. La a o a fecha se expresa como un par de n meros. El primer n mero corresponde a una marca de tiempo UNIX UTC u u (segundos desde el primero de enero de 1970); la segunda es el corrimiento horario de la zona horaria del UTC en la cual se encontraba quien hizo la consignaci n, en segundos. o desc Cadena. La descripci n en texto del conjunto de cambios. o 132

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

$ hg log -r1 --template author: {author}\n author: Bryan OSullivan <bos@serpentine.com> $ hg log -r1 --template desc:\n{desc}\n desc: added line to end of <<hello>> file.

in addition, added a file with the helpful name (at least i hope that some might consider it so) of goodby $ hg log -r1 --template files: {files}\n files: goodbye hello $ hg log -r1 --template file_adds: {file_adds}\n file_adds: goodbye $ hg log -r1 --template file_dels: {file_dels}\n file_dels: $ hg log -r1 --template node: {node}\n node: 522d8d7a8fda9a24dcac9c5ccfcca067b933220b $ hg log -r1 --template parents: {parents}\n parents: $ hg log -r1 --template rev: {rev}\n rev: 1 $ hg log -r1 --template tags: {tags}\n tags: mytag

Figura 11.1: Template keywords in use files Lista de cadenas. Todos los cheros modicados, adicionados o eliminados por este conjunto de cambios. file adds Lista de cadenas. Ficheros adicionados por este conjunto de cambios. file dels Lista de cadenas. Ficheros eliminados por este conjunto de cambios. node Cadena. El hash de identicaci n de este conjunto de cambios como una cadena hexadecimal de 40 caracteres. o parents Lista de cadenas. Los ancestros del conjunto de cambios. rev Entero. El n mero de revisi n del repositorio local. u o tags Lista de cadenas. Todas las etiquetas asociadas al conjunto de cambios. Unos experimentos sencillos nos mostrar n qu esperar cuando usamos estas palabras claves; puede ver los resula e tados en la gura 11.1. Como mencionamos anteriormente, la palabra clave de fecha no produce salida legible por un humano, debemos tratarla de forma especial. Esto involucra usar un ltro, acerca de lo cual hay m s en la secci n 11.6. a o
1 2 3 4

$ hg log -r1 --template date: {date}\n date: 1234290210.00 $ hg log -r1 --template date: {date|isodate}\n date: 2009-02-10 18:23 +0000

11.5.

Secuencias de Control

El motor de plantillas de Mercurial reconoce las secuencias de control m s comunmente usadas dentro de las a cadenas. Cuando ve un backslash (\), ve el caracter siguiente y sustituye los dos caracteres con un reemplazo sencillo, como se describe a continuaci n: o 133

\\ Backslash, \, ASCII 134. \n Nueva lnea, ASCII 12. \r Cambio de lnea, ASCII 15. \t Tab, ASCII 11. \v Tab Vertical, ASCII 13. \{ Corchete abierto, {, ASCII 173. \} Corchete cerrado, }, ASCII 175. Como se indic arriba, si desea que la expansi n en una plantilla contenga un caracter literal \, {, o {, debe o o escaparlo.

11.6.

Uso de ltros con palabras claves

Algunos de los resultados de la expansi n de la plantilla no son f ciles de usar de inmediato. Mercurial le permite o a especicar una cadena de ltros opcionales para modicar el resultado de expandir una palabra clave. Ya ha visto el ltro usual isodate en acci n con anterioridad para hacer legible la fecha. o A continuaci n hay una lista de los ltros de Mercurial m s comunmente usados. Ciertos ltros pueden aplicarse o a a cualquier texto, otros pueden usarse unicamente en circunstancias especcas. El nombre de cada ltro est seguido a de la indicaci n de d nde puede ser usado y una descripci n de su efecto. o o o addbreaks Cualquier texto. A ade una etiqueta XHTML <br/> antes del nal de cada lnea excepto en la nal. Por n ejemplo, foo\nbar se convierte en foo<br/>\nbar. age palabra clave date. Muestra la edad de la fecha, relativa al tiempo actual. Ofrece una cadena como 10 minutes. basename Cualquier texto, pero de utilidad sobre todo en palabras claves relativas a ficheros. Trata el texto como una ruta, retornando el nombre base. Por ejemplo, foo/bar/baz, se convierte en baz. date date palabra clave. Mostrar la fecha en un formato similar a la orden date de in a similar format to the Unix, pero con la zona horaria includa. Una cadena como Mon Sep 04 15:13:13 2006 -0700. domain Cualquier texto, pero de mayor utilidad para la palabra clave author. Encuentra la primera cadena que luce como una direcci n de correo electr nico, y extrae solamente el componente del dominio. Por ejemplo, de o o Bryan OSullivan <bos@serpentine.com> se extrae serpentine.com. email Cualquier texto, pero de mayor utilidad para la palabra clave author. Extrae la primera cadena que luce como una direcci n de correo. Por ejemplo, de Bryan OSullivan <bos@serpentine.com> extrae bos@serpentine.com. o escape Cualquier texto. Reemplaza los caracteres especiales de XML/XHTML: &, < y > con las entidades XML. fill68 Cualquier texto. Lograr que el texto ocupe las primeras 68 columnas. Es util emplearlo antes de pasar el texto por el ltro tabindent, y queremos que a n quepa en una ventana de fuente ja y 80 columnas. u fill76 Cualquier texto. Lograr que el texto quepa en 76 columnas. firstline Cualquier texto. Mostrar la primera lnea de texto sin saltos de lnea. hgdate date palabra clave. Mostrar la fecha como un par de n meros legibles. Muestra una cadena como 1157407993 25200. u isodate date palabra clave. Mostrar la fecha como una cadena de texto en el formato. Muestra una cadena como 2006-09-04 15:13:13 -0700. 134

obfuscate Cualquier texto, pero de mayor utilidad para la palabra clave author. Muestra el campo de texto como una secuencia de entidades XML. Esto ayuda a eliminar ciertos robots est pidos de adquisici n de correo. u o person Cualquier texto, util sobre todo para la palabra clave author. Muestra el texto que hay antes de la direcci n de o correo electr nico. Por ejemplo, Bryan OSullivan <bos@serpentine.com> mostrara Bryan OSullivan. o rfc822date date palabra clave. Muestra una fecha con el mismo formato que se usa en los encabezados de correo. Mostrara una cadena como Mon, 04 Sep 2006 15:13:13 -0700. short Hash del conjunto de cambios. Muestra la forma corta de un hash de conjunto de cambios, of a changeset hash, p.e. una cadena hexadecimal de 12 bytes. shortdate date palabra clave. Mostrar a o, mes y da de una fecha. Muestrauna cadena como 2006-09-04. n strip Cualquier texto. Elimina todos los espacios en blanco al principio y al nal de la cadena. tabindent Cualquier texto. Muestra el texto con todas las lneas excepto la primera que comience con el caracter tab. urlescape Cualquier texto. Escapa todos los caracteres que se consideren como especiales por los parsers de URL. Por ejemplo, foo bar se convierte en foo%20bar. user Cualquier texto, util sobre todo para la palabra clave author. Retorna el usuario de una direcci n de correo. o Por ejemplo, Bryan OSullivan <bos@serpentine.com> se convierte en bos. Nota: Si trata de aplicar un ltro a una porci n de datos que no puede procesarse, o Mercurial fallar e imprimir una excepci n de Python. Por ejemplo, el tratar de a a o usar la salida de la palabra clave desc con el ltro isodate no resultar algo util. a

11.6.1.

Combinar ltros

Combinar ltros es para generar una salida en la forma como usted lo desea es muy sencillo. La cadena de ltros siguientes arman una descripci n, despu s aseguran que cabe limpiamente en 68 columnas, y las indenta con o e 8 caracteres (por lo menos en sistemas tipo Unix, en los que el tab por convenci n se extiende en 8 caracteres). o
1 2 3 4 5 6

$ hg log -r1 --template description:\n\t{desc|strip|fill68|tabindent}\n description: added line to end of <<hello>> file. in addition, added a file with the helpful name (at least i hope that some might consider it so) of goodbye. Observe el uso de \t (un caracter tab) en la plantilla para forzar que la primera lnea se indente; esto es necesario para lograr que la primera lnea luzca indentada; es necesario debido a que tabindent indenta todas las lneas excepto la primera. Tenga en cuenta que el orden de los ltros importa. El primer ltro se aplica primero al resultado de la palabra clave; el segundo al resultado de la aplicaci n del primer ltro y as sucesivamente. Por ejemplo, usar fill68|tabindent o es muy distinto al resultado de usar tabindent|fill68.

11.7.

De plantillas a estilos

Una plantilla provee una forma r pida y sencilla para dar formato a una salida. Las plantillas pueden volvers vera bosas, y es util poder darle un nombre a una plantilla. Un chero de estilo es una plantilla con un nombre, almacenado en un chero. M s a n, al usar un chero de estilo se dispara el poder del motor de plantillas en un nivel imposible de alcanzar a u usando las opci n --template desde la lnea de ordenes. o 135

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60

$ hg log -r1 --template {author}\n Bryan OSullivan <bos@serpentine.com> $ hg log -r1 --template {author|domain}\n serpentine.com $ hg log -r1 --template {author|email}\n bos@serpentine.com $ hg log -r1 --template {author|obfuscate}\n | cut -c-76 &#66;&#114;&#121;&#97;&#110;&#32;&#79;&#39;&#83;&#117;&#108;&#108;&#105;&#11 $ hg log -r1 --template {author|person}\n Bryan OSullivan $ hg log -r1 --template {author|user}\n bos $ hg log -r1 --template looks almost right, but actually garbage: {date}\n looks almost right, but actually garbage: 1234290210.00 $ hg log -r1 --template {date|age}\n 1 second $ hg log -r1 --template {date|date}\n Tue Feb 10 18:23:30 2009 +0000 $ hg log -r1 --template {date|hgdate}\n 1234290210 0 $ hg log -r1 --template {date|isodate}\n 2009-02-10 18:23 +0000 $ hg log -r1 --template {date|rfc822date}\n Tue, 10 Feb 2009 18:23:30 +0000 $ hg log -r1 --template {date|shortdate}\n 2009-02-10 $ hg log -r1 --template {desc}\n | cut -c-76 added line to end of <<hello>> file. in addition, added a file with the helpful name (at least i hope that some m $ hg log -r1 --template {desc|addbreaks}\n | cut -c-76 added line to end of <<hello>> file.<br/> <br/> in addition, added a file with the helpful name (at least i hope that some m $ hg log -r1 --template {desc|escape}\n | cut -c-76 added line to end of &lt;&lt;hello&gt;&gt; file. in addition, added a file with the helpful name (at least i hope that some m $ hg log -r1 --template {desc|fill68}\n added line to end of <<hello>> file. in addition, added a file with the helpful name (at least i hope that some might consider it so) of goodbye. $ hg log -r1 --template {desc|fill76}\n added line to end of <<hello>> file. in addition, added a file with the helpful name (at least i hope that some might consider it so) of goodbye. $ hg log -r1 --template {desc|firstline}\n added line to end of <<hello>> file. $ hg log -r1 --template {desc|strip}\n | cut -c-76 added line to end of <<hello>> file. in addition, added a file with the helpful name (at least i hope that some m 136 $ hg log -r1 --template {desc|tabindent}\n | expand | cut -c-76 added line to end of <<hello>> file. in addition, added a file with the helpful name (at least i hope tha $ hg log -r1 --template {node}\n 522d8d7a8fda9a24dcac9c5ccfcca067b933220b

11.7.1.

Los cheros de estilo m s sencillos a

Nuestro chero sencillo de estilo contiene una sola lnea:


1 2 3

$ echo changeset = "rev: {rev}\n" > rev $ hg log -l1 --style ./rev rev: 3 Se le indica a Mercurial, si est imprimiendo un conjunto de cambios, use el texto de la derecha como la plantilla. a

11.7.2.

Sintaxis de cheros de estilo

Las reglas de sintaxis para un chero de estilo son sencillas: El chero se procesa lnea por lnea. Se ignoran el espacio en blanco circundante. Se omiten las lneas en blanco. Si una lnea comienza con los caracteres # o ;, la lnea completa se trata como un comentario, y se omite como si fuera vaca. Una lnea comienza con una palabra clave. Esta debe comenzar con una caracter alfab tico o una raya al piso, e y puede contener subsecuentemente cualquier caracter alfanum rico o una raya al piso. (En notaci n de expree o siones regulares debe coincidir con [A-Za-z_][A-Za-z0-9_]*.) El pr ximo elemento debe ser un caracter =, que puede estar precedido o seguido por una cantidad arbitraria o de espacio. Si el resto de la lnea comienza y termina con caracteres encerrados entre caracteres de comillas (bien sea sencillas o dobles), se trata como cuerpo de la plantilla. Si el resto de la lnea no comienza con una comilla, se trata como el nombre de un chero; los contenidos de este chero se leer n y se usar n como cuerpo de la plantilla. a a

11.8.

Ejemplos de cheros de estilos

Para ilustrar la creaci n de un chero de estilo, construiremos algunos ejemplos. En lugar de ofrecer un chero o completo de estilo y analizarlo, replicaremos el proceso usual de desarrollo de un chero de estilo comenzando con algo muy sencillo, y avanzando por una serie de ejemplos sucesivos m s completos. a

11.8.1.

Identicar equivocaciones en cheros de estilo

Si Mercurial encuentra un problema en un chero de estilo en el cual usted est trabajando, imprime un mensaje a de error suscinto, cuando usted identique lo que signica, resulta muy util.
1 2

$ cat broken.style changeset = Tenga en cuenta que broken.style trata de denir la palabra clave changeset, pero omite dar un contenido para esta. Cuando se le indica a Mercurial que use este chero de estilo, se queja inmediatamente.

137

1 2

$ hg log -r1 --style broken.style abort: broken.style:1: parse error Este mensaje de error luce intimidante, pero no es muy difcil de seguir: El primer componente es la forma como Mercurial dice me rindo.
1

abort: broken.style:1: parse error A continuaci n viene el nombre del chero que contiene el error. o

abort: broken.style:1: parse error Siguendo el nombre del chero viene el n mero de lnea en la que se encontr el error. u o

abort: broken.style:1: parse error Finalmente, la descripci n de lo que fall . o o

abort: broken.style:1: parse error La descripci n del problema no siempre es clara (como en este caso), pero aunque sea crptica, casi siempre es o trivial la inspecci n visual de la lnea en el chero de estilo y encontrar lo que est mal. o a

11.8.2.

Identicar de forma unica un repositorio

Si desea identicar un repositorio de Mercurial de forma unica con una cadena corta como identicador, puede usar la primera revisi n en el repositorio. o
1 2

$ hg log -r0 --template {node} 92cb4692d38c537be0935f906eeff2a47033600c No es garanta de unicidad, pero no es utill en ciertos casos: many cases. No funcionar en un repositorio completamente vaco, porque un repositorio as no tiene una revisi n zero. a o Tampoco funcionar en caso (muy raro) cuando el repositorio sea una fusi n de dos repositorios independientes a o y tiene los dos directorios por ah. Hay ciertos casos en los cuales podra colocar el identicador: Como una llave en la tabla de una base de datos que administra repositorios en un servidor. Como una parte del par {ID repositorio, ID revisi n}. Almacene esta informaci n de forma independiente cuano o do ejecute construcciones automatizadas u otras actividades, de forma que pueda reconstruir posteriormente en caso de ser necesario.

138

11.8.3.

Mostrando salida parecida a Subversion

Intentemos emular la salida usual que usa otro sistema de control de revisiones, Subversion.
1 2 3 4 5 6 7 8 9 10

$ svn log -r9653 -----------------------------------------------------------------------r9653 | sean.hefty | 2006-09-27 14:39:55 -0700 (Wed, 27 Sep 2006) | 5 lines On reporting a route error, also include the status for the error, rather than indicating a status of 0 when an error has occurred. Signed-off-by: Sean Hefty <sean.hefty@intel.com> -----------------------------------------------------------------------Dado que la salida de Subversion es sencilla, es f cil copiar y pegar una porci n de su salida en un chero, y a o reemplazar el texto producido previamente por Subversion con valores base que quisi ramos ver expandidos. e

1 2 3 4 5 6

$ cat svn.template r{rev} | {author|user} | {date|isodate} ({date|rfc822date}) {desc|strip|fill76} -----------------------------------------------------------------------Esta plantilla diere en algunos detalles de la salida producida por Subversion: Subversion imprime una fecha legible (el Wed, 27 Sep 2006 en el ejemplo de salida anterior) en par ntee sis. El motor de plantillas de Mercurial no ofrece una forma sencilla de desplegar una fecha en este formato sin imprimir tambi n la hora y la zona horaria. e Emulamos las lneas de separaci n de subversion con caracteres - en una lnea. Usamos la palabra clave o header del motor de plantillas para imprimir una lnea de separaci n como la primera lnea de salida (ver m s o a abajo), para lograr una salida similara a la de Subversion. La salida de subversion incluye un conteo en el encabezado del n mero de lneas en el mensaje de consinaci n. u o No podemos replicarlo en Mercurial; el motor de plantilla no ofrece en la actualidad un ltro que cuente la cantidad de objetos que se le pasen. No me tom m s de un minuto o dos de trabajo para reemplazar texto literal de un ejemplo de salida de la salida o a de Subversion con ciertas palabras claves y ltros para ofrecer la plantilla anterior. El chero de estilo se reere sencillamente a la plantilla.

1 2 3

$ cat svn.style header = ------------------------------------------------------------------------\n\n changeset = svn.template Podramos haber includo el texto del chero plantilla directamente en el chero de estilo encerrando entre comillas y reemplazando las nuevas lneas con secuencias \n, pero hara muy difcil de leer el chero de estilos. La facilidad para leer es importante cuando est decidiendo si un texto pertenece a un chero de estilo o a un chero de plantilla a includo en el estilo. Si el chero de estilo luce muy grande o complicado, si inserta una pieza de texto literal, mejor col quelo en una plantilla. o

139

Captulo 12

Administraci n de cambios con Colas de o Mercurial


12.1. El problema de la administraci n de parches o

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 todava tiene el e o o fallo, debe extraer su arreglo del arbol de fuentes anteriores y aplicarlo a la nueva versi n. Una tarea tediosa en la cual o es f cil equivocarse. a Este es un caso simple del problema del manejo de parches. Usted tiene un arbol de fuentes del mantenedor principal que no puede cambiar: necesita hacer algunos cambios locales sobre el arbol principal; y deseara poder mantener tales cambios separados, de forma tal que pueda aplicarlos a versiones m s nuevas del arbol principal. a El problema de administraci n de parches surge en muchas situaciones. Probablemente la m s visible es cuando un o a usuario de un proyecto de software de fuentes abiertas contribuye con un arreglo de un fallo o una nueva caracterstica 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 a diff y patch (ver la secci n 12.4 para ver c mo emplear tales herramientas). Cuando la cantidad de cambios comienza o o 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 modicar varios cheros, pero est haciendo una sola cosa), a y puede tener cierta cantidad de tales parches para diferentes fallos y cambios locales. En esta situaci n, si enva un o parche que arregla un fallo a los mantenedores principales de un paquete y ellos incluyen su arreglo en una publicaci n o posterior, puede deshacerse de tal parche cuando se actualice a la nueva versi n. o Mantener un solo parche frente a un arbol principal es algo tedioso y es f cil equivocarse, pero no es difcil. a Aunque, la complejidad del problema crece r pidamente a medida que la cantidad de parches que tiene que mantener a crece. Con m s que una peque a cantidad de cambios, entender cu les ha aplicado se convierte de algo desordenado a a n a algo avasallante. Afortunadamente Mercurial provee una extensi n poderos: Colas de Mercurial (o simplemente MQ), que simo plica en gran medida el problema de administraci n de parches. o

12.2.

La prehistoria de las Colas de Mercurial

A nales de los 90s, muchos desarrolladores del n cleo de Linux comenzaron a mantener series de parches u que modicaron el comportamiento del n cleo de Linux. Algunos se enfocaban en estabilidad, otros en aumentar las u caractersticas, y otros un poco m s especulativos. a 140

Los tama os de las series de parches crecieron r pidamente. En el 2002, Andrew Morton public algunos guiones n a o de lnea de ordenes que estuvo usando para automatizar la tarea de administrar su cola de parches. Andrew us ex o it samente tales guiones para administrar centenas (a veces millares) de parches en el n cleo de Linux. o u

12.2.1.

Trabajar parches con quilt

A comienzos del 2003, Andreas Gruenbacher y Martin Quinson tomaron la aproximaci n de los guiones de Ano drew y publicaron una herramienta llamada patchwork quilt [AG], o simplemente quilt (ver [Gru05] el paper que lo describe). Dado que quilt automatizaba sustancialmente la administraci n de parches, fue adoptado en gran medida o por desarrolladores de programas abiertos. Quilt maneja una pila de parches sobre un arbol de directorios. Para comenzar, usted le indica a quilt que administre un arbol de directorios, le indica qu cheros manejar; Este almacena los nombres y los contenidos de estos cheros. e Para arreglar un fallo, usted crea un nuevo parche (con una sola orden), edita los cheros que est arreglando y a refresca el parche. El paso de refresco hace que quilt revise el arbol 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 modicar a el arbol desde el arbol con un parch aplicado a un rbol con dos parches aplicados. a Usted puede elegir qu cambios desea aplicar al arbol. Si pop1 un parche, los cambios hechos por tal parchve e desaparecean del arbol de directorios. Quilt recuerda qu parches ha sacado, para que pueda introducirlos2 posterir e ormente, as el arbol de directorios se restaurar con las modicaciones que vienen del parche. Lo m s importante es a a que puede ejecutar la orden refresh en cualquier momento, y el ultimo parche ser actualizado. Esto signica que a puede, en cualquier momento, cambiar qu parches ser n aplicados y qu modicaciones hacen ellos. e a e 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 chero comprimido y empaquetado o una copia de trabajo de Subversion.

12.2.2.

Pasar de trabajo con parches con Quilt hacia Colas de Mercurial

A mediados de 2005, Chris Mason tom las caractersticas de quilt y escribi una extensi n que llam Colas de o o o o Mercurial3 , que proporcion un comportamiento a Mercurial al estilo quilt. o La diferencia clave entre quilt y MQ es que quilt no sabe nada acerca del sistema de control de revisiones, mientras que MQ est integrado con Mercurial. Cada parche que usted introduce se representa como un conjunto de cambios a en Mercurial. Si sustrae un parche, el conjunto de cambios desaparece.4 Dado que quilt no se preocupa por las herramientas de control de revisiones, contin a siendo una porci n de u o software tremendamente util para aquellas situaciones en las cuales no puede usar Mercurial y MQ.

12.3.

La gran ventaja de MQ

No puedo sobreestimar el valor que MQ ofrece en la unicaci n de parches y el control de revisiones. o La principal raz n por la cual los parches han persistido en el mundo del software libre y de fuentes abiertasa o pesar de la creciente disponibilidad de herramientas poderosas de control de revisiones es la 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 e ((((wild-eyed)))), debe ser cuidadoso en c mo lo hace, o puede dejar trazas innecesariaso peor a n, desconcertantes o u 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 o a aislar su trabajo. Sus parches viven encima del historial de revisiones normales, y puede hacer que ellos desaparezcan
del T. saca del T. push 3 N. del T. Mercurial Queues 4 N. del T. introduce originalmente es push y pop es sustraer en este contexto, usaremos el original en ingl s cuando encontremos que facilita la e comprensi n o
2 N. 1 N.

141

o reaparezcan cuando lo desee. Si no le gusta un parche, puede desecharlo. Si un parche no satisface todo lo que usted desea, puede arreglarlotantas veces como lo requiera, hasta que lo haya renado lo suciente hacia sus expectativas. Por ejemplo, la integraci n de parches con el control de revisiones hace que el entender los parches y revisar sus o efectosy sus interacciones con el c digo en el cu l est n enlazados sea mucho m s sencillo. Dado que todo parche o a a a que se aplique tiene un conjunto de cambios asociado, puede usar hg log filename para ver qu conjuntos de e cambios y parches afectaron un chero. Puede usar la orden bisect para hacer una b squeda binaria sobre todos los u conjuntos de cambios y parches aplicados para ver d nde se introdujo un fallo o d nde fue arreglado. Puede usar la o o orden hg annotate para ver qu conjuntos de cambios o parches modicaron una lnea particular de un chero e fuente. Y mucho m s. a

12.4.

Entender los parches

Dado que MQ no esconde su naturaleza parche-c ntrica, es muy util para entender de qu se tratan los parches, y e e un poco acerca de las herramientas que trabajan con ellos. La orden de Unix tradicional diff compara dos cheros, e imprime una lista de diferencias de sus lneas. La orden patch entiende esas diferencias como modicaciones para construir un chero. Vea en la gura 12.1 un ejemplo sencillo de tales ordenes en acci n. o
1 2 3 4 5 6 7 8 9 10 11 12 13

$ echo this is my original thought > oldfile $ echo i have changed my mind > newfile $ diff -u oldfile newfile > tiny.patch $ cat tiny.patch --- oldfile 2009-02-10 18:23:25.000000000 +0000 +++ newfile 2009-02-10 18:23:25.000000000 +0000 @@ -1 +1 @@ -this is my original thought +i have changed my mind $ patch < tiny.patch patching file oldfile $ cat oldfile i have changed my mind

Figura 12.1: Uso sencillo de las ordenes diff y patch El tipo de chero que diff genera (y que 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.) e a Un parche puede comenzar con un texto arbitrario; la orden 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, o la orden patch busca la primera lnea que comience con la cadena diff -. MQ trabaja con diffs unicados (patch acepta varios formatos de diff adicionales, pero MQ no). Un diff unicado contiene dos clases de encabezados. El encabezado de chero describe el chero que se est modicando; contiene el a nombre del chero a modicar. Cuando patch ve un nuevo encabezado de chero, busca un chero con ese nombre para modicarlo. Despu s del encabezaado vienen varios trozos. Cada trozo comienza con un encabezado; que identica el rango de e lneas del chero que el trozo debe modicar. Despu s del encabezado, un trozo comienza y termina con unas pocas e lneas (usualmente tres) de texto del chero que no han sido modicadas; las cuales llamamos el contexto del trozo. Si solamente hay una peque a cantidad de contexto entre trozos sucesivos, diff no imprime un nuevo encabezado para n el trozo, continua integrando los trozos, con unas lneas de contexto entre las modicaciones. Cada lnea de contexto comienza con un caracter de espacio. En el trozo, si una lnea comienza con - signica elimine esta lnea, si la lnea comienza con un + signica inserte esta lnea. Por ejemplo, una lnea que se 142

modica se representa con una lnea eliminada y una lnea insertada. Retomaremos aspectos m s sutiles acerca de parches posteriormente (en la secci n 12.6), pero en el momento a o usted ya debera tener suciente informaci n para usar MQ. o

12.5.

Comenzar a usar Colas de Mercurial

Dado que MQ est implementado como una extensi n, debe habilitarla explcitamente antes de comenzar a usarla. a o (No necesita descargar nada; MQ viene con la distribuci n est ndar de Mercurial.) Para habilitar MQ, edite su chero o a /.hgrc, y a ada las lneas de la gura 12.5. n
1 2

[extensions] hgext.mq =

Figura 12.2: Lneas a a adir en /.hgrc para habilitar la extensi n MQ n o Cuando la extensi n est habilitada, aparecer n varios comandos. Para vericar que la extensi n est trabajando, o e a o a puede usar hg help para ver si la orden hg qinit est disponible; vea un ejemplo en la gura 12.3. a
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

$ hg help qinit hg qinit [-c] init a new queue repository The queue repository is unversioned by default. If -c is specified, qinit will create a separate nested repository for patches (qinit -c may also be run later to convert an unversioned patch repository into a versioned one). You can use qcommit to commit changes to this queue repository. options: -c --create-repo create queue repository

use "hg -v help qinit" to show global options

Figura 12.3: C mo vericar que MQ est habilitado o a Puede usar MQ en cualquier repositorio de Mercurial, y sus comandos solamente operar n con tal repositorio. a Para comenzar, basta con preparar el repositorio con la orden hg qinit (ver la gura 12.4). Esta orden crea un directorio vaco llamado .hg/patches, donde MQ mantendr sus metadatos. Como otras ordenes de Mercurial, la a orden hg qinit no imprime nada cuando es exitosa.

12.5.1.

Crear un nuevo parche

Para comenzar a trabajar en un nuevo parche use la orden hg qnew. Esta orden recibe un argumento, el nombre del parche a crear. MQ lo usar como el nombre del chero en el directorio .hg/patches, como puede apreciarlo en a la gura 12.5.

143

1 2 3 4 5 6 7

$ $ $ $ $ $ $

hg init mq-sandbox cd mq-sandbox echo line 1 > file1 echo another line 1 > file2 hg add file1 file2 hg commit -mfirst change hg qinit

Figura 12.4: Preparar un repositorio para usar MQ


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

$ hg tip changeset: tag: user: date: summary:

0:90039acadb36 tip Bryan OSullivan <bos@serpentine.com> Tue Feb 10 18:23:27 2009 +0000 first change

$ hg qnew first.patch $ hg tip changeset: 1:495236f727e1 tag: qtip tag: first.patch tag: tip tag: qbase user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:27 2009 +0000 summary: [mq]: first.patch $ ls .hg/patches first.patch series

status

Figura 12.5: Crear un nuevo parche Tambi n hay otros dos nuevos cheros en el directorio .hg/patches: series y status. El chero series lista e todos los parches de los cuales MQ tiene noticia para este repositorio, con un parche por lnea. Mercurial usa el chero status para mantener registros interns; da seguimiento a todos los parches que MQ ha aplicado en el repositorio. Nota: En ciertas ocasiones usted querr editar el chero series a mano; por a ejemplo, cambiar el orden en que se aplican ciertos parches. A pesar de esto, es una mala idea editar manualmente el chero status, dado que es f cil desorientar a a MQ acerca de lo que est pasando. a Una vez que haya creado un nuevo parche, puede editar los cheros en el directorio de trabajo, como lo hara usualmente. Toda las ordenes que de a Mercurial, tales como hg diff y hg annotate, trabajar n de la misma a forma como lo han hecho antes.

12.5.2.

Refrescar un parche

Cuando usted llega a un punto en el cual desea guardar su trabajo, use la orden hg qrefresh (gura 12.5) para actualizar el parche en el cual est trabajando. Esta orden almacena los cambios que haya hecho al directorio actual de a 144

trabajo en su parche, y almacena el conjunto de cambios correspondiente que contiene los cambios.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

$ echo line 2 >> file1 $ hg diff diff -r 495236f727e1 file1 --- a/file1 Tue Feb 10 18:23:27 2009 +0000 +++ b/file1 Tue Feb 10 18:23:27 2009 +0000 @@ -1,1 +1,2 @@ line 1 +line 2 $ hg qrefresh $ hg diff $ hg tip --style=compact --patch 1[qtip,first.patch,tip,qbase] 131b8ed49ec4 2009-02-10 18:23 +0000 [mq]: first.patch diff -r 90039acadb36 -r 131b8ed49ec4 file1 --- a/file1 Tue Feb 10 18:23:27 2009 +0000 +++ b/file1 Tue Feb 10 18:23:27 2009 +0000 @@ -1,1 +1,2 @@ line 1 +line 2

bos

Figura 12.6: Refrescar un parche Puede ejecutar la orden hg 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 hg revert sobre sus modicaciones para volver al refresco anterior.

12.5.3.

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 hg qnew para crear un nuevo parche. Mercurial aplicar este parche sobre su parche anterior. Para un ejemplo, ver la gura 12.8. a Note que el parche contiene los cambios en nuestro parche anterior como parte de su contexto (lo ver m s claramente a a en la salida de hg annotate). Hasta ahora, con excepci n de hg qnew y hg qrefresh, hemos sido cuidadosos para aplicar unicamente o ordenes usuaales de Mercurial. De todas maneras, MQ ofrece muchos comandos que son m s sencillos de usar cuando a est pensando acerca de parches, como se puede ver en la gura 12.9: e La orden hg qseries lista cada parche del cual MQ tiene noticia en este repositorio, desde el m s antiguo a hasta el m s nuevo (El ultimo creado). a La orden hg qapplied lista cada parche que MQ haya aplicado en este repositorio, de nuevo, desde el m s a antiguo hasta el m s nuevo (El aplicado m s recientemente). a a

12.5.4.

Manipular la pila de parches

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

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

$ echo line 3 >> file1 $ hg status M file1 $ hg qrefresh $ hg tip --style=compact --patch 1[qtip,first.patch,tip,qbase] 4fef714d728c [mq]: first.patch

2009-02-10 18:23 +0000

bos

diff -r 90039acadb36 -r 4fef714d728c file1 --- a/file1 Tue Feb 10 18:23:27 2009 +0000 +++ b/file1 Tue Feb 10 18:23:27 2009 +0000 @@ -1,1 +1,3 @@ line 1 +line 2 +line 3

Figura 12.7: Refrescar un parche muchas veces para acumular cambios Un parche 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 o orden hg qpop. MQ sabe acerca de, o maneja un parche sustrado, pero el parche ya no tendr un conjunto de a cambios correspondientes en el repositorio, y el directorio de trabajo no contendr los cambios hechos por el parche. a La gura 12.10 ilustra la diferencia entre parches aplicados y seguidos. Puede reaplicar un parche no aplicado o sustrado con la orden hg 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. a Vea ejemplos de hg qpop y hg qpush en acci n en la gura 12.11. Vea que hemos sustrado uno o dos parches, o la salida dehg qseries contin a igual, mientras que hg qapplied ha cambiado. u

12.5.5.

Introducir y sustraer muchos parches

Mientras que hg qpush y hg qpop operan sobre un unico parche cada vez, puede introducir y sustraer varios parches de una vez. La opci n -a de hg qpush introduce todos los cambios que no hayan sido aplicados, mientras o que la opci n -a de hg qpop sustrae todos los cambios aplicados. (Vea la secci n 12.7 m s adelante en la cual se o o a explican otras formas de de introducir y sustraer varios cambios.)

12.5.6.

Medidas de seguridad y c mo saltarlas o

Muchas ordenes MQ revisan el directorio de trabajo antes de hacer cualquier cosa, y fallan si encuentran alguna modicaci n. Lo hacen para garantizar que usted no pierda cambio alguno de los que haya hecho, pero que no hayan o sido incorporados en alg n parche. La gura 12.13 ilusta esto; la orden hg qnew no crear un nuevo parche si hay u a cambios notorios, causados en este caso por aplicado la orden hg add a file3. Las ordenes que revisan el directorio actual cuentan con una opci n Se lo que estoy haciendo, que siempre o est nombrada como -f. El signicado exacto de -f depende de la orden. Por ejemplo, hg qnew -f incorporar n a a cualquier cambio notorio en el nuevo parche que crea pero hg qpop -f revertir las modicaciones a cualquier a chero que haya sido afectado por el parche que est siendo sustrado. Aseg rese de leer la documentaci n de la a u o opci n -f de cada comando antes de usarla! o

146

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

$ hg qnew second.patch $ hg log --style=compact --limit=2 2[qtip,second.patch,tip] 17da5d88f25b [mq]: second.patch 1[first.patch,qbase] [mq]: first.patch 4fef714d728c

2009-02-10 18:23 +0000

bos

2009-02-10 18:23 +0000

bos

$ echo line 4 >> file1 $ hg qrefresh $ hg tip --style=compact --patch 2[qtip,second.patch,tip] 7cf293b98474 [mq]: second.patch

2009-02-10 18:23 +0000

bos

diff -r 4fef714d728c -r 7cf293b98474 file1 --- a/file1 Tue Feb 10 18:23:27 2009 +0000 +++ b/file1 Tue Feb 10 18:23:28 2009 +0000 @@ -1,3 +1,4 @@ line 1 line 2 line 3 +line 4 $ hg annotate file1 0: line 1 1: line 2 1: line 3 2: line 4

Figura 12.8: Aplicar un parche despu s del primero e

12.5.7.

Trabajar con varios parches a la vez

La orden hg qrefresh siempre refresca el ultimo parche aplicado. Esto signica que usted puede suspender su trabajo en un parche (refresc ndolo), sustraerlo o introducirlo para lograr que otro parche est de ultimo y trabajar en a e ese parche por un rato. A continuaci n un ejemplo que ilustra c mo puede usar esta habilidad. Digamos que est desarrollando una nueva o o a caracterstica en dos parches. El primero es un cambio en la parte fundamental de su programa, y el segundosobre el primerocambia la interfaz de usuario para usar el c digo que ha a adido a la parte fundamental. Si ve que hay o n un fallo en la parte fundamental mientras est trabajando en el parche de UI5 , es f cil arreglar la parte fundamental. a a Simplemente use hg qrefresh sobre el parche de la UI para guardar los cambios de su trabajo en progreso, y use hg qpop para sacar sustraer el parche de la parte fundamental. Arregla el fallo sobre la parte fundamental, aplique hg qrefresh sobre el parche fundamental, y aplique hg qpush sobre el parche de UI para continuar donde haba quedado.
5 N.

del T. Interfaz de Usuario, User Interface en ingl s e

147

1 2 3 4 5 6

$ hg qseries first.patch second.patch $ hg qapplied first.patch second.patch

Figura 12.9: Entender la pila de parches con hg qseries y hg qapplied


presente en la serie, pero no aplicado parche aplicado ms recientemente

forbidillegalparams.patch fixmemoryleak.patc

preventcompilerreorder.patch 201ad3209902

parches aplicados, Conjuntos de cambios presentes

namespacecleanup.patch powerpcportfixes.patc reportdevinfocorrectly.patch

126b84e593ae a655daf15409 e50d59aaea3a

Figura 12.10: Parches aplicados y no aplicados en la pila de parches de MQ

12.6.

M s acerca de parches a

MQ usa la orden GNU patch para aplicar los parches, por lo tanto es util conocer ciertos detalles de c mo trabaja o patch, y tambi n acerca de los parches. e

12.6.1.

La cantidad de franjas

Si ve el encabezado de un parche, notar que la ruta al chero tiene un componente adicional al principio, que no a est presente en la ruta. Esta es una traza de c mo generaba anteriormente los parches la gente (algunos a n lo hacen, a o u pero es raro con las herramientas de control de revisiones del actuales). Alicia desempaquetara un comprimido, editara sus cheros, y querra crear un parche. Por lo tanto ella renom brara su directorio de trabajo, desempacara el comprimido de nuevo (para lo cual necesit el renombramiento), y o usara las opciones -r y -N de diff para generar recursivamente un parche entre el directorio original y el modicado. El resultado sera que el nombre del directorio original estara al principio de toda ruta en cada encabezado de chero, y el nombre del directorio modicado estara al frente de la porci n derecha de la ruta del chero. o Como alguien que reciba un parche de Alicia en la red podra obtener dos directorios, uno original y el otro modi cado con exactamente los mismos nombres, la orden patch tiene la opci n -p que indica la cantidad de componentes o de la ruta a eliminar cuando se vaya a aplicar el parche. Este n mero se llama la cantidad de eliminaciones. u La opci n con -p1 signica elimine uno. Si patch ve un nombre de chero foo/bar/baz en el encabezado o del chero, eliminar foo y tratar de parchar un chero llamado bar/baz. (Hablando estrictamente, la cantidad de a a eliminaciones se reere a la cantidad de separadores de ruta (y los componentes que vayan con ellos) a eliminar. Si el contador es uno volver foo/bar en bar, pero /foo/bar (note la barra extra) en foo/bar.) a La cantidad a eliminarest ndar para parches es uno; casi todos los parches contienen un componente inicial de a la ruta que necesita ser eliminado. La orden hg diff de Mercurial genera nombres de ruta de esta forma, y la orden hg import y MQ esperan parches que tengan a uno como cuenta de eliminaciones. 148

1 2 3 4 5 6 7 8 9 10 11 12 13 14

$ hg qapplied first.patch second.patch $ hg qpop Now at: first.patch $ hg qseries first.patch second.patch $ hg qapplied first.patch $ cat file1 line 1 line 2 line 3

Figura 12.11: Modicar la pila de parches aplicados


1 2 3 4 5 6 7 8

$ hg qpush -a applying second.patch Now at: second.patch $ cat file1 line 1 line 2 line 3 line 4

Figura 12.12: Pushing all unapplied patches 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 hg qimport en primera medida, porque hg qimport o a no tiene todava una opci n -p option (ver Fallo de Mercurial No. 311). Lo mejor que puede hacer es aplicar hg o qnew por su cuenta, y despu s usar patch -pN para aplicar tal parche, seguido de hg addremove para tener en e cuenta cualquier chero adicionado o eliminado por el parche, seguido de hg qrefresh. Esta complejidad puede ser innecesaria; consulte Fallo de Mercurial No. 311 para m s informaci n. a o

12.6.2.

Estrategias para aplicar parches

Cuando patch aplica un trozo, intenta varias estrategias sucesivas que decrecen en precisi n para intentar aplicarlo. o Esta t cnica de pruebas y error aveces permite que un parche que fue generado contra una versi n anterior de un e o chero, sea aplicada sobre una versi n m s nueva del mismo. o a Primero patch intenta una correspondencia perfecta donde los n meros de lnea, el contexto y el texto a modicar u deben coincidir perfectamente. Si no lo logra, intenta encontrar una correspondencia exacta del contexto, sin tener en cuenta el n mero de lnea. Si es exitoso, imprime una lnea indicando que el trozo fue aplicado, pero a un corrimiento u del n mero de lnea original. u Si falla la correspondencia por contexto, patch elimina la primera y la ultima lnea del contexto, e intenta una correspondencia reducida del contexto. Si el trozo con contexto reducido es exitoso, imprime un mensaje indicando que aplic el trozo con un factor difuso (el n mero despu s del factor difuso indica cu ntas lneas de contexto patch o u e a tuvo que eliminar antes de aplicar el parche). 149

1 2 3 4

$ echo file 3, line 1 >> file3 $ hg qnew add-file3.patch $ hg qnew -f add-file3.patch abort: patch "add-file3.patch" already exists

Figura 12.13: Crear un parche a la fuerza Cuando ninguna de estas t cnicas funciona, patch imprime un mensaje indicando que el trozo en cuesti n se e o desech . Almacena los trozos desechados (tambi n llamados descartados) en un chero con el mismo nombre, y la o e extensi n .rej a adida. Tambi n almacena una copia igual al chero original con la extensi n .orig; la copia del o n e o chero sin extensi n contendr cualquier cambio hecho por los trozos que s se aplicaron sin problema. Si usted tiene o a un parche que modica foo con seis trozos, y uno de ellos falla al aplicarse, tendr : un chero original foo.orig, un a chero foo.rej que contiene el trozo, y foo, que contiene los cambios que se aplicaron por los cinco trozos exitosos.

12.6.3.

Algunos detalles de la representaci n de parches o

Hay ciertas cosas utiles por saber acerca de c mo trabaja patch con los cheros: o Debera ser obvio que patch no puede manipular cheros binarios. No se preocupa por el bit ejecutable; crea cheros nuevos en modo lectura, pero no ejecutable. patch intenta eliminar un chero como una diferencia entre el chero a eliminar y un chero vaco. Y por lo tanto su idea de Borr este chero debera pensarse como toda lnea de este chero fue eliminada en un e parche. Trata la adici n de un chero como un diff entre un chero vaco y el chero a ser adicionado. Por lo tanto en o un parche su idea de A ad este chero se vera como toda lnea de este chero fue a adida. n n Trata el renombramiento de un chero como la eliminaci n del nombre anterior y la adici n del nuevo nombre. o o Esto signica que los cheros renombrados dejan un rastro grande en los parches. (Tenga en cuenta que Mercurial no trata de inferir cuando los cheros han sido renombrados o copiados en un parche en este momento.) patch no puede representar cheros vacos, por lo tanto no puede usar un parche para representar la noci n o A ad este chero vaco al arbol. n

12.6.4.

Cuidado con los difusos

Cuando aplique un trozo con un corrimiento, o con un factor difuso, aveces ser taotalmente exitoso, tales t cnicas a e inexactas dejan claramente la posibilidad de corromper el chero parchado. Los casos m s tpicos involucran aplicar a un parche dos veces o en un sitio incorrecto del chero. Si patch o hg qpush llegan a mencionar un corrimiento o un factor difuso, debera asegurarse que los cheros modicados est n correctos despu s del suceso. e e Casi siempre es buena idea refrescar un parche que fue aplicado con un corrimiento o un factor difuso; refrescar el parche genera nueva informaci n de contexto que permitir aplicarlo limpiamente. Digo casi siempre, no siempre, o a puesto que en ciertas ocasiones refrescar un parche lo har fallar frente a una revisi n diferente del chero. En algunos a o casos, como por ejemplo, cuando usted est manteniendo un parche que debe estar encima de m ltiples revisiones de a u un arbol de fuentes, es aceptable tener un parche aplicado algo difuso, siempre que haya vericado los resultados del proceso de parchar.

150

12.6.5.

Manejo de descartes

Si hg qpush falla al aplicar un parche, mostrar un texto de error y saldr . Si ha dejado cheros .rej, es mejor a a arreglar los trozos descartados antes de introducir parches adicionales o hacer cualquier otra cosa. Si su parche sola aplicarse limpiamente, y ya no lo hace porque ha cambiado c digo subyacente en el cual se basa o su parche, las Colas de Mercurial pueden ayudar; consulte la secci n 12.8. o Desafortunadamente, no hay grandes t cnicas para tratar los trozos descartados. Casi siempre deber consultar el e a chero .rej y editar el chero objetivo, aplicando los trozos descartados a mano. Si es aventurero, Neil Brown, un hacker del n cleo Linux, escribi una herramienta llamada wiggle [Bro], que es u o m s vigorosa que patch en su intento de hacer que se aplique un parche. a Otro hacker del nucleo Linux, Chris Mason (el autor de las Colas de Mercurial), escribi una herramienta similar o llamada mpatch [Mas], que sigue una aproximaci n sencilla para automatizar la aplicaci n de trozos descartados por o o patch. La orden mpatch puede ayudar con cuatro razones comunes por las cuales un parche ha sido descartado: El contexto en la mitad de un trozo ha cambiado. Un trozo ha perdido cierto contexto al principio o al nal. Un trozo largo podra aplicarse mejorpor completo o una partesi estaba cortado en trozos m s peque os. a n Un trozo remueve lneas con contenido ligeramente diferente que aquellas que est n presentes en el chero. a Si usted usa wiggle o mpatch, debera ser doblemente cuidadoso al revisar sus resultados cuando haya terminado. De hecho, mpatch refuerza este m todo de revisar por partida doble su salida, dej ndolo a usted en un programa de e a fusi n cuando la herramienta haya terminado su trabajo, de tal forma que usted pueda vericar lo que ha hecho y o pueda terminar de aplicar cualquier fusi n faltante. o

12.7.

maximizar el rendimiento de MQ

MQ es muy eciente al tratar con una gran cantidad de parches. Corr unos experimentos de desempe o a mediados n del 2006 para una charla que d en la conferencia EuroPython 2006 [OS06]. Emple la serie de parches para el n cleo e u Linux 2.6.17-mm1, que contaba con 1.738 parches. Los apliqu sobre un repositorio del n cleo de Linux con todas e u las 27.472 revisiones entre 2.6.12-rc2 y 2.6.17. En mi port til antiguo y lento, logr aplicar hg qpush -a a los 1.738 parches en 3.5 minutos, y hg qpop -a a e en 30 segundos. (En un port til m s nuevo, el tiempo para introducir todos los parches, se logr en menos de dos a a o minutos.) Apliqu hg qrefresh sobre uno de los parches m s grandes (que hizo 22.779 lneas de cambios en 287 e a cheros) en 6,6 segundos. Claramente, MQ funciona adecuadamente en arboles grandes, y adem s hay unos trucos que pueden emplearse a para obtener el m ximo desempe o. a n En primer lugar, trate de hacer en lote las operaciones. Cada vez que ejecute hg qpush o hg qpop, tales ordenes revisan el directorio de trabajo para asegurarse de que usted no ha hecho cambios y ha olvidado ejecutar hg qrefresh. En un arbol peque o, el tiempo de esta revisi n puede ser mnimo, Pero en un arbol mediano (con decenas n o de miles de cheros), puede tomar un segundo o m s. a Las ordenes hg qpush y hg qpop le permiten introducir o sustraer varios parches en una operaci n. Puede o identicar el parche destino que desee. Cuando aplique hg qpush con un destino, introducir tantos parches a como sea necesario hasta que el especicado est en el tope de la pila. Cuando emplee hg qpop con un destino, MQ e sustraer parches hasta que el parche destino est en el tope. a e Puede identicar un parche destino con el nombre del parche o con el n mero. Si se reere al n mero, los parches u u se contar n desde cero; esto signica que el primer parche es cero, el segundo es uno y as sucesivamente. a

151

12.8.

Actualiar los parches cuando el c digo cambia o

Es com n contar con una pila de parches sobre un repositorio que usted no modica directamente. Si est trabau a jando en cambios de c digo de otros, o en una caracterstica que tarda bastante en desarrollarse comparada con la tasa o de cambio del c digo sobre la cual se est trabajando, necesitar sincronizarse con el c digo, y ajustar cualquier trozo o a a o en sus parches que ya no est n al da. A esto se le llama hacer rebase a su serie de parches. e La va m s sencilla de hacerlo es con hg qpop -a sobre sus parches, despu s hacer hg pull de los cambios a e en el repositorio, y nalmente hacer hg qpush -a con sus parches de nuevo. MQ dejar de de introducir parches a siempre que llegue a un parche que no se pueda aplicar debido a un conicto, permiti ndole a usted arreglarlo, aplicar e hg qrefresh al parche afectado y continuar introduciendo hasta que haya arreglado la pila completa. Esta aproximaci n es sencilla y funciona bien si no espera cambios en el c digo original que afecte en gran medida o o los parches que usted est aplicando. Si su pila de parches toca c digo que es modicado frecuentemente o de forma e o invasiva sobre el c digo subyacente, arreglar trozos manualmente se vuelve desgastante. o Es posible automatizar de forma parcial el proceso de rebase. Si sus parches se aplican limpiamente sobre algunas revisiones del repositorio subyacente, MQ puede usar esta informaci n para ayudarle a a resolver conictos entre sus o parches y una revisi n distinta. o El proceso resulta un poco complejo: 1. Para comenzar, haga hg qpush -a sobre todos los parches que usted sepa se aplican limpiamente. 2. Guarde una copia de seguridad de su directorio de parches con hg qsave -e -c. Esto imprime el nombre del directorio en el cual se han guardado los parches. Guardar los parches en un directorio llamado a .hg/patches.N , donde N es un entero peque o. Tambi n consigna un conjunto de cambios de seguridad n e sobre sus parches aplicados; esto es para mantener el hist rico, y guarda los estados de los cheros series y o status. 3. Use hg pull para traer los nuevos cambios en el repositorio subyacente. (No ejecute hg pull -u; vea m s a adelante por qu .) e 4. Actualice a la nueva revisi n punta con hg update -C para sobreescribir los parches que haya introducido. o 5. Fusione todos los parches con hg qpush -m -a. La opci n -m de hg qpush le indica a MQ que haga una o fusi n que involucra tres fuentes si el parche falla al aplicarse. o Durante el hg qpush -m, cada parche en el chero series se aplica normalmente. Si un parche se aplica difusamente o se niea a aplicarse, MQ consulta la cola que usted guard con hg qsave, y aplica una fusi n de tres o o con el correspondiente conjunto de cambios. Esta fusi n usa la maquinaria de Mercurial, por lo tanto puede mostrar o una herramienta de fusi n GUI para ayudarle a resolver los problemas. o Cuando termine de resolver los efectos de un parche, MQ refrescar su parche basado en el resultado de la fusi n. a o Al nal de este proceso, su repositorio tendr una cabeza extra de la antigua cola de parches, y una copia de la a cola de parches anterio estar en .hg/patches.N . Puede eliminar la cabeza extra con hg qpop -a -n patches.N a o hg strip. Puede eliminar .hg/patches.N una vez que est seguro de que no lo necesita m s como copia de e a seguridad.

12.9.

Identicar parches

Las ordenes de MQ le permiten trabajar reri ndose al nombre del parche o al n mero. Es obvio hacerlo por el e u nombre; por ejemplo se pasa el nombre foo.patch a hg qpush, que introducir los parches hasta que foo.patch a se aplique. Para hacerlo m s corto, puede referirse a un parche con un nombre y un corrimiento de n mero; por ejemplo, a u foo.patch-2 signica dos parches antes de foo.patch, mientras que bar.patch+4 signica cuatro parches despu s de bar.patch. e

152

Referirse a un parche por su ndice no es muy diferente. El primer parche que se imprime en la salida de hg qseries es el parche cero (si, es el primero en los sistemas que comienzan su conteo en cero); el segundo parche es uno y as sucesivamente. MQ facilita el trabajo cuando est usando ordenes normales de Mercurial. Cada comando que acepte Identia cadores de conjuntos de cambios tambi n aceptar el nombre de un parche aplicado. MQ aumenta las etiquetas nore a malmente en el repositorio con un distintivo para cada parche aplicado. Adicionalmente, las etiquetas especiales qbase y qtip identican los parches primero y ultimo, respectivamente. Junto con las capacidades de Mercurial para etiquetar, estas adiciones hacen que trabajar con parches sea muy sencillo. Desea enviar una bomba de parches a una lista de correo con los ultimos cambios que ha hecho?
1

hg email qbase:qtip (No sabe qu es una bomba de parches? Consulte la secci n 14.4.) e o Desea ver todos los parches desde que se aplic foo.patch sobre los cheros de un subdirectorio en su arbol? o

hg log -r foo.patch:qtip subdir

Dado que MQ nombra los parches disponibles al resto de Mercurial con su maquinaria de etiquetas interna, usted no necesita teclear el nombre completo de un parche cuando desea identicarlo por su nombre. Otra consecuencia deseable al representar los nombres de parches como etiquetas es que cuando ejecute la orden hg log, desplegar el nombre del parche como una etiqueta, usualmente con la salida normal. Esto facilita distinguir a visualmente los parches aplicados de las revisiones normales. La gura 12.14 muestra algunos comandos usuales de Mercurial al trabajar con parches.

12.10.

Otra informaci n util o

Hay una cantidad de aspectos que hacen que el uso de MQ no representen secciones en s mismas, pero de los cuales es bueno estar enterado. Los presentamos en aqu: Usualmente cuando hace hg qpop a un parche y vuelve a hacerle hg qpush, el conjunto de cambios que representa el parche despu s de introducir/sustraer tendr una identidad distinta que aquella que representaba el e a conjunto de cambios anteriormente. Consulte la seccti n B.1.13 para obtener informaci n del por qu de esto. o o e No es una buena idea aplicar hg merge de cambios de otra rama con un conjunto de cambios de parches, por lo menos si desea mantener la informaci n de parches de ese conjunto de cambios y los conjuntos de cambios o que se encuentran por debajo en la pila de parches. Si intenta hacerlo, parecer que ha sido exitoso, pero MQ se a confundir . a

12.11.

Administrar parches en un repositorio

Dado que el directorio .hg/patches de MQ reside fuera del repositorio de trabajo de Mercurial, el repositorio subyacente de Mercurial no sabe nada acerca de la administraci n o presencia de parches. o Esto presenta la interesante posibilidad de administrar los contenidos del directorio de parches como un repositorio de Mercurial por su cuenta. Puede ser una forma util de trabajar. Por ejemplo, puede trabajar en un parche por un rato, hacerle hg qrefresh y despu s hacer hg commit al estado actual del parche. Esto le permite devolverse a esa e versi n del parche posteriormente. o Puede tambi n compartir diferentes versiones de la misma pila de parches entre varios repositorios subyacentes. e Uso esto cuando estoy desarrollando una caracterstica del n cleo Linux. Tengo una copia original de las fuentes del u 153

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

$ hg qapplied first.patch second.patch $ hg log -r qbase:qtip changeset: 1:b3508ccf62ad tag: first.patch tag: qbase user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:26 2009 +0000 summary: [mq]: first.patch changeset: tag: tag: tag: user: date: summary: 2:c836697fbf55 qtip second.patch tip Bryan OSullivan <bos@serpentine.com> Tue Feb 10 18:23:26 2009 +0000 [mq]: second.patch

$ hg export second.patch # HG changeset patch # User Bryan OSullivan <bos@serpentine.com> # Date 1234290206 0 # Node ID c836697fbf55654f972d867359527813dbbc5d44 # Parent b3508ccf62adb8916c6a7b64105642fa516f5a90 [mq]: second.patch diff -r b3508ccf62ad -r c836697fbf55 other.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/other.c Tue Feb 10 18:23:26 2009 +0000 @@ -0,0 +1,1 @@ +double u;

Figura 12.14: Uso de las caractersticas de etiquetamiento al trabajar con MQ n cleo para varias arquitecturas, y clon un rpositorio en cada una que contiene los parches en los cuales estoy trabau e jando. Cuando quiero probar un cambio en una arquitectura diferente, introduzco mis parches actuales al repositorio de parches asociado con el arbol del kernel, sustraigo e introduzco todos mis parches, armo y pruebo el n cleo. u Llevar los parches en un repositorio permite que varios desarrolladores puedan trabajar en la misma serie de parches sin sobreponerse, todo sobre la fuente base subyacente que pueden o no controlar.

12.11.1.

Soporte de MQ para repositorios de parches

MQ le ayuda a trabajar con el directorio .hg/patches como un repositorio; cuando usted prepara un repositorio para trabajar con parches usando hg qinit, puede pasarle la opci n -c para que se cree el directorio .hg/patches o como un repositorio de Mercurial.

154

Nota: Si olvida usar la opci n -c option, puede ir al directorio .hg/patches o en cualquier momento y ejecutar hg init. No olvide a adir una entrada en el n chero status del chero .hgignore, a pesar de que (hg qinit -c hace estodo de forma autom tica para usted); usted seguro no quiere administrar el chero a status. MQ nota convenientemente que el directorio .hg/patches es un repositorio, har hg add autom ticamente a a a cada parche que usted cree e importe. MQ provee una orden corta, hg qcommit, que ejecuta hg commit en el directorio .hg/patches. Lo que ahorra tecleo recurrente. Finalmente, para administrar convenientemente el directorio de parches, puede denir el alias mq en sistemas Unix. Por ejemplo, en sistemas Linux con el int rprete bash, puede incluir el siguiente recorte de c digo6 en su chero e o /.bashrc.
1

alias mq=hg -R $(hg root)/.hg/patches Puede aplicar las ordenes de la forma mq pull al repositorio principal.

12.11.2.

Detalles a tener en cuenta

El soporte de MQ para trabajar con un repositorio de parches es limitado en ciertos aspectos: MQ no puede detectar autom ticamente los cambios que haga al directorio de parches. Si aplica hg pull, edita a manualmente, o hace hg update a los parches o el chero series, tendr que aplicar hg qpop -a y despu s hg a e qpush -a en el repositorio subyacente para que los cambios se reejen all. Si olvida hacerlo, puede confundir a MQ en cuanto a qu parches se han aplicado. e

12.12.

Otras herramientas para trabajar con parches

Cuando haya trabajado por cierto tiempo con parches, desear herramientas que le ayuden a entender y manipular a los parches con los que est tratando. e La orden diffstat [Dic] genera un histograma de modicaciones hechas a cada chero en un parche. Provee una interesante forma de dar un vistazo al parchequ cheros afecta, y cu ntos cambios introduce a cada chero y e a en total. (Me ha parecido interesante usar la opci n -p de diffstat, puesto que de otra forma intentar hacer cosas o a inteligentes con prejos de cheros que terminan confundi ndome.) e El paquete patchutils [Wau] es invaluable. Provee un conjunto de peque as utilidades que siguen la losofa n Unix; cada una hace una cosa muy bien hecha a un parche. La orden patchutils que m s uso es filterdiff, a que extrae subconjuntos de un chero de parche. Por ejemplo, dado un parche que modica centenas de cheros en docenas de directorios, una unica invocaci n de filterdiff puede generear un parche m s peque o que solamente o a n toca aquellos cheros con un patr n. Puede ver otro ejemplo en la secci n 13.9.2. o o

12.13.

Buenas pr cticas de trabajo con parches a

En caso de que est trabajando en una serie de parches para enviar a un proyecto de software libre o de fuentes e abiertas, o en una serie que desea tratar como un conjunto de cambios regular, cuando haya terminado, puede usar t cnicas sencillas para mantener su trabajo bien organizado. e De nombres descriptivos a sus parches. Un buen nombre para un parche podra ser rework-device-alloc.patch, porque da de forma inmediata una pista del prop sito del parche. Los nombres largos no deben ser un problema; no o los estar tecleando repetidamente, pero estar ejecutando regularmente ordenes como hg qapplied y hg qtop. a a Los nombres adecuados son especialmente importantes cuando tiene bastantes parches con los cuales trabajar, o si est trabajando en diferentes tareas y sus parches toman solamente una porci n de su atenci n. a o o
6 N.

del T. snippet

155

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

$ diffstat -p1 remove-redundant-null-checks.patch drivers/char/agp/sgi-agp.c | 5 ++--drivers/char/hvcs.c | 11 +++++-----drivers/message/fusion/mptfc.c | 6 ++---drivers/message/fusion/mptsas.c | 3 +-drivers/net/fs_enet/fs_enet-mii.c | 3 +-drivers/net/wireless/ipw2200.c | 22 ++++++---------------drivers/scsi/libata-scsi.c | 4 +--drivers/video/au1100fb.c | 3 +-8 files changed, 19 insertions(+), 38 deletions(-) $ filterdiff -i */video/* remove-redundant-null-checks.patch --- a/drivers/video/au1100fb.cremove-redundant-null-checks-before-free-in-drivers +++ a/drivers/video/au1100fb.c @@ -743,8 +743,7 @@ void __exit au1100fb_cleanup(void) { driver_unregister(&au1100fb_driver); + } module_init(au1100fb_init); if (drv_info.opt_mode) kfree(drv_info.opt_mode); kfree(drv_info.opt_mode);

Figura 12.15: Las ordenes diffstat, filterdiff, y lsdiff Tenga en cuenta en qu parche est trabajando. Use la orden hg qtop para dar un vistazo al texto de sus parches e a frecuentementepor ejemplo, use hg tip -p)para asegurarse en d nde est ubicado. En distintas oportunidades o a me sucedi que apliqu hg qrefresh a un parche distinto al que deseaba hacerlo, y usualmente es complejo migrar o e los cambios al parche correcto despu s de haberlo hecho mal. e Por este motivo, vale la pena invertir ese poco tiempo para aprender c mo usar otras herramientas que describ en o la secci n 12.12, particularmente diffstat y filterdiff. La primera le dar una idea de qu cambios est haciendo o a e a su parche, mientras que la segunda permite seleccionar trozos de un parche para colocarlos en otro.

12.14.
12.14.1.

Recetas de MQ
Administrar parches triviales

Puesto que colocar cheros en un repositorio de Mercurial es tan sencillo, tiene bastante sentido administrar parches de esta forma incluso si desea hacer algunos cambios al paquete de cheros que descarg . o Para comenzar a descargar y desempaqueter un paquete de cheros, y volverlo en un repositorio de Mercurial:
1 2 3 4 5 6 7

$ $ $ $ $ $ $

download netplug-1.2.5.tar.bz2 tar jxf netplug-1.2.5.tar.bz2 cd netplug-1.2.5 hg init hg commit -q --addremove --message netplug-1.2.5 cd .. hg clone netplug-1.2.5 netplug 156

8 9

updating working directory 18 files updated, 0 files merged, 0 files removed, 0 files unresolved Continue creando una pila de parches y haga sus cambios.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

$ cd netplug $ hg qinit $ hg qnew -m fix build problem with gcc 4 build-fix.patch $ perl -pi -e s/int addr_len/socklen_t addr_len/ netlink.c $ hg qrefresh $ hg tip -p changeset: 1:4adf6cb9cc16 tag: qtip tag: build-fix.patch tag: tip tag: qbase user: Bryan OSullivan <bos@serpentine.com> date: Tue Feb 10 18:23:26 2009 +0000 summary: fix build problem with gcc 4 diff -r ca53495653b5 -r 4adf6cb9cc16 netlink.c --- a/netlink.c Tue Feb 10 18:23:26 2009 +0000 +++ b/netlink.c Tue Feb 10 18:23:26 2009 +0000 @@ -275,7 +275,7 @@ exit(1); } + int addr_len = sizeof(addr); socklen_t addr_len = sizeof(addr); if (getsockname(fd, (struct sockaddr *) &addr, &addr_len) == -1) { do_log(LOG_ERR, "Could not get socket details: %m");

Digamos que pasan unas semanas o meses, y el autor del paquete libera una nueva versi n. Primero se traen sus o cambios al repositorio.
1 2 3 4 5 6 7 8 9 10 11 12 13

$ hg qpop -a Patch queue now empty $ cd .. $ download netplug-1.2.8.tar.bz2 $ hg clone netplug-1.2.5 netplug-1.2.8 updating working directory 18 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd netplug-1.2.8 $ hg locate -0 | xargs -0 rm $ cd .. $ tar jxf netplug-1.2.8.tar.bz2 $ cd netplug-1.2.8 $ hg commit --addremove --message netplug-1.2.8 La porci n que comienza con hg locate mostrada m s arriba, borra todos los cheros en el directorio de trabajo, o a 157

as que la opci n --addremove de hg commit puede indicar qu cheros se han eliminado en la nueva versi n del o e o arbol de fuentes. Finalmente, puede aplicar sus parches encima del nuevo arbol de fuentes
1 2 3 4 5 6 7 8 9 10 11 12 13

$ cd ../netplug $ hg pull ../netplug-1.2.8 pulling from ../netplug-1.2.8 searching for changes adding changesets adding manifests adding file changes added 1 changesets with 12 changes to 12 files (run hg update to get a working copy) $ hg qpush -a (working directory not at tip) applying build-fix.patch Now at: build-fix.patch

12.14.2.

Combinar parches completos

MQ provee la orden hg qfold que le permite combinar parches enteros. Se integran7 los parches que ust ed nombre, en el orden que especique, en el ultimo parche aplicado, y concatena sus descripciones al nal de su descripci n. Deber sustraer los cambios para poder integrarlos. o a El orden en el que integre los parches importa. Si el parche ultimamente aplicado es foo, e integra hg qfold bar y quux en el, terminar con un parche que tiene el mismo efecto que si hubiera aplicado primero foo, y despu s a e bar, seguido de quux.

12.14.3.

Fusionar una porci n de un parche dentro de otro o

Fusionar partes de un parche dentro de otro es m s complejo que combinar completamente dos parches. a Si desea mover cambios de cheros completos, puede usar las opciones filterdiffs -i y -x para elegir las modicaciones remover de un parche, concatenar su salida al nal del parche donde desea fusionarlo. Usualmente no necesitar modicar el parche del cu l ha fusionado los cambios. En cambio, MQ reportar que hay unos trozos a a a que se han desechado cuando usted aplique hg qpush (de los trozos que haya movido al otro parche), y puede sencillamente aplicar hg qrefresh para eliminar los trozos replicados. Si tiene un parche que tiene varios trozos que modican un chero, y desea mover solamente unos de ellos, el trabajo es un poco m s enredado, pero puede automatizarlo parcialmente. Use lsdiff -nvv para imprimir algunos a metadatos del parche.
1 2 3 4 5 6 7 8 9 10 11

$ lsdiff -nvv remove-redundant-null-checks.patch 22 File #1 a/drivers/char/agp/sgi-agp.c 24 Hunk #1 static int __devinit agp_sgi_init(void) 37 File #2 a/drivers/char/hvcs.c 39 Hunk #1 static struct tty_operations hvcs_ops = 53 Hunk #2 static int hvcs_alloc_index_list(int n) 69 File #3 a/drivers/message/fusion/mptfc.c 71 Hunk #1 mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, in 85 File #4 a/drivers/message/fusion/mptsas.c 87 Hunk #1 mptsas_probe_hba_phys(MPT_ADAPTER *ioc) 98 File #5 a/drivers/net/fs_enet/fs_enet-mii.c
7 N.

del T. fold

158

12 13 14 15 16 17 18 19 20 21

111

164 178

100 Hunk #1 File #6 113 Hunk #1 126 Hunk #2 140 Hunk #3 150 Hunk #4 File #7 166 Hunk #1 File #8 180 Hunk #1

static struct fs_enet_mii_bus *create_bu a/drivers/net/wireless/ipw2200.c static struct ipw_fw_error *ipw_alloc_er static ssize_t clear_error(struct device static void ipw_irq_tasklet(struct ipw_p static void ipw_pci_remove(struct pci_de a/drivers/scsi/libata-scsi.c int ata_cmd_ioctl(struct scsi_device *sc a/drivers/video/au1100fb.c void __exit au1100fb_cleanup(void)

Esta orden imprime tres clases diferentes de n meros: u (en la primera columna) un n mero de chero para identicar cada chero modicado en el parche; u (En la siguiente lnea, indentado) el n mero de lnea dentro de un chero modicado donde comienza el trozo; u y (en la misma lnea) un n mero de trozo que identica el trozo. u Tendr que hacer una inspecci n visual, y leer el parche para identicar los n meros de chero y trozo que desea, a o u pero puede pasar posteriormente a las opciones --files y --hunks de filterdiff, para seleccionar exactamente el chero y el trozo que desea extraer. Cuando tenga el trozo, puede concatenarlo al nal de su parche objetivo y continuar como en la secci n 12.14.2. o

12.15.

Diferencias entre quilt y MQ

Si le es familiar quilt, MQ provee un conjunto similar de ordenes. Hay algunas diferencias en c mo funcionan. o Debe haber notado que la mayora de comandos de quilt tienen su contraparte en MQ, que simplemente comienzan con q. Las excepciones son las ordenes add y remove de quilt, que realmente son las ordenes hg add y hg remove de Mercurial. No hay un equivalente en MQ para la orden edit de quilt.

159

Captulo 13

Usos avanzados de las Colas de Mercurial


Auunque es f cil aprender los usos m s directos de las Colas de Mercurial, tener algo de disciplina junto con a a algunas de las capacidadees menos usadas de MQ hace posible trabajar en entornos de desarrollo complejos. En este captulo, usar como ejemplo una t cnica que he usado para administrar el desarrollo de un controlador de e e dispositivo Inniband para el kernel de Linux. El controlador en cuesti n es grande (al menos en lo que se reere a o controladores), con 25,000 lneas de c digo esparcidas en 35 cheros fuente. Es mantenido por un equipo peque o de o n desarrolladores. Aunque mucho del material en este captulo es especco de Linux, los mismos principios aplican a cualquier base de c digo de la que usted no sea el propietario principal, y sobre la que usted necesita hacer un mont n de desarrollo. o o

13.1.

El problema de multiples objetivos

El kernel de Linux cambia con rapidez, y nunca ha sido estable internamente; los desarrolladores hacen cambios dr sticos entre versiones frecuentemente. Esto signica que una versi n del controlador que funciona bien con una a o versi n particular del kernel ni siquiera compilar correctamente contra, tpicamente, cualquier otra versi n. o a o Para mantener un controlador, debemos tener en cuenta una buena cantidad de versiones de Linux en mente. Un objetivo es el arbol de desarrollo principal del kernel de Linux. En este caso el mantenimiento del c digo o es compartido parcialmente por otros desarrolladores en la comunidad del kernel, quienes hacen modicaciones de-af n al controlador a medida que desarrollan y renan subsistemas en el kernel. a Tambi n mantenemos algunos backports para versiones antiguas del kernel de Linux, para dar soporte a e las necesidades de los clientes que est n corriendo versiones antiguas de Linux que no incorporan nuestros a controladores. (Hacer el backport de un pedazo de c digo es modicarlo para que trabaje en una versi n de su o o entorno objetivo anterior a aquella para la cual fue escrito.) Finalmente, nosotros liberamos nuestro software de acuerdo a un cronograma que no necesariamente est alina eado con el que usan los distribuidores de Linux y los desarrolladores del kernel, as que podemos entregar nuevas caractersticas a los clientes sin forzarlos a actualizar kernels completos o distribuciones.

13.1.1.

Aproximaciones tentadoras que no funcionan adecuadamente

Hay dos maneras est ndar de mantener una porci n de software que debe funcionar en muchos entornos diferentes. a o La primera es mantener varias ramas, cada una pensada para un unico entorno. El problema de esta aproximaci n o es que usted debe tener una disciplina f rrea con el ujo de cambios entre repositorios. Una nueva caracterstica o un e arreglo de fallo deben empezar su vida en un repositorio prstino, y luego propagarse a cada repositorio de backport. Los cambios para backports est n m s limitados respecto a las ramas a las que deberan propagarse; un cambio para a a backport que es aplicado a una rama en la que no corresponde probablemente har que el controlador no compile. a 160

La segunda es mantener un unico arbol de c digo fuente lleno de declaraciones que activen o desactiven secciones o de c digo dependiendo del entorno objetivo. Ya que estos ifdefs no est n permitidos en el arbol del kernel de Linux, o a debe seguirse alg n proceso manual o autom tico para eliminarlos y producir un arbol limpio. Una base de c digo u a o mantenida de esta manera se convierte r pidamente en un nido de ratas de bloques condicionales que son difciles de a entender y mantener. Ninguno de estos enfoques es adecuado para situaciones en las que usted no es due o de la copia can nica n o de un arbol de fuentes. En el caso de un controlador de Linux que es distribuido con el kernel est ndar, el arbol de a Linux contiene la copia del c digo que ser considerada por el mundo como la can nica. La versi n ocial de mi o a o o controlador puede ser modicada por gente que no conozco, sin que yo siquiera me entere de ello hasta despu s de e que los cambios aparecen en el arbol de Linus. Estos enfoques tienen la debilidad adicional de dicultar la generaci n de parches bien formados para enviarlos a o la versi n ocial. o En principio, las Colas de Mercurial parecen ser un buen candidato para administrar un escenario de desarrollo como el de arriba. Aunque este es de hecho el caso, MQ tiene unas cuantas caractersticas adicionales que hacen el trabajo m s agradable. a

13.2.

Aplicar parches condicionalmente mediante guardias

Tal vez la mejor manera de conservar la cordura con tantos entornos objetivo es poder escoger parches especcos para aplicar para cada situaci n. MQ provee una caracterstica llamada guardias (que se origina del comando guards o de Quilt) que hace precisamente esto. Para empezar, creemos un repositorio sencillo para experimentar.
1 2 3 4 5 6 7 8 9

$ $ $ $ $ $ $ $ $

hg qinit hg qnew hello.patch echo hello > hello hg add hello hg qrefresh hg qnew goodbye.patch echo goodbye > goodbye hg add goodbye hg qrefresh

Esto nos brinda un peque o repositorio que contiene dos parches que no tienen ninguna dependencia respecto al otro, n porque tocan cheros diferentes. La idea detr s de la aplicaci n condicional es que usted puede etiquetar un parche con un guardia, que sima o plemente es una cadena de texto de su elecci n, y luego decirle a MQ que seleccione guardias especcos para usar o cuando aplique parches. MQ entonces aplicar , u omitir , un parche vigilado, dependiendo de los guardias que usted a a haya seleccionado. Un parche puede tener una cantidad arbitraria de guardias; cada uno es positivo (aplique el parche si este guardia es seleccionado) o negativo (omita este parche si este guardia es seleccionado). Un parche sin guardias siempre es aplicado.

13.3.

Controlar los guardias de un parche

El comando hg qguard le permite determinar qu guardias deben aplicarse a un parche, o mostrar los guardias e que est n en efecto. Sin ning n argumento, el comando muestra los guardias del parche actual de la parte m s alta de a u a la pila.
1 2

$ hg qguard goodbye.patch: unguarded

161

Para poner un guardia positivo en un parche, preje el nombre del guardia con un +.
1 2 3

$ hg qguard +foo $ hg qguard goodbye.patch: +foo Para poner un guardia negativo en un parche, preje el nombre del guardia con un -.

1 2 3

$ hg qguard hello.patch -quux $ hg qguard hello.patch hello.patch: -quux Nota: El comando hg qguard pone los guardias en un parche; no los modica. Esto signica que si usted ejecuta hg qguard +a +b sobre un parche, y luego hg qguard +c en el mismo parche, el unico guardia sobre el parche despu s del e comando ser +c. a Mercurial almacena los guardias en el chero series; la forma en que son almacenados es f cil tanto de entender a como de editar a mano. (En otras palabras, usted no tiene que usar el comando hg qguard si no lo desea; est bien a simplemente editar el chero series)

1 2 3

$ cat .hg/patches/series hello.patch #-quux goodbye.patch #+foo

13.4.

Selecccionar los guardias a usar

El comando hg qselect determina qu guardias est n activos en cualquier momento. El efecto de esto es e a determinar qu parches aplicar MQ la pr xima vez que usted ejecute hg qpush. No tiene ning n otro efecto; en e a o u particular, no hace nada a los parches que ya han sido aplicados. Sin argumentos, el comando hg qselect lista los guardias en efecto actualmente, uno por cada lnea de salida. Cada argumento es tratado como el nombre de un guardia a aplicar.
1 2 3 4 5 6 7 8

$ hg qpop -a Patch queue now empty $ hg qselect no active guards $ hg qselect foo number of unguarded, unapplied patches has changed from 1 to 2 $ hg qselect foo Si est interesado, los guardias seleccionados actualmente est n almacenados en el chero guards. a a

1 2

$ cat .hg/patches/guards foo Podemos ver el efecto que tienen los guardias seleccionados cuando ejecutamos hg qpush.

1 2 3 4

$ hg qpush -a applying hello.patch applying goodbye.patch Now at: goodbye.patch 162

Un guardia no puede empezar con un caracter + o -. El nombre del guardia no debe contener espacios en blanco, pero muchos otros caracteres son aceptables. Si usted trata de usar un guardia con un nombre inv lido, MQ se a quejar : a
1 2

$ hg qselect +foo abort: guard +foo starts with invalid character: + Cambiar los guardias seleccionados cambia los parches que son aplicados.

1 2 3 4 5 6

$ hg qselect quux number of guarded, applied patches has changed from 0 to 2 $ hg qpop -a Patch queue now empty $ hg qpush -a patch series already fully applied Usted puede ver en el ejemplo de abajo que los guardias negativos tienen precedencia sobre los guardias positivos.

1 2 3 4 5 6 7 8

$ hg qselect foo bar number of unguarded, unapplied patches has changed from 0 to 2 $ hg qpop -a no patches applied $ hg qpush -a applying hello.patch applying goodbye.patch Now at: goodbye.patch

13.5.

Reglas de MQ para aplicar parches

Las reglas que MQ usa para decidir si debe aplicar un parche son las siguientes. Un parche sin guardias es aplicado siempre. Si el parche tiene alg n guardia negativo que corresponda con cualquiera de los guardias seleccionados, se salta u el parche. Si el parche tiene alg n guardia positivo que corresponda con cualquiera de los guardias seleccionados, se aplica u el parche. Si el parche tiene guardias positivos o negativos, pero ninguno corresponde con cualquiera de los guardias seleccionados, se salta el parche.

13.6.

Podar el entorno de trabajo

En el trabajo del controlador de dispositivo que mencion anteriormente, yo no aplico los parches a un arbol e normal del kernel de Linux. En cambio, uso un repositorio que s lo contiene una instant nea de los cheros fuente y o a de cabecera que son relevantes para el desarrollo de Inniband. Este repositorio tiene un 1 % del tama o del repositorio n del kernel, por lo que es m s f cil trabajar con el. a a Luego escojo una versi n base sobre la cual son aplicados los parches. Es una instant nea del arbol del kernel o a de Linux en una revisi n de mi elecci n. Cuando tomo la instant nea, almaceno el ID de conjunto de cambios en el o o a mensaje de consignaci n. Ya que la instant nea preserva la forma y el contenido de las partes relevantes del arbol o a del kernel, puedo aplicar mis parches sobre mi peque o repositorio o sobre un arbol normal del kernel. n 163

Normalmente, el arbol base sobre el que se aplican los parches debera ser una instant nea de un arbol de desarrollo a muy reciente. Esto facilita mucho el desarrollo de parches que puedan ser enviados al arbol ocial con pocas o ninguna modicaci n. o

13.7.

Dividir el chero series

Yo categorizo los parches en el chero series en una serie de grupos l gicos. Cada secci n de parches similares o o empieza con un bloque de comentarios que describen el prop sito de los parches que le siguen. o La secuencia de grupos de parches que mantengo se muestra a continuaci n. El orden de los grupos es importante; o explicar porqu luego de que presente los grupos. e e El grupo aceptado. Son parches que el equipo de desarrollo ha enviado al mantenedor del subsistema Inni band, y que el ha aceptado, pero que no est n presentes en la instant nea en la cual est basada el repositorio a a a peque o. Estos son parches de s lo lectura, presentes unicamente para transformar el arbol en un estado n o similar al del repositorio del mantenedor ocial. El grupo revisar. Parches que yo he enviado, pero sobre los que que el mantenedor ocial ha solicitado modicaciones antes de aceptarlos. El grupo pendiente. Parches que no he enviado al mantenedor ocial, pero que ya est n terminados. Estos a parches ser n de s lo lectura por un buen tiempo. Si el mantenedor ocial los acepta cuando los enve, los a o mover al nal del grupo aceptado. Si el solicita que modicaciones en alguno de ellos, los mover al principio e e del grupo revisar. El grupo en proceso. Parches que est n siendo activamente desarrollados, y no deberan ser enviados a ninguna a parte a n. u El grupo backport. Parches que adaptan el arbol de fuentes a versiones antiguas del arbol del kernel. El grupo no enviar. Parches que por alguna raz n nunca deben ser enviados al mantenedor ocial del kernel. o Por ejemplo, alguno de esos parches podra cambiar las cadenas de identicaci n embebidas del controlador o para hacer m s f cil la distinci n, en pruebas de campo, entre una versi n del controlador de salida-del- rbol y a a o o a una versi n entregada por un vendedor de alguna distribuci n. o o Ahora volvemos a las razones para ordenar los grupos de parches en esta manera. Quisi ramos que los parches del e fondo de la pila sean tan estables como sea posible, para no tener que revisar parches m s arriba debido a cambios de a contexto. Poner los parches que nunca cambiar n en el primer lugar del chero series sirve a este prop sito. a o Tambi n desearamos que los parches que sabemos que debemos modicar sean aplicados sobre un arbol de fuentes e que se parezca al ocial tanto como sea posible. Es por esto que mantenemos los parches aceptados disponibles por una buena cantidad de tiempo. Los parches backport y no enviar otan al nal del chero series. Los parches de backport deben ser aplicados encima de todos los otros parches, y los parches no enviar pueden perfectamente quedarse fuera del camino.

13.8.

Mantener la serie de parches

En mi trabajo, uso varios guardias para controlar qu parches deben ser aplicados. e Los parches aceptados son vigilados con accepted. Yo habilito este guardia la mayora de las veces. Cuando aplico los parches sobre un arbol donde los parches ya est n presentes, puedo desactivar este parche, y los a parches que lo siguen se aplicar n sin problemas. a Los parches que est n terminados, pero no han sido enviados, no tienen guardias. Si estoy aplicando la pila a de parches a una copia del arbol ocial, no necesito habilitar ning n guardia para obtener un arbol de fuentes u razonablemente seguro. 164

Los parches que necesitan revisi n antes de ser reenviados tienen el guardia rework. o Para aquellos parches que a n est n bajo desarrollo, uso devel. u a Un parche de backport puede tener varios guardias, uno para cada versi n del kernel a la que aplica. Por ejemplo, o un parche que hace backport de un segmento de c digo a 2.6.9 tendr un guardia 2.6.9. o a La variedad de guardias me brinda una exibilidad considerable para determinar qu tipo de arbol de fuentes acabar por e e obtener. En la mayora de las situaciones, la selecci n de guardias apropiados es automatizada durante el proceso de o compilaci n, pero puedo ajustar manualmente los guardias a usar para circunstancias poco comunes. o

13.8.1.

El arte de escribir parches de backport

Al usar MQ, escribir un parche de backport es un proceso simple. Todo lo que dicho parche debe hacer es modicar una secci n de c digo que usa una caracterstica del kernel que no est presente en la versi n anterior del kernel, para o o a o que el controlador siga funcionando correctamente en esa versi n anterior. o Una meta util al escribir un buen parche de backport es hacer parecer que el c digo hubiera sido escrito para la o versi n vieja del kernel que usted tiene como objetivo. Entre menos intrusivo el parche, m s f cil ser entenderlo y o a a a mantenerlo. Si usted est escribiendo una colecci n de parches de backport para evitar el efecto de nido de ratas de a o tener muchos #ifdefs (secciones de c digo fuente que s lo son usados condicionalmente) en su c digo, no introduzca o o o #ifdefs dependientes de versiones especcas en los parches. En vez de eso, escriba varios parches, cada uno de ellos haciendo cambios incondicionales, y controle su aplicaci n usando guardias. o Hay dos razones para ubicar los parches de backport en un grupo diferente, aparte de los parches regulares cuyos efectos son modicados por ellos. La primera es que mezclar los dos hace m s difcil usar herramientas como la a extensi n patchbomb para automatizar el proceso de enviar los parches a un mantenedor ocial. La segunda es que un o parche de backport puede perturbar el contexto en el que se aplica un parche regular subsecuente, haciendo imposible aplicar el parche normal limpiamente sin que el parche de backport sea aplicado antes.

13.9.
13.9.1.

Consejos utiles para hacer desarrollo con MQ


Organizar parches en directorios

Si est trabajando en un proyecto grande con MQ, no es difcil acumular un gran n mero de parches. Por ejemplo, a u tengo un repositorio de parches que contiene m s de 250 parches. a Si usted puede agrupar estos parches en categoras l gicas separadas, usted puede almacenarlos en diferentes o directorios si lo desea; MQ no tiene problemas manejando nombres de parches que contienen separadores de ruta.

13.9.2.

Ver el historial de un parche

Si usted est desarrollando un conjunto de parches en un perodo de tiempo grande, es una buena idea mantenerlos a en un repositorio, como se discuti en la secci n 12.11. Si lo hace, notar r pidamente que usar el comando hg diff o o a a para mirar el historial del repositorio no es viable. Esto es debido en parte a que usted est mirando la segunda derivada a del c digo real (el diff de un diff), pero tambi n porque MQ a ade ruido al proceso al modicar las marcas de tiempo o e n y los nombres de directorio cuando actualiza un parche. Sin embargo, usted puede usar la extensi n extdiff, que es provisto junto con Mercurial, para convertir un diff o de dos versiones de un parche en algo legible. Para hacer esto, usted necesitar un paquete de un tercero llamado a patchutils [Wau]. Este paquete provee un comando llamado interdiff, que muestra las diferencias entre dos diffs como un diff. Al usarlo en dos versiones del mismo diff, genera un diff que representa el diff de la primera a la segunda versi n. o Usted puede habilitar la extensi n extdiff de la manera usual, a adiendo una lnea a la secci n [extensions] o n o de su hgrc.

165

1 2

[extensions] extdiff = El comando interdiff espera recibir los nombres de dos cheros, pero la extensi n extdiff le pasa un par de o directorios al programa que ejecuta, cada uno de los cuales puede contener una cantidad arbitraria de cheros. Por esto necesitamos un programa peque o que ejecute interdiff en cada par de cheros de estos dos directorios. n Este programa est disponible como hg-interdiff en el directorio examples del repositorio de c digo fuente que a o acompa a a este libro. n

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42

#!/usr/bin/env python # # Adapter for using interdiff with mercurials extdiff extension. # # Copyright 2006 Bryan OSullivan <bos@serpentine.com> # # This software may be used and distributed according to the terms of # the GNU General Public License, incorporated herein by reference. import os, sys def walk(base): # yield all non-directories below the base path. for root, dirs, files in os.walk(base): for f in files: path = os.path.join(root, f) yield path[len(base)+1:], path else: if os.path.isfile(base): yield , base # create list of unique file names under both directories. files = dict(walk(sys.argv[1])) files.update(walk(sys.argv[2])) files = files.keys() files.sort() def name(base, f): if f: path = os.path.join(base, f) else: path = base # interdiff requires two files; use /dev/null if one is missing. if os.path.exists(path): return path return /dev/null ret = 0 for f in files: if os.system(interdiff "%s" "%s" % (name(sys.argv[1], f), name(sys.argv[2], f))): 166

43 44 45

ret = 1 sys.exit(ret) Con el programa hg-interdiff en la ruta de b squeda de su int rprete de comandos, puede ejecutarlo como u e sigue, desde dentro de un directorio de parches MQ:

hg extdiff -p hg-interdiff -r A:B my-change.patch Ya que usted seguramente querr usar este comando tan largo a menudo, puede hacer que hgext lo haga disponible a como un comando normal de Mercurial, editando de nuevo su hgrc.

1 2

[extdiff] cmd.interdiff = hg-interdiff Esto le indica a hgext que ponga a disposici n un comando interdiff, con lo que usted puede abreviar la invocaci n o o anterior de hg extdiff a algo un poco m s manejable. a

hg interdiff -r A:B my-change.patch Nota: El comando interdiff trabaja bien s lo si los cheros contra los cuales o son generadas las versiones de un parche se mantienen iguales. Si usted crea un parche, modica los cheros subyacentes, y luego regenera el parche, interdiff podra no producir ning n resultado util. u La extensi n extdiff es util para m s que solamente mejorar la presentaci n de los parches MQ. Para leer m s o a o a acerca de esto, vaya a la secci n 14.2. o

167

Captulo 14

Anadir funcionalidad con extensiones


A pesar de que el coraz n de Mercurial es muy completo desde el punto de vista de funcionalidad, carece de o caractersticas rimbombantes deliberadamente. Esta aproximaci n de preservar la simplicidad mantiene el programa o sencillo tanto para mantenedores como para usuarios. Si embargo Mercurial no le cierra las posibilidades a un conjunto inexible de ordenes: usted puede a adir caracn tersticas como extensiones (aveces llamadas a adidos1 ). Ya hemos discutido algunas de estas extensiones en captulos n anteriores: La secci n 3.3 cubre la extensi n fetch; que combina jalar cambios y fusionarlos con los cambios locales en o o una sola orden: hg fetch. En el captulo 10, cubrimos muchas extensiones que son utiles en funcionalidades relacionadas con ganchos: Los acl a aden listas de control de acceso; bugzilla a ade integraci n con el sistema de seguimiento de fallos n n o Bugzilla; y notify enva noticaciones por correo de nuevos cambios. La extensi n de administraci n de parches MQ es tan invaluable que amerita dos captulos y un ap ndice por o o e s misma. El captulo 12 cubre lo b sico; el captulo 13 discute temas avanzados; y el ap ndice B muestra en a e detalle cada orden. En este captulo 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. o En la secci n 14.1, discutiremos la posibilidad de mejorar el desempe o en gran medida con la extensi n o n o inotify.

14.1.

Mejorar el desempeno con la extensi n inotify o

Desea lograr que las operaciones m s comunmente usadas de Mercurial se ejecuten centenas de veces m s r pido? a a a A leer! Mercurial tiene gran desempe o bajo circunstancias normales. Por ejemplo, cuando ejecuta la orden hg status, n Mercurial tiene que revisar casi todos los cheros y directorios en su repositorio de forma que pueda desplegar el estado de los cheros. Muchas otras ordenes tienen que hacer tal trabajo tras bambalinas; por ejemplo la orden hg diff usa la maquinaria de estado para evitar hacer operaciones de comparaci n costosas en cheros que obviamente no han o cambiado. Dado que obtener el estado de los cheros es crucial para obtener buen desempe o, los autores de Mercurial han n optimizado este c digo en la medida de lo posible. Sin embargo, no puede obviarse el hecho de que cuando ejecuta o hg status, Mercurial tendr que hacer por lo menos una costosa llamada al sistema por cada chero administrado a
1 N.

del T. plugins

168

para determinar si ha cambiado desde la ultima vez que se consign . Para un repositorio sucientemente grande, puede o tardar bastante tiempo. Para mostrar en n meros la magnitud de este efect, cre un repositorio que contena 150.000 cheros administrador. u e Tard diez segundos para ejecutar hg status, a pesar de que ninguno de los cheros haba sido modicado. o Muchos sistemas operativos modernos contienen una facilidad de noticaci n de cheros. Si un programa se o registra con un servicio apropiado, el sistema operativo le noticar siempre que un chero de inter s haya sido a e creado, modicado o borrado. En sistemas Linux, el componente del n cleo que lo hace se llama inotify. u La extensi n inotify habla con el componente inotify del n cleo para optimizar las ordenes de hg status. o u La extensi n tiene dos componentes. Un daemonio est en el fondo recibiendo noticaciones del subsistema inotify. o a Tambi n escucha conexiones de una orden regular de Mercurial. La extensi n modica el comportamiento de Mercue o rial de tal forma que, en lugar de revisar el sistema de cheros, 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 o a necesidad de revisar cada directorio y chero del repositorio. Retomando los diez segundos que med al ejecutar la orden hg status de Mercurial sobre un repositorio de 150.000 cheros. Con la extensi n inotify habilitada, el tiempo se disip a 0.1 seconds, un factor cien veces m s o o a r pido. a Antes de continuar, tenga en cuenta algunos detalles: La extensi n inotify es especca de Linux. Porque se enlaza directamente con el subsistema inotify del o n cleo Linux, no funciona en otros sistemas operativos. u Debera funcionar en cualquier distribuci n Linux a partir de comienzos del 2005. Las distribuciones m s an o a tiguas deben tener un kernel sin inotify, o una versi n de glibc que no tiene necesariamente el soporte para o la interfaz. No todos los sistemas de cheros pueden usarse con la extensi n inotify. Los sistemas de cheros tales como o NFS no lo soportan, por ejemplo, si est corriendo Mercurial en vaios sistemas, montados todos sobre el mismo a sistema de cheros en red. El sistema inotify del kernel no tiene forma de saber acerca de los cambios hechos en otro sistema. La mayora de sistemas de cheros locales (p.e. ext3, XFS, ReiserFS) deberan funcionar bien. Hacia mayo de 2007 la extensi n inotify no vena de forma predeterminada en Mercurial2 , y es un poco m s o a compleja de activar que otras extensiones. Pero la mejora en el desempe o bien vale la pena! n La extensi n vena en dos partes: un conjunto de parches al c digo fuente de Mercurial, y una librera de interfaces o o Nota: Hay dos libreras de enlace de Python hacia inotify. Una de ellas se llama pyinotify, y en algunas distribuciones de Linux se encuentra como de Python hacia el subsistema inotify. python-inotify. Esta es la que no necesita, puesto que tiene muchos fallos, y es ineciente para ser pr ctica. a

Nota: Si sigue las instrucciones a continuaci n, estar reempl o a o Para comenzar, es mejor tener una copia de Mercurial funcional instalada: biendo cualquier instalaci n previa de Mercurial que pudiera de Mercurial m s reciente y peligrosa. No diga que no se le a 1. Clone el repositorio de interfaz entre Python e inotify. Armelo e inst lelo: a
1 2 3 4

hg clone http://hg.kublai.com/python/inotify cd inotify python setup.py build --force sudo python setup.py install --skip-build

2. Clone el repositorio crew de Mercurial. Clone el repositorio de parches de inotify de forma tal que las colas de Mercurial puedan aplicar los parches sobre el repositorio crew.
2 N.

del T. Desde el 2008 para kernels 2.6 viene en Mercurial, pero no est activada de forma predeterminada a

169

1 2 3

hg clone http://hg.intevation.org/mercurial/crew hg clone crew inotify hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches

3. Aseg rese de instalar la extensi n Colas de Mercurial mq y que est n habilitadas. Si nunca ha usado MQ, lea la u o e secci n 12.5 para poder comenzar r pidamente. o a 4. Vaya al repositorio de inotify y aplique todos los parches de inotify con la opci n -a de la orden hg o qpush.
1 2

cd inotify hg qpush -a Si obtiene un mensaje de error de hg qpush, no debera continuar. Mejor pida ayuda.

5. Arme e instale la versi n parchada de Mercurial. o


1 2

python setup.py build --force sudo python setup.py install --skip-build

Una vez que haya armado una versi n funcional parchada de Mercurial, todo lo que necesita es habilitar la extensi n o o inotify colocando una entrada en su hgrc.
1 2

[extensions] inotify = Cuando la extensi n inotify est habilitada, Mercurial iniciar transparente y autom ticamente el daemonio de eso e a a tado la primera vez que ejecute un comando que requiera estado del repositorio. Ejecuta un daemonio 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 o despu s de habilitar la extensi n inotify y ejecuta unos pocos comandos en diferentes repositorios, ver que hay e o a algunos procesos de 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 inotify hao bilitada, correr casi con el mismo desempe o que una orden usual de Mercurial. Esto es debido a que el estado del a n daemonio necesita aplicar una b squeda normal sobre el estado para poder tener una lnea de partida frente a la cual u aplicar posteriormente actualizaciones del n cleo. De todas formas, todo comando posterior que haga cualquier clase u de revisi n del estado debera ser notablemente m s r pido en repositorios con incluso un tama o modesto. A n mejor, o a a n u a medida que su repositorio sea m s grande, mejor desempe o ver . El daemonio inotify hace operaciones de estado a n a de forma casi instant nea en repositorios de todos los tama os! a n Si lo desea, puede iniciar manualmente un daemonio de estado con la orden hg inserve. Esto le da un control un poco m s no acerca de c mo debera ejecutarse el daemonio. Esta orden solamente estar disponible cuando haya a o a habilitado la extensi n inotify. o Cuando est usando la extensi n inotify, no debera ver diferencia en el comportamiento de Mercurial, con e o la unica excepci n de que los comandos relacionados con el estado deberan ejectuarse mucho m s r pido que coo a a mo solan hacerlo. Debera esperar especcamente que las ordenes no deberan ofrecer salidas distintas; ni ofrecer resultados diferentes. Si alguna de estas situaciones ocurre, por favor reporte el fallo.

14.2.

Soporte exible de diff con la extensi n extdiff o

La orden predeterminada hg diff de Mercurial despliega diffs en texto plano unicadas. 170

1 2 3 4 5 6 7

$ hg diff diff -r d6e1fbefacc8 myfile --- a/myfile Tue Feb 10 18:23:22 2009 +0000 +++ b/myfile Tue Feb 10 18:23:22 2009 +0000 @@ -1,1 +1,2 @@ The first line. +The second line. Si dese emplear una herramienta externa para desplegar las modicaciones, querr usar la extensi n extdiff. Esta le a o permitir usar por ejemplo una herramienta gr ca de diff. a a La extensi n extdiff viene con Mercurial, y es f cil congurar. En la secci n [extensions] de su hgrc, basta o a o con a adir una entrada de una lnea para habilitar la extensi n. n o

1 2

[extensions] extdiff = Esto introduce una orden llamada hg extdiff, que de forma predeterminada usa su orden del sistema diff para generar un diff unicado de la misma forma que lo hace el comando predeterminado hg diff.

1 2 3 4 5 6

$ hg extdiff --- a.d6e1fbefacc8/myfile +++ /tmp/extdiff83LA2p/a/myfile @@ -1 +1,2 @@ The first line. +The second line.

2009-02-10 18:23:22.000000000 +0000 2009-02-10 18:23:22.000000000 +0000

El resultado no ser exactamente el mismo que con la orden interna hg diff, puesto que la salida de diff vara de a un sistema a otro, incluso pasando las mismas opciones. Como lo indican las lneasmaking snapshot, la orden hg extdiff funciona creando dos instant neas de a su arbol de fuentes. La primera instant nea es la revisi n fuente; la segunda es la revisi n objetivo del directorio a o o de trabajo. La orden hg extdiff genera estas instant neas en un directorio temporal, pasa el nombre de cada a directorio a un visor de diffs temporal y borra los directorios temporales. Por cuestiones de eciencia solamente genera instant neas de los directorios y cheros que han cambiado entre dos revisiones. a Los nombres de los directorios de instant neas tienen los mismos nombres base de su repositorio. Si su repositorio a tiene por ruta /quux/bar/foo, foo ser el nombre de cada instant nea de directorio. Cada instant nea de directorio a a a tiene sus identicadores de conjuntos de cambios al nal del nombre en caso de que sea apropiado. Si una instant nea a viene de la revisi n a631aca1083f, el directorio se llamar foo.a631aca1083f. Una instant nea del directorio de o a a trabajo no tendr el identicador del conjunto de cambios, y por lo tanto ser solamente foo en este ejemplo. Para ver a a c mo luce en la pr ctica, veamos de nuevo el ejemplo hg extdiff antes mencionado. Tenga en cuenta que los diffs o a tienen los nombres de las instant neas de directorio dentro de su encabezado. a La orden hg extdiff acepta dos opciones importantes. La opci n -p le permite elegir un programa para ver las o diferencias, en lugar de diff. Con la opci n -o puede cambiar las opciones que hg extdiff pasa a tal programa o (de forma predeterminada las opciones son-Npru, que tienen sentido unicamente si est usando diff). En otros a aspectos, la orden hg extdiff act a de forma similar a como lo hace la orden hg diff de Mercurial: usted usa u los mismos nombres de opciones, sintaxis y argumentos para especicar las revisiones y los cheros que quiere, y as sucesivamente. Por ejemplo, para ejecutar la orden usual del sistema diff, para lograr que se generen diferencias de contexto (con la opci n -c) en lugar de diferencias unicadas, y cinco lneas de contexto en lugar de las tres predeterminadas o (pasando 5 como argumento a la opci n -C). o
1 2

$ hg extdiff -o -NprcC5 *** a.d6e1fbefacc8/myfile

Tue Feb 10 18:23:22 2009 171

3 4 5 6 7 8

--- /tmp/extdiff83LA2p/a/myfile *************** *** 1 **** --- 1,2 ---The first line. + The second line.

Tue Feb 10 18:23:22 2009

Es sencillo lanzar unas herramienta usual de diferencias. Para lanzar el visor kdiff3:
1

hg extdiff -p kdiff3 -o 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 mq junto con la orden interdiff est en la secci n 13.9.2. o a o

14.2.1.

Denici n de alias de comandos o

Acordarse de todas las opciones de las ordenes hg extdiff y el visor de diferencias de su preferencia puede ser dispendioso, y por lo tanto la extensi n extdiff le permite denir nuevas ordenes que invocar n su visor de o a diferencias con las opciones exactas. Basta con editar su chero hgrc, y a adir una secci n llamada [extdiff]. Dentro de esta secci n puede denir n o o varias ordenes. Mostraremos como a adir la orden kdiff3. Despu s de denido, puede teclear hg kdiff3 y la n e extensi n a extdiff ejecutar la orden kdiff3. o a
1 2

[extdiff] cmd.kdiff3 = Si deja vaca la porci n derecha de la denici n, como en el ejemplo, la extensi n extdiff usa el nombre de la o o o orden se denir como el nombre del programa externo a ejecutar. Pero tales nombres no tienen por qu ser iguales. a e Denimos ahora la orden llamada hg wibble, que ejecuta kdiff3.

1 2

[extdiff] cmd.wibble = kdiff3 Tambi n puede especicar las opciones predeterminadas con las cuales desea invocar el visor de diferencias. Se e usa el prejo opts., seguido por el nombre de la orden a la cual se aplican las opciones. En este ejemplos se dene la orden hg vimdiff que ejecuta la extensi n DirDiff del editor vim. o

1 2 3

[extdiff] cmd.vimdiff = vim opts.vimdiff = -f +next +execute "DirDiff" argv(0) argv(1)

14.3.

Uso de la extensi n transplant para seleccionar o

Need to have a long chat with Brendan about this.

14.4.

Enviar cambios va correo electr nico con la extensi n patchbomb o o

Varios proyectos tienen la cultura de revisi n de cambios, en la cual la gente enva sus modicaciones a una lista o de correo para que otros las lean y comenten antes de consignar la versi n nal a un repositorio compartido. Algunos o proyectos tienen personas que act an como cancerberos; ellos aplican los cambios de otras personas a un repositorio u para aquellos que no tienen acceso. 172

Mercurial facilita enviar cambios por correo para revisi n o aplicaci n gracias a su extensi n patchbomb. La o o o extensi n es tan popular porque los cambios se formatean como parches y es usual que se enva un conjunto de o cambios por cada correo. Enviar una gran cantidad de cambios por correos se llama por tanto bombardear el buz n o de entrada del destinatario, de ah su nombre bombardeo de parches. Como es usual, la conguraci n b sica de la extensi n patchbomb consta de una o dos lneas en su hgrc. o a o
1 2

[extensions] patchbomb = Cuando haya habilitado la extensi n, dispondr de una nueva orden, llamada hg email. o a La forma mejor y m s segura para invocar la orden hg email es ejecutarla siempre con la opci n -n; que le a o mostrar lo que la orden enviara, sin enviar nada. Una vez que haya dado un vistazo a los cambios y vericado que a est enviando los correctos, puede volver a ejecutar la misma orden, sin la opci n -n. a o La orden hg email acepta la misma clase de sintaxis de revisiones como cualquier otra orden de Mercurial. Por ejemplo, enviar todas las revisiones entre la 7 y la punta, inclusive. a

hg email -n 7:tip Tambi n puede especicar un repositorio para comparar. Si indica un repositoro sin revisiones, la orden hg email e enviar todas las revisiones en el repositorio local que no est n presentes en el repositorio remoto. Si especica a a revisiones adicionalmente o el nombre de una rama (la ultima con la opci n -b), respetar las revisiones enviadas. o a Ejecutar la orden hg email sin los nombres de aquellas personas a las cuales desea enviar el correo es completamente seguro: si lo hace, solicitar tales valores de forma interactiva. (Si est usando Linux o un sistema tipo Unix, a a tendr capacidades estiloreadline aumentadas cuando ingrese tales encabezados, lo cual es sumamente util.) a Cuando enve una sola revisi n, la orden hg email de forma predeterminada usar la primera lnea de descrip o a ci n del conjunto de cambios como el tema del unico mensaje que se enviar . o a Si enva varias revisiones, la orden hg email enviar normalmente un mensaje por conjunto de cambios. Colo a car como prefacio un mensaje introductorio en el cual usted debera describir el prop sito de la serie de cambios que a o est enviando. a

14.4.1.

Cambiar el comportamiento de las bombas de parches

Cada proyecto tiene sus propias convenciones para enviar cambios en un correo electr nico; la extensi n patchbomb o o intenta acomodarse a diferentes variaciones gracias a las opciones de la lnea de ordenes: Puede escribir un tema para el mensaje introductorio en la lnea de ordenes con la opci -s. Toma un argumento: n el tema del mensaje a usar. Para cambiar el correo electr nico del campo del cual se origina, use la opci n -f. Toma un argumento, el correo o o electr nico a usar. o El comportamiento predeterminado es enviar diferencias unicadas (consulte la secci n 12.4 si desea una deo scripci n del formato), una por mensaje. Puede enviar un conjunto binario3 con la opci n -b. o o Las diferencias unicadas est n precedidas por un encabezado de metadatos. Puede omitirlo, y enviar diferencias a sin adornos con la opci n --plain. o Las diferencias usualmente se envan en lnea, como parte del cuerpo del mensaje con la descripci n del o parche. Que facilita a a la mayor cantidad de lectores citar y responder partes de un diff, dado que algunos clientes de correo solamente citar n la primera parte MIME del cuerpo de un mensaje. Si preere enviar la a descripci n y el diff en partes separadas del cuerpo, use la opci n -a. o o
3 N.

del T. binary bundle

173

En lugar de enviar mensajes de correo puede escribirlos a un chero con formato-mbox- con la opci n -m. La o opci n recibe un argumento, el nombre del chero en el cual escribir. o Si desea a adir un resumen con formato-diffstat en cada parche, y uno como mensaje introductorio, use la n opci n -d. La orden diffstat despliega una tabla que contiene el nombre de cada chero parchado, el n mero o u de lneas afectadas, y un historgrama mostrando cu nto ha sido modicado cada chero. Lo cual ofrece a los a lectores una mirada cuantitativa de cuan complejo es el parche.

174

Ap ndice A e

Referencia de Ordenes
A.1. hg addAnade cheros en la pr xima consignaci n o o

--include, tambi n -I e --exclude, tambi n -X e --dry-run, tambi n -n e

A.2.

hg diffimprime los cambios en el historial o el directorio actual

Mostrar las diferencias entre revisiones para cheros especicados o directorios, con el formato unicado diff. Si desea ver una descripci n del formato unicado diff, ver la secci n 12.4. o o De forma predeterminada, esta orden no imprime las diferencias para los cheros binarios que Mercurial est sigue iendo. Para controlar este comportamiento, vea las opciones -a y --git.

A.2.1.

Options

opci n --nodates o Omite la fecha y hora cuando se muestran los encabezados de las diferencias. --ignore-blank-lines, tambi n -B e No imprime los cambios que solamente insertan o eliminan lneas en blanco. Una lnea que contiene espacios en blanco no se considera como una lnea en blanco. --include, tambi n -I e Incluye cheros y directorios cuyos nombres coinciden con los patrones elegidos. --exclude, tambi n -X e Excluye los cheros y directorios cuyos nombres coinciden con los patrones elegidos. --text, tambi n -a e Si no especica esta opci n, hg diff no mostrar las diferencias de los cheros que detecte como binarios. Al o a especicar -a se forza a hg diff a tratar los cheros como texto, y generar diferencias para todos.

175

Esta opci n es util para los cherso que son texto en mayor medida pero que tienen caracteres NUL. Si lo usa o en cheros que contienen muchos datos binarios, la salida ser incomprensible. a --ignore-space-change, tambi n -b e No imprime si el unico cambio que en la lnea es la cantidad de espacio en blanco. --git, tambi n -g e Mostrar diferencias compatibles con git. XXX reference a format description. --show-function, tambi n -p e Mostrar el nombre de la funci n que contiene el c digo en una porci n del encabzado usando una heurstica simple. o o o Esta funcionalidad se habilita de forma predeterminada, as que la opci n -p no tiene efectos a menos que cambie el o valor de showfunc en la conguraci n, como en el ejemplo siguiente. o
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

$ echo [diff] >> $HGRC $ echo showfunc = False $ hg diff diff -r a38a6c74a605 myfile.c --- a/myfile.c Tue Feb +++ b/myfile.c Tue Feb @@ -1,4 +1,4 @@ int myfunc() { return 1; + return 10; } $ hg diff -p diff -r a38a6c74a605 myfile.c --- a/myfile.c Tue Feb +++ b/myfile.c Tue Feb @@ -1,4 +1,4 @@ int myfunc() int myfunc() { return 1; + return 10; } --rev, tambi n -r e

>> $HGRC

10 18:23:18 2009 +0000 10 18:23:18 2009 +0000

10 18:23:18 2009 +0000 10 18:23:18 2009 +0000

Especique una o m s revisiones para comparar. La orden hg diff acepta hasta dos opciones -r para especicar a las revisiones a comparar. 1. Despliega las diferencias entre la revisi n padre y del directorio de trabajo. o 2. Despliega las diferencias entre el conjunto de cambios especicados y el directorio de trabajo. 3. Despliega las diferencias entre dos conjuntos de cambios especicados. Puede especicar dos revisiones usando o bien sea las opciones -r o la notaci n de rango. Por ejemplo, las dos o especicaciones de revisiones a continuaci n son equivalentes: o 176

1 2

hg diff -r 10 -r 20 hg diff -r10:20 Cuando especica dos revisiones, esto tiene signicado para Mercurial. Esto signica que hg diff -r10:20 producir un diff que transformar los cheros desde los contenidos en la revisi n 10 a los contenidos de la revisi n a a o o 20, mientras que hg diff -r20:10 signica lo opuesto: el diff que transformara los contenidos de los cheros de la revisi n 20 a los contenidos de la revisi n 10. No puede invertir el orden de esta forma si est haciendo un diff frente o o a al directorio de trabajo. --ignore-all-space, tambi n -w e

A.3.

hg versionimprime la informaci n de versi n y derechos de reo o producci n o

Esta orden despliega la versi n de Mercurial que est usando, y su nota de derechos de reproducci n. Hay cuatro o a o clases de cadenas de versi n posibles: o La cadena unknown. Esta versi n de Mercurial no fue construida en un repositorio de Mercurial, y no puede o determinar su propia versi n. o Una cadena num rica corta, tal como 1.1. Esta es una construcci n de una versi n de Mercurial que se idene o o tica con una etiqueta especca en el repositorio en el cual fue armada (Esto no signica necesariamente que est ejecutando una versi n ocial; alguien pudo haber a adido tal etiqueta a cualquier versi n del repositorio a o n o en el cual armaron Mercurial). Una cadena hexadecimal, tal como 875489e31abe. Esta es una construcci n de una revisi n dada de Mercuo o rial. Una cadena hexadecimal seguida por una fecha, tal como 875489e31abe+20070205. Esta construcci n de la o revisi n de Mercurial fue la construcci n de un repositorio que tuvo cambios locales que no han sido consignao o dos.

A.3.1.

Consejos y trucos

Por qu dieren los resultados de hg diff y hg status? e Cuando ejecuta la orden hg status, ver una lista de cheros para los cuales Mercurial almacenar cambios la a a pr xima vez que consigne. Si ejecuta la orden hg diff, ver que imprime diferencias solamente para un subconjunto o a de los cheros que hg status liste. Hay dos posibles razones para este comportamiento: La primera es que hg status imprime cierta clase de modicaciones que hg diff no despliega normalmente. La orden hg diff usualmente despliega diferencias unicadas, las cuales no tienen la habilidad de representar algunos cambios que Mercurial puede seguir. Lo m s notable es que las diferencias tradicionales no pueden representar a un cambio acerca de la ejecutabilidad de un chero, pero Mercurial s almacena esta informaci n. o Si usa la opci n --git de hg diff, mostrar diferencias compatibles con git que pueden desplegar esta inforo a maci n adicional. o La segunda raz n posible para que hg diff est imprimiendo diferencias para un subconjunto de cheros de o e lo que muestra hg status es que si usted le invoca sin argumento alguno, hg diff imprime diferencias frente al primer padre del directorio de trabajo. Si ha ejecutado hg merge para fusionar dos conjuntos de cambios, pero no ha consignado a n los resultados de la fusi n, su directorio de trabajo tiene dos padres (use hg parents para u o verlos). Mientras que hg status imprime modicaciones relativas a ambos padres despu s de una fusi n que no e o se ha consignado, hg diff opera a n relativo solamente al primer padre. Puede lograr que imprima las diferencias u relativas al segundo padre especicando tal padre con la opci n -r. No hay forma de hacer que imprima las diferencias o relativas a los dos padres. 177

Generar diferencias seguras en binarios Si usa la opci n -a para forzar que Mercurial imprima las diferencias de los cheros que so o bien casi compleo tamente texto o contienen muchos datos binarios, tales diferencias no pueden aplicarse subsecuentemente a la orden hg import de Mercurial o a la orden patch del sistema. Si desea generar una diferencia de un chero binario que es seguro para usarlo como entrada a la orden hg import, use la opci n hg diffgit cuando genere el parche. La orden patch del sistema no puede tratar con o parches binarios.

178

Ap ndice B e

Referencia de las Colas de Mercurial


B.1. Referencia de ordenes MQ

Si desea dar un vistazo a las ordenes que ofrece MQ, use la orden hg help mq.

B.1.1.

hg qappliedimprimir los parches aplicados

La orden hg qapplied imprime la pila actual de parches aplicados. Los parches se imprimen en orden de antig edad, primero los m s antiguos y despu s los m s recientes, por lo tanto el ultimo parche de la lista es el que u a e a est en el tope. a

B.1.2.

hg qcommitconsignar cambios en la cola del repositorio

La orden hg qcommit consigna cualquier cambio sobresaliente en el repositorio .hg/patches. Esta orden solamente funciona si el directorio .hg/patches es un repositorio, p.e. usted cre el directorio con hg qinit -c o o ejecut hg init en el directorio despu s de correr hg qinit. o e Esta orden es un atajo para hg commit --cwd .hg/patches.

B.1.3.

hg qdeleteeliminar un parche del chero series

La orden hg qdelete elimina la entrada del chero series para el parche en el directorio .hg/patches. No sca el parche si ha sido aplicado. De forma predeterminada no borra el chero del parche; use la opci n -f para o hacerlo. Opciones: -f Elimina el chero del parche.

B.1.4.

hg qdiffimprimir la diferencia del ultimo parche aplicado

La orden hg qdiff imprime un diff del parche m s recientemente aplicado. Es equivalente a hg diff -r-2:-1. a

B.1.5.

hg qfoldfusionar (integrar) varios parches en uno solo

La orden hg qfold fusiona muchos parches en el ultimo parche aplicado, de tal forma que el ultimo parche aplicado es la uni n de todos los cambios de los parches en cuesti n. o o Los parches a fusionar no deben haber sido aplicados; hg qfold saldr indicando un error si alguno ha sido a aplicado. El orden en el cual los parches se pliegan es signicativo; hg qfold a b signica aplique el parche m s a reciente, seguido de a, y seguido de b. 179

Los comentarios de los parches integrados se colocan al nal de los comentarios del parche destino, con cada bloque de comentarios separado con tres asteriscos (*). Se usa la opci n -e para editar el mensaje de consignaci n o o para el conjunto de cambios/parches despu s de completarse el pliegue. e Opciones: -e Edita el mensaje de consignaci n y la descripci n del parche del parche que se ha integrado. o o -l Usa los contenidos del chero dado como el nuevo mensaje de consignaci n y descripci n del parche para el o o parche a integrar. -m Usa el texto dado como el mensaje de consignaci n y descripci n del parche para el parche integrado. o o

B.1.6.

hg qheaderdesplegar el encabezado/descripci n de un parche o

La orden hg qheader imprime el encabezado o descripci n de un parche. De forma predeterminada, imprime o el encabezado del ultimo parche aplicado. Si se da un argumento, imprime el encabezado del parche referenciado.

B.1.7.

hg qimportimportar el parche de un tercero en la cola

La orden hg qimport a ade una entrada de un parche externo al chero series y copia el parche en el directorio n .hg/patches. A ade la entrada inmediatamente despu s del ultimo parche aplicado, pero no introduce el parche. n e Si el directorio .hg/patches es un repositorio, hg qimport autom ticamente hace un hg add del parche a importado.

B.1.8.

hg qinitpreparar un repositorio para trabajar con MQ

La orden hg qinit prepara un repositorio para trabajar con MQ. Crea un directorio llamado .hg/patches. Opciones: -c Crea .hg/patches como un repositorio por s mismo. Tambi n crea un chero .hgignore que ignorar el e a chero status. Cuando el directorio .hg/patches es un repositorio, las ordenes hg qimport y hg qnew hacen hg add autom ticamente a los parches nuevos. a

B.1.9.

hg qnewcrear un parche nuevo

La orden hg qnew crea un parche nuevo. Exige un argumento, el nombre que se usar para tal parche. El parche a reci n creado est vaco inicialmente. Se a ade al chero series despu s del ultimo parche aplicado, y se introduce e a n e en el tope de ese parche. Si hg qnew encuentra cheros modicados en el directorio de trabajo, rehusar crear un parche nuevo a meos a que se emplee -f la opci n (ver m s adelante). Este comportamiento le permite hacer hg qrefresh al ultimo parche o a aplicado antes de aplicar un parche nuevo encima de este. Opciones: -f Crea un parche nuevo si los contenidos del directorio actual han sido modicados. Cualquier modicaci n o signicativa se a ade al parche recientemente creado, de tal forma que al nalizar la orden, el directorio de n trabajo no lucir modicado. a -m Usa el texto dado como el mensaje de consignaci n. Este texto se almacenar al principio del chero del parche, o a antes de los datos del parche.

B.1.10.

hg qnextimprimir el nombre del pr ximo parche o

La orden hg qnext imprime el nombre del siguiente parche en el chero series a continuaci n del ultimo o parche aplicado. Este parche sera el pr ximo parche a aplicar si se ejecutara la orden hg qpush. o 180

B.1.11.

hg qpopsustraer parches de la pila

La orden hg qpop elimina los parches aplicados del tope de la pila de parches aplicados. De forma predeterminada solamente remueve un parche. Esta orden elimina los conjuntos de cambios que representan los parches sustrados del repositorio, y actualiza el directorio de trabajo para deshacer los efectos de los parches. Esta orden toma un argumento opcional, que usa como el nombre o el ndice del parche que desea sustraer. Si se da el nombre, sustraer los parches hasta que el parche nombrado sea el ultimo parche aplicado. Si se da un n mero, hg a u qpop lo trata como un ndice dentro del chero series, contando desde cero (no cuenta las lneas vacas o aquellas que sean unicamente comentarios). Sustrae los parches hasta que el parche identicado por el ndice sea el ultimo parche aplicado. La orden hg qpop no lee o escribe parches en el chero series. hg qpop se constituye por tanto en una forma segura de sustraer un parche del chero series o un parche que ha eliminado o renombrado completamente. En los dos ultimos casos, use el nombre del parche tal como lo hizo cuando lo aplic . o De forma predeterminada, la orden hg qpop no sustraer parche alguno si el directorio de trabajo ha sido modia cado. Puede modicar este comportamiento con la opci n -f, que revierte todas las modicaciones del directorio de o trabajo. Opciones: -a Sustrae todos los parches aplicados. Restaura el repositorio al estado antes de haber aplicado parche alguno. -f Revertir forzadamente cualquier modicaci n del directorio de trabajo cuando se hace sustracciones. o -n Sustraer un parche de la cola dado un nombre. La orden hg qpop elimina una lnea del nal del chero status por cada parche que se sustrae.

B.1.12.

hg qprevimprimir el nombre del parche anterior

La orden hg qprev imprime el nombre del parche en el chero series que est antes del ultimo parche aplicado. a Este se volver el ultimo parche aplicado si ejecuta hg qpop. a

B.1.13.

hg qpushintroducir parches a la pila

La orden hg qpush a ade parches a la pila. De forma predeterminada a ade solamente un parche. n n Esta orden crea un conjunto de cambios que representa cada parche aplicado y actualiza el directorio de trabajo aplicando los efectos de los parches. Los datos predeterminados cuando se crea un conjunto de cambios corresponde a: La fecha de consignaci n y zona horaria corresponden a la hora actual de la zona. Dado que tales datos se o usan para computar la identidad de un conjunto de cambios, signica que si hace hg qpop a un parche y hg qpush de nuevo, el conjunto de cambios que introduzca tendr una identidad distinta a la del conjunto de a cambios que sustrajo. El autor es el mismo que el predeterminado usado por la orden hg commit. El mensaje de consignaci n es cualquier texto del chero del parche que viene antes del primer encabezado del o diff. Si no hay tal texto, un mensaje predeterminado se sua para identicar el nombre del parche. Su un parche contiene un encabezado de parche de Mercurial (XXX add link), la informaci n en el encabezado del o parche tiene precedencia sobre el predeterminado. Opciones: -a Introduce todos los parches que no han sido aplicados del chero series hasta que no haya nada m s para a introducir. 181

-l A ade el nombre del parche al nal del mensaje de consignaci n n o -m Si un parche no se aplica limpiamente, usa la entrada para un parche en otra cola almacenada para computar los par metros en una fusi n de tres, y aplica una fusi n de tres fuentes usando la maquinaria usual de Mercurial. a o o Usa la resoluci n de la fusi n como el contenido del parche nuevo. o o -n Usa la cola mencionada si se est fusionando en la introducci n. a o La orden hg qpush lee, pero no modica el chero series. A ade al nal del chero hg status una lnea n por cada parche que se introduce.

B.1.14.

hg qrefreshactualiza el ultimo parche aplicado

La orden hg qrefresh actualiza el ultimo parche aplicado. Modica el parche, elimina el ultimo conjunto de cambios que represent el parche, y crea un nuevo conjunto de cambios para representar el parche modicado. o La orden hg qrefresh busca las siguientes modicaciones: Los cambios al mensaje de consignaci n, p.e. el texto antes del primer encabezado de diff en el chero del o parche, se replejan en el nuevo conjunto de cambios que representa el parche. Las modicaciones a los cheros a los que se les da seguimiento en el directorio de trabajo se a ade al parche. n Los cambios a los cheros a los que se les da seguimiento con hg add, hg copy, hg remove, o hg rename. Se a aden al parche los cheros a adidos, copiados y renombrados, mientras que los cheros elimin n nados y las fuentes renombradas se eliminan. Incluso si hg qrefresh no detecta cambios, de todas maneras recrea el conjunto de cambios que representa el cambio. Esto causa que la identidad del conjunto de cambios diera del conjunto de cambios previo que identic al o parche. Opciones: -e Modicar la descripci n de la consignaci n y el parche con el editor de texto preferido. o o -m Modicar el mensaje de consignaci n y la descripci n del parche con el texto dado. o o -l Modicar el mensaje de consignaci n y la descripci n del parche con el texto del chero dado. o o

B.1.15.

hg qrenamerenombrar un parche

La orden hg qrename renombra un parche y cambia la entrada del parche en el chero series. Con un argumento sencillo, hg qrename renombra el ultimo parche aplicado. Con dos argumentos, renombra el primer argumento con el segundo.

B.1.16.

hg qrestorerestaurar el estado almacenado de la cola

XXX No idea what this does.

B.1.17.

hg qsavealmacena el estado actual de la cola

XXX Likewise.

B.1.18.

hg qseriesimprime la serie completa de parches

La orden hg qseries imprime la serie completa de parches del chero series. Imprime solamente los nombres de los parches sin las lneas en blanco o comentarios. Imprime primero el primero y de ultimo, el ultimo aplicado. 182

B.1.19.

hg qtopimprime el nombre del parche actual

hg qtop imprime el nombre del ultimo parche aplicado.

B.1.20.

hg qunappliedimprimir los parches que aun no se han aplicado

La orden hg qunapplied imprime los nombres de los parches del chero series que todava no han sido aplicados. Los imprime de acuerdo al orden en el cual seran introducidos.

B.1.21.

hg stripremover una revisi n y sus descendientes o

La orden hg strip remueve una revisi n, y todos sus descendientes del repositorio. Deshace los efectos de las o revisiones removidas del repositorio, y actualiza el directorio de trabajo hasta el primer padre de la revisi n removida. o La orden hg strip almacena una copia de segurida de los conjuntos de cambios en un agrupamiento, de forma tal que puedan ser reaplicados en caso de que se hayan removido por equivocaci n. o Opciones: -b Almacenar conjuntos de cambios no relacionados que se han mezclado con los conjuntos de cambios que est n a en franjas con el agrupamiento de copia de seguridad. -f Si una rama tiene varias ramas principales remueve todos los frentes. XXX This should be renamed, y usa -f para desagrupar revisiones cuando hay cambios pendientes. -n No almacene la copia de seguridad agrupada.

B.2.
B.2.1.

Referencia de cheros de MQ
El chero series

El chero series contiene una lista de los nombres de todos los parches que MQ puede aplicar. Se representa como una lista de nombres, uno por lnea. Se ignora el espacio en blanco al principio y al nal. Las lneas pueden contener comentario. Un comentario comienza con el caracter #, y va hasta el nal de la lnea. Se ignoran las lneas vacas y las que solamente contengan comentarios. En alg n momento podra editar el chero series a mano, por tal motivo se admiten comentarios y lneas en u blanco como se menciono anteriormente. Por ejemplo, puede poner en comentario un parche temporalmente y hg qpush omitir tal parche cuando los aplique. Tambi n puede cambiar el orden en el cual se aplican los parches, a e reordenando las entradas en el chero series. Tambi n es posible colocar el chero series bajo control de revisiones; tambi n es favorable colocar todos los e e parches que reera bajo control de revisiones. Si crea un directorio de parches con la opci n -c de hg qinit, esto o se har autom ticamente. a a

B.2.2.

El chero status

El chero status contiene los nombres y los hashes de los conjuntos de cambios de todos los parches que MQ ha aplicado. A diferencia del chero series, este NO ha sido dise ado para ser editado. No debera colocar este chero n bajo el control de revisiones o modicarlo de forma alguna. MQ lo usa estrictamente para administraci n interna. o

183

Ap ndice C e

Instalar Mercurial desde las fuentes


C.1. En un sistema tipo Unix

Si usa un sistema tipo Unix que tiene una versi n sucientemente reciente de Python (2.3 o superior) disponible, o es f cil instalar Mercurial desde las fuentes. a 1. Descargue un paquete fuente reciente de http://www.selenic.com/mercurial/download. 2. Descomprmalo:
1

gzip -dc mercurial-version.tar.gz | tar xf -

3. Vaya al directorio fuente y ejecute el gui n de instalaci n. Esto armar Mercurial y lo instalar en su directorio o o a a casa:
1 2

cd mercurial-version python setup.py install --force --home=$HOME

Cuando termine la instalaci n, Mercurial estar en el subdirectorio bin de su directorio casa. No olvide asegurarse de o a que este directorio est presente en el camino de b squeda de su int rprete de ordenes. e u e Probablemente necesitar establecer la variable de ambiente PYTHONPATH de tal forma que los ejecutables de Mera curial puedan encontrar el resto de los paquetes de Mercurial. Por ejemplo, en mi port til, la estableca a /home/bos/lib/python. a La ruta exacta que usted use depender de como ha sido construdo Python en su sistema, pero debera ser f cil dea a ducirla. Si no est seguro, mire lo que haya mostrado el script en el paso anterior, y vea d nde se instalaron los a o contenidos del directorio mercurial se instalaron.

C.2.

En Windows

Armar e instalar Mercurial en Windows requiere una variedad de herramientas, cierta suciencia t cnica y paciene cia considerable. Personalmente, no le recomiendo hacerlo si es un usuario casual. A menos que intente hacer hacks a Mercurial, le recomiendo que mejor use un paquete binario. Si est decidido a construir Mercurial desde las fuentes en Windows, siga el camino difcil indicado en el wiki de a Mercurial en http://www.selenic.com/mercurial/wiki/index.cgi/WindowsInstall, y espere que el proceso sea realmente un trabajo duro.

184

Ap ndice D e

Licencia de Publicaci n Abierta o


Versi n 1.0, 8 Junio de 1999 o

D.1.

Requerimientos en versiones modicadas y no modicadas

Los trabajos bajo Publicaci n Abierta pueden reproducirse y distribuirse enteros o en porciones, en cualquier o medio fsico o electr nico, siempre y cuando se respeten los t rminos de esta licencia, y se incorpore esta licencia o o e su referencia (con cualquiera de las opciones elegidas por el autor y el editor) en la reproducci n. o A continuaci n mostramos la forma correcta de incorporar por referencia: o Copyright (c) a o por nombre del autor o designado. Este material puede distribuirse solamente bajo los n t rminos y condiciones especicados por la Licencia de Publicaci n Abierta, vx.y o posterior (la ultima e o versi n disponible est en http://www.opencontent.org/openpub/). o a La referencia debe estar seguida inmediatamente por cualquier opci n elegida por el(os) autor(es) y/o editor(es) o del documento (consulte la secci n D.6). o Se permite la redistribuci n comercial de los materiales sujetos a la Publicaci n Abierta. o o Cualquier publicaci n en forma est ndar de libro (papel) requerir citar al editor y autor original. Los nombres o a a del editor y el autor aparecer n en todas las supercies externas del libro. En todas las supercies externas el nombre a del editor deber aparecer en tama o de la misma medida que el ttulo del trabajo y ser citado como poseedor con a n a respecto al ttulo.

D.2.

Derechos de reproducci n o

El derecho de reproducci n de cada Publicaci n Abierta pertenece al(os) autor(es) o designados. o o

D.3.

Alcance de la licencia

Los t rminos de licencia dsecritos aplican a todos los trabajos bajo licencia de publicaci n abierta a menos que se e o indique de otra forma en este documento. La simple agregaci n de trabajos de Publicaci n Abierta o una porci n de trabajos de Publicaci n Abierta con otros o o o o trabajos o programas en el mismo medio no causar n que esta licencia se aplique a los otros trabajos. Los agregados a deber n contener una nota que especique la inclusi n de matrial de Publicaci n Abierta y una nota de derechos de a o o reproducci n acorde. o Separabilidad. Si cualquier porci n de esta licencia no es aplicable en alguna jurisdicci n, las porciones restantes o o se mantienen. 185

Sin garanta. Los trabajos de Publicaci n Abierta se licencian y ofrecen como est n sin garanta de ninguna o a clase, expresa o implcita, incluyendo, pero no limitados a las garantas de mercabilidad y adaptabilidad para un prop sito particular o garanta de no infracci n. o o

D.4.

Requerimientos sobre trabajos modicados

Todas las versiones modicadas de documentos cubiertos por esta licencia, incluyendo traducciones, antologas, compilaciones y documentos parciales, deben seguir estos requerimientos: 1. La versi n modicada debe estar etiquetada como tal. o 2. La persona que hace la modicaci n debe estar identicada y la modicaci n con fecha. o o 3. El dar cr dito al autor original y al editor si se requiere de acuerdo a las pr cticas acad micas de citas. e a e 4. Debe identicarse el lugar del documento original sin modicaci n. o 5. No puede usarse el(os) nombre(s) del autor (de los autores) para implicar relaci n alguna con el documento o resultante sin el permiso explcito del autor (o de los autores).

D.5.

Recomendaciones de buenas pr cticas a

Adicional a los requerimientos de esta licencia, se solicita a los redistribuidores y se recomienda en gran medida que: 1. Si est distribuyendo trabajaos de Publicaci n Abierta en copia dura o CD-ROM, enve una noticaci n por a o o correo a los autores acerca de su intenci n de redistribuir por lo menos con treinta das antes de que su manuscrito o o el medio se congelen, para permitir a los autores tiempo para proveer documentos actualizados. Esta noticaci n debera describir las modicaciones, en caso de que haya, al documento. o 2. Todas las modicaciones sustanciales (incluyendo eliminaciones) deben estar marcadas claramente en el documento o si no descritas en un adjunto del documento. 3. Finalmente, aunque no es obligatorio bajo esta licencia, se considera de buenos modales enviar una copia gratis de cualquier expresi n en copia dura o CD-ROM de un trabajo licenciado con Publicaci n Abierta a el(os) o o autor(es).

D.6.

Opciones de licencia

El(os) autor(es) y/o editor de un documento licenciado con Publicaci n Abierta pueden elegir ciertas opciones o a adiendo informaci n a la referencia o a la copia de la licencia. Estas opciones se consideran parte de la instancia de n o la licencia y deben incluirse con la licencia (o su incorporaci n con referencia) en trabajos derivados. o A Prohibir la distribuci n de versiones substancialmente modicadas sin el permiso explcito del(os) autor(es). Se o denen modicaciones substanciales como cambios en el contenido sem ntico del documento, y se excluyen a simples cambios en el formato o correcciones tipogr cas. a Para lograr esto, a ada la frase Se prohibe la distribuci n de versiones substancialmente modicadas de este n o documento sin el permiso explcito del due o de los derechos de reproducci n. a la referencia de la licencia o a la n o copia.

186

B Est prohibido prohibir cualquier publicaci n de este trabajo o derivados como un todo o una parte en libros est ndar a o a (de papel) con prop sitos comerciales a menos que se obtenga un permiso previo del due o de los derechos de o n reproducci n. o Para lograrlo, a ada la frase La distribuci n del trabajo o derivados en cualquier libro est ndar (papel) se prohibe n o a a menos que se obtenga un permiso previo del due o de los derechos de reproducci n. a la referencia de la licencia n o o la copia.

187

Bibliografa
[AG] [BI] [Bro] [Dic] [Dus] Jean Delvare Andreas Gruenbacher, Martin Quinson. Patchwork quilt. http://savannah.nongnu.org/ projects/quilt. Ronald Oussoren Bob Ippolito. Universal macpython. http://bob.pythonmac.org/archives/2006/04/ 10/python-and-universal-binaries-on-mac-os-x/. Neil Brown. wiggle/. wiggleapply conicting patches. http://cgi.cse.unsw.edu.au/neilb/source/

Thomas Dickey. diffstatmake a histogram of diff output. http://dickey.his.com/diffstat/ diffstat.html. Andy Dustman. Mysql for python. http://sourceforge.net/projects/mysql-python.

[Gru05] Andreas Gruenbacher. How to survive with many patches (introduction to quilt). http://www.suse.de/ agruen/quilt.pdf, June 2005. [Mas] Chris Mason. mpatchhelp solve patch rejects. http://oss.oracle.com/mason/mpatch/.

[OS06] Bryan OSullivan. Achieving high performance in mercurial. In EuroPython Conference, July 2006. XXX. [Pyt] [RS] [Tat] [Wau] Python.org. ConfigParserconguration module-ConfigParser.html. le parser. http://docs.python.org/lib/

GNU Project volunteers Richard Stallman. Gnu coding standardschange logs. http://www.gnu.org/ prep/standards/html_node/Change-Logs.html. Simon Tatham. Puttyopen source ssh client for windows. http://www.chiark.greenend.org.uk/ sgtatham/putty/. Tim Waugh. patchutils/. patchutilsprograms that operate on patch les. http://cyberelk.net/tim/

188

Indice alfab tico e


.hg/hgrc, chero, 73, 74, 110 .hg/localtags, chero, 84, 128, 129 .hg/patches.N , directorio, 152 .hg/patches, directorio, 143, 144, 153155, 178, 179 .hg/store/data, directorio, 36 .hgignore, chero, 155, 179 .hgrc, chero, 20, 35 .hgtags, chero, 83, 84, 128, 129 .orig, chero, 150 .rej, chero, 150, 151 .ssh/config, chero, 69 .ssh, directorio, 67, 68 EMAIL, variable de entorno, 20 HGMERGE, variable de entorno, 31, 33 HGUSER, variable de entorno, 20 HG NODE, variable de entorno, 112, 124 HG PARENT1, variable de entorno, 124 HG PARENT2, variable de entorno, 124 HG SOURCE, variable de entorno, 125 HG URL, variable de entorno, 124, 125 Mercurial.ini, chero de conguraci n, 66 o PATH, variable de entorno, 68 PYTHONPATH, variable de entorno, 68, 71, 115, 183 acl, extensi n, 117, 118, 168 o acl, gancho, 118 addbreaks, ltro de plantilla, 134 addremove, comando, 52, 149 add, comando, 44, 4951, 54, 58, 75, 77, 91, 92, 94, 146, 155, 159, 174, 179, 181 opci n --dry-run, 174 o opci n --exclude, 174 o opci n --include, 174 o opci n -I, 174 o opci n -n, 174 o opci n -X, 174 o age, ltro de plantilla, 134 annotate, comando, 142, 144, 145 authorized keys, chero, 67, 68 author, palabra clave de plantilla, 132, 134, 135 ltro domain, 134 ltro email, 134 ltro person, 135 ltro user, 135 backout, comando, 95102 opci n --merge, 96, 98, 101 o opci n -m, 96 o basename, ltro de plantilla, 134 bash, comando de sistema, 155 bisect, comando, 102108 bisect, extensi n, 2, 142 o branches, comando, 86 branches, palabra clave de plantilla, 132 branch, comando, 87, 88 bugzilla, extensi n, 119122, 168 o bugzilla, gancho, 119, 120 bundle, comando, 126 changegroup, gancho, 109, 112, 125128 chmod, comando de sistema, 70 clone, comando, 13, 18, 65, 73, 84 opci n -r, 84 o commit, comando, 1921, 30, 41, 49, 52, 86, 112, 116, 117, 153, 155, 158, 178, 180 opci n --addremove, 158 o opci n -A, 52 o opci n -l, 117 o opci n -u, 20 o commit, gancho, 109, 112, 113, 126, 127, 129 config, comando, 110 convert, comando (extensi n conver), 10 o convert, extensi n, 10 o conver, extensi n o comando convert, 10 copy, comando, 44, 5256, 95, 181 opci n --after, 55 o cp, comando, 54 cp, comando de sistema, 54 date, ltro de plantilla, 134 date, palabra clave de plantilla, 132, 134, 135 ltro age, 134 ltro date, 134 ltro hgdate, 134 ltro isodate, 134, 135 ltro rfc822date, 135 ltro shortdate, 135

189

desc, palabra clave de plantilla, 132, 135 diffstat, comando opci n -p, 155 o diffstat, comando de sistema, 155, 156, 173 diff, comando, 19, 21, 144, 148, 165, 168, 170, 171, 174178 opci n --exclude, 174 o opci n --git, 174176 o opci n --ignore-all-space, 176 o opci n --ignore-blank-lines, 174 o opci n --ignore-space-change, 175 o opci n --include, 174 o opci n --nodates, 174 o opci n --rev, 175 o opci n --show-function, 175 o opci n --text, 174 o opci n -a, 174, 177 o opci n -B, 174 o opci n -b, 175 o opci n -C, 171 o opci n -c, 171 o opci n -g, 175 o opci n -I, 174 o opci n -N, 148 o opci n -p, 175 o opci n -r, 148, 175, 176 o opci n -w, 176 o opci n -X, 174 o diff, comando de sistema, 140, 142, 148, 171 domain, ltro de plantilla, 134 email, comando (extensi n patchbomb), 173 o email, comando (extensi n patchbomb) o opci n --plain, 173 o opci n -a, 173 o opci n -b, 173 o opci n -d, 173 o opci n -f, 173 o opci n -m, 173 o opci n -n, 173 o opci n -s, 173 o email, ltro de plantilla, 134 escape, ltro de plantilla, 134 export, comando, 101 extdiff, comando (extensi n extdiff), 167, 171, 172 o extdiff, comando (extensi n extdiff) o opci n -o, 171 o opci n -p, 171 o extdiff, extensi n, 165167, 170172 o comando extdiff, 167, 171, 172 extdiff, extensi n o comando extdiff opci n-o, 171 o

opci n-p, 171 o fetch, comando, 35 fetch, comando (extensi n fetch), 168 o fetch, extensi n, 35, 168 o comando fetch, 168 ficheros, palabra clave de plantilla, 134 file adds, palabra clave de plantilla, 133 file dels, palabra clave de plantilla, 133 files, palabra clave de plantilla, 133 fill68, ltro de plantilla, 134 fill76, ltro de plantilla, 134 filterdiff, comando opci n --files, 159 o opci n --hunks, 159 o opci n -i, 158 o opci n -x, 158 o filterdiff, comando de sistema, 155, 156, 158, 159 firstline, ltro de plantilla, 134 foo, comando, 88 git, comando de sistema, 63, 175, 176 grep, comando de sistema, 105, 107 guards, chero, 162 header, palabra clave de plantilla, 139 heads, comando, 28 help, comando, 12, 13, 143, 178 hg-interdiff, chero, 166, 167 hgdate, ltro de plantilla, 134 hgext, extensi n, 167 o hgmerge, comando de sistema, 31, 33, 129 hgrc, chero secci n acl.allow, 118 o secci n acl.deny, 118 o secci n acl, 118 o entrada bundle, 118 entrada pull, 118 entrada push, 118 entrada serve, 118 entrada sources, 118 secci n bugzilla, 119, 121 o entrada db, 120 entrada host, 119 entrada notify, 120 entrada password, 120 entrada usermap, 120 entrada user, 120 entrada version, 119 secci n diff o entrada showfunc, 175 secci n extdiff, 172 o secci n extensions, 35, 165, 171 o secci n hooks, 112 o secci n notify, 122 o

190

entrada config, 122 entrada maxdiff, 123 entrada sources, 123 entrada strip, 122 entrada template, 123 entrada test, 122, 124 secci n ui o entrada username, 20 entrada verbose, 113 secci n usermap, 120, 122 o secci n web, 73, 74, 121, 123 o entrada accesslog, 74 entrada address, 74 entrada allow archive, 73 entrada allowpull, 73 entrada baseurl, 121, 123 entrada contact, 73 entrada description, 74 entrada errorlog, 74 entrada ipv6, 74 entrada maxchanges, 73 entrada maxfiles, 73 entrada motd, 74 entrada name, 74 entrada port, 74 entrada stripes, 73 entrada style, 73, 74 entrada templates, 74 hgrc, chero de conguraci n, 69, 73, 74, 90, 110112, o 114, 115, 118122, 131, 165, 167, 170172 hgweb.cgi, chero, 7074 hgweb.config, chero, 72, 74 hgwebdir.cgi, chero, 7274 hg, comando de sistema, 68 import, comando, 148, 177 incoming, comando, 22, 65, 110, 131 incoming, gancho, 109, 119, 125128 init, comando, 155, 178 inotify, extensi n, 168170 o comando inserve, 170 inserve, comando (extensi n inotify), 170 o interdiff, comando de sistema, 165167, 172 isodate, ltro de plantilla, 134, 135 kdiff3, comando de sistema, 31, 32, 172 locate, comando, 157 log, comando, 1418, 20, 21, 82, 83, 87, 88, 96, 131, 132, 142, 153 opci n --patch, 17 o opci n --rev, 16, 18 o opci n --template, 132, 135 o opci n -p, 17 o opci n -r, 16, 18 o

lsdiff comando de sistema, 158 lsdiff, comando de sistema, 156 mercurial.localrepo, m dulo o clase localrepository, 115, 124 mercurial.node, m dulo o funci n bin, 124 o mercurial.ui, m dulo o clase ui, 115, 124 merge, comando, 29, 35, 4042, 80, 90, 153, 176 merge, comando de sistema, 33, 34 mpatch, comando de sistema, 151 mq comando de sistema, 155 mq, comando de sistema, 155 mq, extensi n, 170, 172 o comando qapplied, 145, 146, 148, 155, 178 comando qcommit, 155, 178 comando qdelete, 178 comando qdiff, 178 comando qfold, 158, 178 comando qguard, 161, 162 comando qheader, 179 comando qimport, 149, 179 comando qinit, 143, 154, 178, 179, 182 comando qnew, 143, 145, 146, 149, 179 comando qnext, 179 comando qpop, 146, 147, 151, 153, 180 comando qprev, 180 comando qpush, 146, 147, 150153, 158, 162, 170, 179182 comando qrefresh, 144, 145, 147, 149, 151153, 156, 158, 179, 181 comando qrename, 181 comando qrestore, 181 comando qsave, 152, 181 comando qselect, 162 comando qseries, 145, 146, 148, 153, 181 comando qtop, 155, 156, 182 comando qunapplied, 182 mq, extensi n o comando qdel opci n-f, 178 o comando qfold opci n-e, 179 o opci n-l, 179 o opci n-m, 179 o comando qinit opci n-c, 154, 155, 178, 179, 182 o comando qnew opci n-f, 146, 179 o opci n-m, 179 o comando qpop opci n-a, 146, 151, 152, 155, 180 o

191

opci n-f, 146, 180 o opci n-n, 152, 180 o comando qpush opci n-a, 146, 151, 152, 155, 170, 180 o opci n-l, 181 o opci n-m, 152, 181 o opci n-n, 181 o comando qrefresh opci n-e, 181 o opci n-l, 181 o opci n-m, 181 o comando qsave opci n-c, 152 o opci n-e, 152 o node, palabra clave de plantilla, 133 ltro short, 135 notify, extensi n, 122124, 168 o obfuscate, ltro de plantilla, 135 outgoing, comando, 24, 131 outgoing, gancho, 109, 110, 126, 127 pageant, comando de sistema, 67, 68 parents, comando, 24, 29, 30, 40, 176 parents, palabra clave de plantilla, 133 patchbomb, extensi n, 165, 172, 173 o comando email, 173 patchbomb, extensi n o comando email opci n--plain, 173 o opci n-a, 173 o opci n-b, 173 o opci n-d, 173 o opci n-f, 173 o opci n-m, 173 o opci n-n, 173 o opci n-s, 173 o patchutils, paquete, 155, 165 patch comando de sistema, 149 patch, comando opci n --reverse, 101 o opci n -p, 148 o patch, comando de sistema, 101, 102, 140, 142, 148151, 177 perl, comando de sistema, 117 person, ltro de plantilla, 135 plink, comando de sistema, 66, 69 prechangegroup, gancho, 109, 125128 precommit, gancho, 109, 116, 126129 preoutgoing, gancho, 109, 112, 126, 127 pretag, gancho, 109, 128, 129 pretxnchangegroup, gancho, 90, 109, 111, 112, 118, 125 128

pretxncommit, gancho, 109, 111, 113116, 119, 126 128 preupdate, gancho, 109, 129 pull, comando, 2225, 28, 35, 41, 65, 73, 80, 88, 92, 110, 125, 128, 152, 155 opci n -u, 23, 24 o push, comando, 25, 80, 125, 126, 128 puttygen, comando de sistema, 67 putty, comando de sistema, 67 qapplied, comando (extensi n mq), 145, 146, 148, 155, o 178 qcommit, comando (extensi n mq), 155, 178 o qdelete, comando (extensi n mq), 178 o qdel, comando (extensi n mq) o opci n -f, 178 o qdiff, comando (extensi n mq), 178 o qfold, comando, 178 qfold, comando (extensi n mq), 158, 178 o qfold, comando (extensi n mq) o opci n -e, 179 o opci n -l, 179 o opci n -m, 179 o qguard, comando, 162 qguard, comando (extensi n mq), 161, 162 o qheader, comando (extensi n mq), 179 o qimport, comando (extensi n mq), 149, 179 o qinit, comando, 155, 178 qinit, comando (extensi n mq), 143, 154, 178, 179, 182 o qinit, comando (extensi n mq) o opci n -c, 154, 155, 178, 179, 182 o qnew, comando, 146 qnew, comando (extensi n mq), 143, 145, 146, 149, 179 o qnew, comando (extensi n mq) o opci n -f, 146, 179 o opci n -m, 179 o qnext, comando (extensi n mq), 179 o qpop, comando, 146, 151, 152, 155 qpop, comando (extensi n mq), 146, 147, 151, 153, 180 o qpop, comando (extensi n mq) o opci n -a, 146, 151, 152, 155, 180 o opci n -f, 146, 180 o opci n -n, 152, 180 o qprev, comando (extensi n mq), 180 o qpush, comando, 151, 152, 155 qpush, comando (extensi n mq), 146, 147, 150153, 158, o 162, 170, 179182 qpush, comando (extensi n mq) o opci n -a, 146, 151, 152, 155, 170, 180 o opci n -l, 181 o opci n -m, 152, 181 o opci n -n, 181 o

192

qrefresh, comando (extensi n mq), 144, 145, 147, 149, o 151153, 156, 158, 179, 181 qrefresh, comando (extensi n mq) o opci n -e, 181 o opci n -l, 181 o opci n -m, 181 o qrename, comando (extensi n mq), 181 o qrestore, comando (extensi n mq), 181 o qsave, comando, 152 qsave, comando (extensi n mq), 152, 181 o qsave, comando (extensi n mq) o opci n -c, 152 o opci n -e, 152 o qselect, comando (extensi n mq), 162 o qseries, comando (extensi n mq), 145, 146, 148, 153, o 181 qtop, comando (extensi n mq), 155, 156, 182 o qunapplied, comando (extensi n mq), 182 o remove, comando, 44, 51, 52, 56, 76, 94, 159, 181 opci n --after, 52 o rename, comando, 44, 55, 56, 80, 95, 181 opci n --after, 56 o revert, comando, 52, 58, 9395, 101, 145 rev, palabra clave de plantilla, 133 rfc822date, ltro de plantilla, 135 rollback, comando, 91, 92, 102 root, comando, 76 sed, comando de sistema, 19 series, chero, 144, 152, 155, 162, 164, 178182 serve, comando, 59, 60, 65, 73, 74 opci n -p, 65 o shortdate, ltro de plantilla, 135 short, ltro de plantilla, 135 ssh-add, comando de sistema, 67, 68 ssh-agent, comando de sistema, 67 ssh-keygen, comando de sistema, 67 ssh, comando opci n -C, 69 o ssh, comando de sistema, 42, 60, 6669 status, comando, 19, 21, 49, 5153, 55, 76, 87, 91, 95, 101, 168, 169, 176, 181 opci n -C, 53, 55 o status, chero, 144, 152, 155, 179, 180, 182 strip, comando, 152, 182 opci n -b, 182 o opci n -f, 182 o opci n -n, 182 o strip, ltro de plantilla, 135 sudo apt-get install mercurial-py25, comando de sistema, 12 sudo port install mercurial, comando de sistema, 12

sudo, comando de sistema, 121 tabindent, ltro de plantilla, 134, 135 tabindent, palabra clave de plantilla, 135 tags, comando, 82, 83 tags, palabra clave de plantilla, 133 tag, comando, 61, 81, 83, 84 opci n -f, 83 o opci n -l, 84 o tag, gancho, 109, 128, 129 tar, comando de sistema, 73 tip, comando, 21, 23, 87, 131, 156 opci n -p, 156 o transplant, extensi n, 172 o unbundle, comando, 125, 128 update, comando, 23, 24, 29, 35, 40, 61, 80, 8890, 101, 152, 155 opci n -C, 88, 152 o update, gancho, 110, 129 urlescape, ltro de plantilla, 135 user, ltro de plantilla, 135 version, comando, 12, 68, 176 vim, comando de sistema, 172 wiggle, comando de sistema, 151 zip, comando de sistema, 73 Base de datos de fallos de Mercurial fallo 29, 57 fallo 311, 149 chero de conguraci n o Mercurial.ini (Windows), 66 hgrc (Linux/Unix), 69, 73, 74, 90, 110112, 114, 115, 118122, 131, 165, 167, 170172 ltros de plantilla addbreaks, 134 age, 134 basename, 134 date, 134 domain, 134 email, 134 escape, 134 fill68, 134 fill76, 134 firstline, 134 hgdate, 134 isodate, 134, 135 obfuscate, 135 person, 135 rfc822date, 135 shortdate, 135 short, 135 strip, 135

193

tabindent, 134, 135 urlescape, 135 user, 135 ganchos acl, 118 bugzilla, 119, 120 changegroup, 109, 112, 125128 commit, 109, 112, 113, 126, 127, 129 incoming, 109, 119, 125128 outgoing, 109, 110, 126, 127 prechangegroup, 109, 125128 precommit, 109, 116, 126129 preoutgoing, 109, 112, 126, 127 pretag, 109, 128, 129 pretxnchangegroup, 90, 109, 111, 112, 118, 125 128 pretxncommit, 109, 111, 113116, 119, 126128 preupdate, 109, 129 tag, 109, 128, 129 update, 110, 129 opciones globales opci n --debug, 68, 118 o opci n --exclude, 79 o opci n --include, 79 o opci n --quiet, 18 o opci n --verbose, 13, 17, 18 o opci n -I, 79 o opci n -q, 18, 77 o opci n -v, 13, 17, 18, 65, 77, 113 o opci n -X, 79 o palabras clave de plantilla author, 132, 134, 135 branches, 132 date, 132, 134, 135 desc, 132, 135 ficheros, 134 file adds, 133 file dels, 133 files, 133 header, 139 node, 133 parents, 133 rev, 133 tabindent, 135 tags, 133 tags tip, 125, 128 special tag names qbase, 153

qtip, 153 variables de entorno EMAIL, 20 HGMERGE, 31, 33 HGUSER, 20 HG NODE, 112, 124 HG PARENT1, 124 HG PARENT2, 124 HG SOURCE, 125 HG URL, 124, 125 PATH, 68 PYTHONPATH, 68, 71, 115, 183

194

También podría gustarte