Está en la página 1de 204

Control Distribuido de Revisiones con Mercurial

Bryan OSullivan Copyright c 2006, 2007 Bryan OSullivan. nicamente bajo los t Este material puede distribuirse u erminos y condiciones establecidos en la versi on 1.0 de la Licencia de Publicaci on Abierta (OPL). Re erase por favor al ap endice D para 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 oneste libro es Libre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1. Introducci on 1.1. Acerca del control de revisiones . . . . . . . . . . . . . 1.1.1. Por qu e usar control de revisiones? . . . . . . . 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 odigo abierto . . . . 1.4.2. Ventajas para proyectos comerciales . . . . . . . 1.5. Por qu e elegir Mercurial? . . . . . . . . . . . . . . . . 1.6. Comparaci on de Mercurial con otras herramientas . . . . 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 asico 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 e hay en un repositorio? . . . . . . . . . . . . . . . . . . . . . . . . 2.4. Vistazo r apido al historial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4.1. Conjuntos de cambios, revisiones, y comunic andose con otras personas 2.4.2. Ver revisiones espec cas . . . . . . . . . . . . . . . . . . . . . . . . 2.4.3. Informaci on m as detallada . . . . . . . . . . . . . . . . . . . . . . . .
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 on . . . 2.7.3. Escribir un buen mensaje de consignaci on 2.7.4. Cancelar una consignaci on . . . . . . . . 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 es de una red . . 3. Una gira de Mercurial: fusionar trabajo 3.1. Fusionar l neas de trabajo . . . . . . . . . . . . . 3.1.1. Conjuntos de cambios de frentes . . . . . 3.1.2. Hacer la fusi on . . . . . . . . . . . . . . 3.1.3. Consignar los resultados de la fusi on . . . 3.2. Fusionar cambios con conictos . . . . . . . . . 3.2.1. Usar una herramienta gr aca para fusi on 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 . . . . . . . . . . . . nico chero . . . . . . 4.1.1. Seguir el historial de un u 4.1.2. Administraci on de cheros monitoreados . . . . 4.1.3. Registro de informaci on del conjunto de cambios 4.1.4. Relaciones entre revisiones . . . . . . . . . . . . 4.2. Almacenamiento seguro y eciente . . . . . . . . . . . . 4.2.1. Almacenamiento eciente . . . . . . . . . . . . 4.2.2. Operaci on segura . . . . . . . . . . . . . . . . . 4.2.3. Recuperaci on r apida de datos . . . . . . . . . . 4.2.4. Identicaci on e integridad fuerte . . . . . . . . . 4.3. Historial de revisiones, ramas y fusiones . . . . . . . . . 4.4. El directorio de trabajo . . . . . . . . . . . . . . . . . . 4.4.1. Qu e pasa en una consignaci on . . . . . . . . . . 4.4.2. Creaci on de un nuevo frente . . . . . . . . . . . 4.4.3. Fusi on de frentes . . . . . . . . . . . . . . . . . 4.5. Otras caracter sticas de dise no interesantes . . . . . . . . 4.5.1. Compresi on ingeniosa . . . . . . . . . . . . . . 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 d a a d a 5.1. C omo indicarle a Mercurial qu e cheros seguir . . . . . . . . 5.1.1. Nombramiento expl cito e impl cito de cheros . . . . 5.1.2. Nota al margen: Mercurial trata cheros, no directorios 5.2. C omo dejar de hacer seguimiento a un chero . . . . . . . . .
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 e decirle expl citamente a Mercurial que elimine un chero? tilagregar y eliminar cheros en un solo paso . . . . . . . . . . . . . . . . 5.2.4. Atajo u 5.3. Copiar cheros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.1. Resultados de copiar un chero durante una fusi on . . . . . . . . . . . . . . . . . . 5.3.2. Por qu e los cambios se reejan en las copias? . . . . . . . . . . . . . . . . . . . . 5.3.3. C omo hacer que los cambios no sigan a la copia? . . . . . . . . . . . . . . . . . . . 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 on . . . . . . . . . . . . . . . . . . . . . . . 5.4.3. Cambios de nombre convergentes y fusi on . . . . . . . . . . . . . . . . . . . . . . 5.4.4. Otros casos l mite relacionados con renombramientos . . . . . . . . . . . . . . . . . 5.5. Recuperarse de equivocaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6. Colaborar con otros 6.1. La interfaz web de Mercurial . . . . . . . . . . . . . . . . . . . . . . . 6.2. Modelos de colaboraci on . . . . . . . . . . . . . . . . . . . . . . . . . 6.2.1. Factores a tener en cuenta . . . . . . . . . . . . . . . . . . . . 6.2.2. Anarqu a informal . . . . . . . . . . . . . . . . . . . . . . . . nico . . . . . . . . . . . . . . . . . . . 6.2.3. Un repositorio central u 6.2.4. Trabajo con muchas ramas . . . . . . . . . . . . . . . . . . . . 6.2.5. Ramas de caracter sticas . . . . . . . . . . . . . . . . . . . . . 6.2.6. El tren de publicaci on . . . . . . . . . . . . . . . . . . . . . . 6.2.7. El modelo del kernel Linux . . . . . . . . . . . . . . . . . . . . 6.2.8. Solamente jalar frente a colaboraci on p ublica . . . . . . . . . . 6.2.9. Cuando la colaboraci on encuentra la administraci on ramicada 6.3. Aspectos t ecnicos de la colaboraci on . . . . . . . . . . . . . . . . . . . 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 omo leer y escribir URLs de ssh . . . . . . . . . . . . . . . . 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 on . . . . . . . . . . . . . . . . 6.5.5. Congurar el lado del servidor apropiadamente . . . . . . . . . 6.5.6. Compresi on con ssh . . . . . . . . . . . . . . . . . . . . . . . 6.6. Servir sobre HTTP usando CGI . . . . . . . . . . . . . . . . . . . . . . 6.6.1. Lista de chequeo de la conguraci on del servidor web . . . . . 6.6.2. Conguraci on b asica de CGI . . . . . . . . . . . . . . . . . . . 6.6.3. Compartir varios repositorios con un gui on CGI . . . . . . . . . 6.6.4. Descarga de cheros fuente . . . . . . . . . . . . . . . . . . . 6.6.5. Opciones de conguraci on en Web . . . . . . . . . . . . . . . . 7. Nombres de cheros y asociaci on de patrones 7.1. Nombrado de cheros simple . . . . . . . . . . . . . . . . . 7.2. Ejecuci on de comandos sin ning un nombre de chero . . . . 7.3. Reportar que est a pasando . . . . . . . . . . . . . . . . . . 7.4. Uso de patrones para identicar cheros . . . . . . . . . . . 7.4.1. Patrones glob estilo int erprete . . . . . . . . . . . . 7.4.2. Asociaci on con patrones de expresiones regulares re
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 usculas . . . . . . . . . . . . . . . . . 7.7.1. Almacenamiento portable y seguro de repositorios 7.7.2. Detecci on de conictos de may usculas/min usculas 7.7.3. Arreglar un conicto de may usculas/min usculas .

. . . . . .

. . . . . .

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 on de versiones y desarrollo ramicado 8.1. Dar un nombre persistente a una revisi on . . . . . . . . . . . . 8.1.1. Manejo de conictos entre etiquetas durante una fusi on 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 no . . . . . . 8.3. Administrar ramas en repositorios estilo gran cuadro . . . . . 8.4. No repita trabajo: fusi on entre ramas . . . . . . . . . . . . . . 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 . . . . . . . . . . . . . . . . . . til nombrar ramas . . . . . . . . . . . . . . 8.8. Normalmente es u 9. Encontrar y arreglar sus equivocaciones 9.1. Borrar el historial local . . . . . . . . . . . . . . . . . . 9.1.1. La consignaci on accidental . . . . . . . . . . . . 9.1.2. Hacer rollback una transacci on . . . . . . . . . . 9.1.3. Erroneamente jalado . . . . . . . . . . . . . . . 9.1.4. Despu es de publicar, un roll back es futil . . . . 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 as control sobre el proceso de retroceso . . . . 9.3.5. Por qu e hg backout hace lo que hace . . . . . 9.4. Cambios que nunca debieron ocurrir . . . . . . . . . . . 9.4.1. C omo protegerse de cambios que han escapado 9.5. Al encuentro de la fuente de un fallo . . . . . . . . . . . 9.5.1. Uso de la orden hg bisect . . . . . . . . . . 9.5.2. Limpieza despu es de la b usqueda . . . . . . . . 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 usqueda perezosamente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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 cr ticos sean ejecutados . . . . . . . . . . . . . . . . . . . 10.3. Precauciones con ganchos pretxn en un repositorio de acceso compartido . . . . . . . . . . . 10.3.1. Ilustraci on del problema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.4. Tutorial corto de uso de ganchos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.4.1. Llevar a cabo varias acciones por evento . . . . . . . . . . . . . . . . . . . . . . . . . 10.4.2. Controlar cu ando puede llevarse a cabo una actividad . . . . . . . . . . . . . . . . . . 10.5. Escribir sus propios ganchos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.5.1. Escoger c omo debe ejecutarse su gancho . . . . . . . . . . . . . . . . . . . . . . . . 10.5.2. Par ametros para ganchos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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 on signicativos . . . . . . . . . . . . . . . . . . . . 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 on con Bugzilla . . . . . . . . . . . . . . . . . . . . . . . . . . 10.7.3. notifyenviar noticaciones de correo electr onico . . . . . . . . . . . . . . . . . . 10.8. Informaci on para escritores de ganchos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.8.1. Ejecuci on de ganchos internos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.8.2. Ejecuci on de ganchos externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.8.3. Averiguar de d onde vienen los conjuntos de cambios . . . . . . . . . . . . . . . . . . 10.9. Referencia de ganchos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.9.1. changegroupluego de a nadir conjuntos de cambios remotos . . . . . . . . . . . . . 10.9.2. commitluego de la creaci on de un nuevo conjunto de cambios . . . . . . . . . . . . 10.9.3. incomingluego de que un conjunto de cambios remoto es a nadido . . . . . . . . . 10.9.4. outgoingluego de la propagaci on de los conjuntos de cambios . . . . . . . . . . . 10.9.5. prechangegroupantes de empezar la adici on de conjuntos de cambios remotos . . 10.9.6. precommitantes de iniciar la consignaci on de un conjunto de cambios . . . . . . . 10.9.7. preoutgoingantes de empezar la propagaci on de conjuntos de cambios . . . . . . 10.9.8. pretagantes de etiquetar un conjunto de cambios . . . . . . . . . . . . . . . . . . 10.9.9. pretxnchangegroupantes de completar la adici on de conjuntos de cambios remotos 10.9.10.pretxncommitantes de completar la consignaci on de un nuevo conjunto de cambios 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 asicas de plantillas . . . . . . . . 11.4. Palabras claves m as comunes en las plantillas 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 as sencillos . 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 nica un repositorio . . . . 11.8.2. Identicar de forma u 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 on de cambios con Colas de Mercurial 12.1. El problema de la administraci on de parches . . . . . . . . . . . . . . . 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 omo saltarlas . . . . . . . . . . . . . 12.5.7. Trabajar con varios parches a la vez . . . . . . . . . . . . . . . 12.6. M as acerca de parches . . . . . . . . . . . . . . . . . . . . . . . . . . 12.6.1. La cantidad de franjas . . . . . . . . . . . . . . . . . . . . . . 12.6.2. Estrategias para aplicar parches . . . . . . . . . . . . . . . . . 12.6.3. Algunos detalles de la representaci on de parches . . . . . . . . 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 odigo cambia . . . . . . . . . . . . . . 12.9. Identicar parches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . til . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.10.Otra informaci on u 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 acticas de trabajo con parches . . . . . . . . . . . . . . . . . 12.14.Recetas de MQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.14.1.Administrar parches triviales . . . . . . . . . . . . . . . . . . 12.14.2.Combinar parches completos . . . . . . . . . . . . . . . . . . . 12.14.3.Fusionar una porci on de un parche dentro de otro . . . . . . . . 12.15.Diferencias entre quilt y MQ . . . . . . . . . . . . . . . . . . . . . . . 13. Usos avanzados de las Colas de Mercurial 13.1. El problema de m ultiples objetivos . . . . . . . . . . . . . . . . . . . 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

. . . . . . . . . .

tiles para hacer desarrollo con MQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 13.9. Consejos u 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 no con la extensi on inotify . . . . . . . . . 14.2. Soporte exible de diff con la extensi on extdiff . . . . . . . . . 14.2.1. Denici on de alias de comandos . . . . . . . . . . . . . . 14.3. Uso de la extensi on transplant para seleccionar . . . . . . . . . 14.4. Enviar cambios v a correo electr onico con la extensi on patchbomb 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 nade cheros en la pr oxima consignaci on . . . . . . . . . . . . . A.2. hg diffimprime los cambios en el historial o el directorio actual . . . . . A.2.1. Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.3. hg versionimprime la informaci on de versi on y derechos de reproducci on A.3.1. Consejos y trucos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B. Referencia de las Colas de Mercurial rdenes MQ . . . . . . . . . . . . . . . . . . . . . . . . . . . B.1. Referencia de o 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 . . . . . . . ltimo parche aplicado . . . B.1.4. hg qdiffimprimir la diferencia del u B.1.5. hg qfoldfusionar (integrar) varios parches en uno solo . . . . B.1.6. hg qheaderdesplegar el encabezado/descripci on de un parche . 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 oximo parche . . . . . . . . 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 . . . . . . . . . . . . . . . ltimo parche aplicado . . . . . . . . . B.1.14. hg qrefreshactualiza el u 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 un no se han aplicado B.1.21. hg stripremover una revisi on y sus descendientes . . . . . . . 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 on Abierta D.1. Requerimientos en versiones modicadas y no modicadas D.2. Derechos de reproducci on . . . . . . . . . . . . . . . . . D.3. Alcance de la licencia . . . . . . . . . . . . . . . . . . . . D.4. Requerimientos sobre trabajos modicados . . . . . . . . D.5. Recomendaciones de buenas pr acticas . . . . . . . . . . . D.6. Opciones de licencia . . . . . . . . . . . . . . . . . . . . Bibliograf a Indice alfab etico

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

185 185 185 185 186 186 186 188 188

VIII

Indice de guras
2.1. Historial gr aco del repositorio hello . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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 es de jalar my-hello a my-new-hello . . . . . Directorio de trabajo y repositorio durante la fusi on, y consignaci on consecuente 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 on entre cheros en el directorio de trabajo y cheros de registro en el repositorio Relaciones entre metadatos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Instant anea de un revlog, con deltas incrementales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . El directorio de trabajo puede tener dos padres . . . . . . . . . . . . . . . . . . . . . . El directorio de trabajo obtiene nuevos padres luego de una consignaci on . . . . . . . El directorio de trabajo, actualizado a un conjunto de cambios anterior . . . . . . . . . Despu es de una consignaci on hecha mientras se usaba un conjunto de cambios anterior Fusi on de dos frentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5.1. Simular un directorio vac o con un chero oculto . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.1. Ramas de Caracter sticas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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 on manual de un retroceso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

10.1. Un gancho simple que se ejecuta al hacer la consignaci on de un conjunto de cambios 10.2. Denici on de un segundo gancho commit . . . . . . . . . . . . . . . . . . . . . . . 10.3. Uso del gancho pretxncommit para controlar consignaciones . . . . . . . . . . . . 10.4. Un gancho que proh be mensajes de consignaci on demasiado cortos . . . . . . . . . 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 on . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 rdenes diff y patch . . . . . . . . . 12.1. Uso sencillo de las o 12.2. L neas a a nadir en /.hgrc para habilitar la extensi on MQ 12.3. C omo vericar que MQ est a habilitado . . . . . . . . . . . 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 es del primero . . . . . . . . . . . . . . . 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 caracter sticas de etiquetamiento al trabajar con MQ . . rdenes diffstat, filterdiff, y lsdiff . . . . . . . . . . 12.15.Las o

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

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 gu a de campo. Escog escribir acerca de Mercurial porque es la herramienta m as f acil para explorar 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

til a otros. Tambi Estoy liberando este libro mientras lo sigo escribiendo, con la esperanza de que pueda ser u en espero que los lectores contribuir an como consideren adecuado.

0.2.

Acerca de los ejemplos en este libro

Este libro toma un enfoque inusual hacia las muestras de c odigo. Cada ejemplo est a en directocada uno es 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 odigo fuente, todos los scripts de ejemplo son ejecutados autom aticamente, y 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 on de Mercurial que es mencionada en la portada del libro. Si yo actualizo la versi on de Mercurial que estoy documentando, y la salida de alg un comando cambia, la construcci on falla. Hay una peque na desventaja de este enfoque, que las fechas y horas que usted ver a en los ejemplos tienden a estar aplastadas juntas de una forma que no ser a posible si los mismos comandos fueran escritos por un humano. Donde un humano puede emitir no m as de un comando cada pocos segundos, con cualquier marca de tiempo resultante 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 on 9.5, por ejemplo. As que cuando usted lea los ejemplos, no le d e mucha importancia a las fechas o horas que vea en las salidas de los comandos. Pero tenga conanza en que el comportamiento que est a viendo es consistente y reproducible.

0.3.

Colof oneste libro es Libre

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

Cap tulo 1

Introducci on
1.1. Acerca del control de revisiones

El control de revisiones es el proceso de administrar diferentes versiones de una pieza de informaci on. En su forma m as simple es algo que la mayor a de gente hace a mano: cada vez que usted modica un chero, lo graba con un nuevo nombre que contiene un n umero, cada uno mayor que el anterior. Administrar manualmente muchas versiones de incluso s olo un chero es una tarea propensa a errores, a pesar de 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 ecadas pasadas, el 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 e usar control de revisiones?

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

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 l, el fracaso est tiene en cuenta, puesto que sin e a casi garantizado. Por otra parte, un arreglo r apido de una sola persona, excluir a la necesidad de usar una herramienta de control de revisiones, porque casi seguramente, el costo de usar una estar a cerca del costo del proyecto. No es as ? nica. Puede aprender lo b Mercurial soporta ambas escalas de de desarrollo de manera u asico en pocos minutos, y dado su bajo sobrecosto, puede aplicar el control de revisiones al proyecto m as peque no con facilidad. Su simplicidad rdenes compitiendo por espacio signica que no tendr a que preocuparse por conceptos obtusos o secuencias de o mental con lo que sea que realmente est e tratando de hacer. Al mismo tiempo, Mercurial tiene alto desempe no y su 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 on de 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

nico. A continuaci El control de revisiones es un campo amplio, tan amplio que no hay un acr onimo o nombre u on presentamos un listado de nombres comunes y acr onimos que se podr an encontrar: Control de revisiones (RCS) Manejo de Conguraciones de Programas (SCM), o administrac on de conguraciones Administraci on de c odigo fuente Control de C odigo Fuente, o Control de Fuentes Control de Versiones (VCS) Algunas personas aducen que estos t erminos tienen signicados diversos, pero en la pr actica se sobreponen tanto que 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 as antigua conocida es SCCS (Sistema de Control de C odigo), escrito por Marc Rochkind en Bell Labs, a comienzos de los setentas (1970s). SCCS operaba sobre cheros individuales, y requer a que cada persona que trabajara en el proyecto tuviera acceso a un espacio compartido en un solo sistema. Solamente una persona pod a modicar un chero en un momento dado; el arbitramiento del acceso a los cheros se hac a con candados. Era com un que la gente pusiera los candados a los cheros, y que posteriormente olvidara quitarlos, impidiendo que otro pudiera modicar los cheros en cuesti on sin la intervenci on del administrador. Walter Tichy desarroll o una alternativa gratuita a SCCS a comienzos de los ochentas (1980s); llam o a su programa RCS (Sistema de Control de Revisiones). Al igual que SCCS, RCS requer a que los desarrolladores trabajaran en nico espacio compartido y colocaran candados a los cheros para evitar que varias personas los modicaran un u simult aneamente. Despu es en los ochenta, Dick Grune us o RCS como un bloque de construcci on para un conjunto de guiones de l nea de comando, que inicialmente llam o cmt, pero que renombr o a CVS (Sistema Concurrente de Versiones). La gran innovaci on de CVS era que permit a a los desarrolladores trabajar simult aneamente de una forma m as o menos independiente en sus propios espacios de trabajo. Los espacios de trabajo personales imped an que los desarrolladores se pisaran las mangueras todo el tiempo, situaci on com un con SCCS y RCS. Cada desarrollador ten a una copia de todos los cheros del proyecto y pod a modicar sus copias independientemente, Ten an que fusionar sus ediciones antes de consignar los cambios al repositorio central. Brian Berliner tom o los scripts originales de Grune y los reescribi o en C, publicando en 1989 el c odigo sobre el cual se ha desarrollado la versi on moderna de CVS. CVS adquiri o posteriormente la habilidad de operar sobre una conexi on de red, dot andolo de una arquitectura, cliente/servidor. La arquitectura de CVS es centralizada; el historial nicamente en el repositorio central. Los espacios de trabajo de los clientes contienen u nicamente del proyecto est au 4

copias recientes de las versiones de los cheros, y pocos metadatos para indicar d onde est a el servidor. CVS ha tenido xito enorme; Es probablemente el sistema de control de revisiones m un e as extendido del planeta. 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 on de repositorio central. (CVS se basaba en RCS para el almacenamiento de su historial; TeamWare usaba SCCS.) A medida que avanzaba la decada de los noventa, se empez o a evidenciar los problemas de CVS. Almacena nica y cambios simult aneos a muchos cheros de forma individual, en lugar de agruparlos como una operaci on u at omica l ogicamente. No maneja bien su jerarqu a de cheros; es f acil desordenar un repositorio al renombrar cheros y directorios. Peor a un, su c odigo fuente es dif cil de leer y mantener, lo que hizo que su umbral de dolor para arreglar sus problemas arquitecturales fuera algo prohibitivo. En 2001, Jim Blandy y Karl Fogel, dos desarrolladores que hab an trabajado en CVS, comenzaron un proyecto para reemplazarlo con una herramienta con mejor arquitectura y c odigo m as limpio. El resultado, Subversion, no se separ o del modelo centralizado cliente/servidor de CVS, pero a nadi o consignaciones at omicas de varios cheros, mejor manejo de espacios de nombres , y otras caracter sticas que lo hacen mejor que CVS. Desde su versi on inicial, ha ido creciendo en popularidad r apidamente. M as o menos en forma simult anea Graydon Hoare comenz o a trabajar en un ambicioso sistema distribuido de control de versiones que llam o Monotone. Mientras que Monotone se enfocaba a evitar algunas fallas de dise no de CVS con una arquitectura peer-to-peer, fue mucho m as all a de las herramientas anteriores (y posteriores) de control de revisiones en varios aspectos innovadores. Usa hashes criptogr acos como identicadores, y tiene una noci on integral de conanza para c odigo de diversas fuentes. Mercurial naci o en el 2005. Algunos de sus aspectos de de dise no fueron inuenciados por Monotone, pero Mercurial 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 ecadas pasadas, mientras la gente se ha hecho familiar con las capacidades de sus herramientas y se ha visto restringida por sus limitaciones. La primera generaci on comenz o administrando cheros individuales en computadores por persona. A pesar de que tales herramientas representaron un avance importante frente al control de revisiones manual, su modelo de candados y la dependencia a un s olo computador los limit o a equipos de trabajo peque nos y acoplados. La segunda generaci on dej o atr as esas limitaciones movi endose a arquitecturas centradas en redes, y administrando proyectos completos a la vez. A medida que los proyectos crec an, nacieron nuevos problemas. Con la necesidad de comunicaci on frecuente con los servidores, escalar estas m aquinas se convirti o en un problema en proyectos realmente grandes. Las redes con poca estabilidad podr an impedir que usuarios remotos se conectaran al servidor. A medida que los proyectos de c odigo abierto comenzaron a ofrecer acceso de s olo lectura de forma an onima a cualquiera, la gente sin permiso para consignar vio que no pod an usar tales herramientas para interactuar en un proyecto de forma natural, puesto que no pod an guardar sus cambios. La generaci on actual de herramientas de control de revisiones es peer-to-peer por naturaleza. Todos estos sistemas nico servidor central, y han permitido que la gente distribuya sus datos de control han eliminado la dependencia de un u de revisiones donde realmente se necesita. La colaboraci on a trav es de Internet ha cambiado las limitantes tecnol ogicas por la cuesti on de elecci on y consenso. Las herramientas modernas pueden operar sin conexi on indenidamente y aut onomamente, necesitando una conexi on de red solamente para sincronizar los cambios con otro repositorio.

1.4.

Algunas ventajas del control distribuido de revisiones

A pesar de que las herramientas para el control distribuido de revisiones lleva varios a nos siendo tan robustas y usables como la generaci on previa de sus contrapartes, algunas personas que usan las herramientas m as antiguas no 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 as r apidas que las centralizadas. Por una raz on sencilla: Una herramienta centralizada necesita comunicarse por red para las operaciones m as usuales, 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 as de la misma forma, comunicarse por red tiene un sobrecosto en una herramienta centralizada. No subestime el valor de una herramienta de respuesta r apida: Usted emplear a mucho 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 on de metadatos en tantos lugares. Si usa un sistema centralizado y su servidor explota, ojal a los medios ltima copia sea reciente y adem f sicos de su copia de seguridad sean conables, y que su u as funcione. Con una herramienta distribuida tiene tantas copias de seguridad disponibles como computadores de contribuidores. La conabilidad de su red afectar a las herramientas distribuidas de una forma mucho menor que a las herramientas centralizadas. Usted no puede siquiera usar una herramienta centralizada sin conexi on de red, excepto por algunas rdenes muy limitadas. Con herramientas distribuidas, si sus conexi o on cae mientras usted est a trabajando, podr a nico que que no podr nisiquiera darse cuenta. Lo u a hacer es comunicarse con repositorios en otros computadores, algo 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 odigo abierto

l, y ese proyecto usa una Si descubre un proyecto de c odigo abierto y decide que desea comenzar a trabajar en e 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 olo lectura a menos que alguien le otorgue permisos para consignar cambios en el repositorio central. Hasta entonces, no podr a almacenar sus cambios y sus modicaciones locales correr an el riesgo de da narse cuando trate de actualizar su vista del repositorio. 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 odigo abierto, puesto que se vuelve muy sencillo hacer una bifurcaci on1 del desarrollo del proyecto. Una bifurcaci on sucede cuando hay diferencias de opini on o actitud entre grupos de desarrolladores que desemboca en la decisi on de la imposibilidad de continuar trabajando juntos. Cada parte toma una copia m as o menos completa del c odigo fuente del proyecto y toma su propio rumbo. En algunas ocasiones los l deres de las bifurcaciones reconcilian sus diferencias. Con un sistema centralizado de control de revisiones, el proceso t ecnico de reconciliarse es doloroso, y se hace de forma muy manual. Usted tiene que rbol de alguna manera. decidir qu e historial de revisiones va a ganar, e injertar los cambios del otro equipo en el a Con esto usualmente se pierde algo o todo del historial de la revisi on de alguna de las partes. Lo que las herramientas distribuidas hacen con respecto a las bifurcaciones, es que las bifurcaciones son la u nica forma de desarrollar un proyecto. Cada cambio que usted hace es potencialmente un punto de bifurcaci on. La gran fortaleza de esta aproximaci on es que las herramientas distribuidas de control de revisiones tiene que ser bueno al 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 erminos de bifurcaciones y fusiones, entonces a aquello a lo que se reere en el mundo del c odigo abierto a una bifurcaci on se convierte puramente en una cuesti on social. Lo que hacen las herramientas distribuidas es disminuir la posibilidad de una bifurcaci on porque: Eliminan la distinci on social que imponen las herramientas centralizadas: aqu ella entre miembros (personas con permiso de consignar) y forasteros (los que no tienen el permiso). Facilitan la reconciliaci on despu es de una bifurcaci on social, porque todo lo que concierne al programa de control de revisiones es una fusi on.
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 a impidiendo la uidez de colaboraci on en lugar de prevenir que alguien se sienta impulsado a obtener una copia y hacer una bifurcaci on con su historial.

1.4.2.

Ventajas para proyectos comerciales

Muchos proyectos comerciales tienen grupos de trabajo distribuidos alrededor del globo. Quienes contribuyen y est an lejos de un repositorio central ver an una ejecuci on m as lenta de los comandos y tal vez menos conabilidad. Los sistemas de control de revisi on comerciales intentan amortiguar estos problemas con adiciones de replicaci on remota que usualmente son muy costosos y complicados de administrar. Un sistema distribuido no padece estos problemas. Mejor a un, puede colocar varios servidores autorizados, por ejemplo, uno por sitio, de tal forma que no haya comunicaci on redundante entre repositorios sobre enlaces de conexi on costosos. 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 t picas de replicaci on tienden a ser costosas y complejas de instalar y administrar. Dado que la carga en un servidor centralsi es que tiene unoes muchas veces menor con una herramienta distribuida (debido a que los datos est an replicados en todas partes), un solo servidor econ omico puede tratar las necesidades de equipos mucho m as grandes, y la replicaci on para balancear la carga se vuelve cosa de guiones. Si tiene un empleado en el campo, se beneciar a grandemente de un sistema distribuido de control de versiones al resolver problemas en el sitio del cliente. La herramienta le permitir a generar construcciones a la medida, probar 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 n a.

1.5.

Por qu e elegir Mercurial?

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

1.6.

Comparaci on de Mercurial con otras herramientas

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

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 a sencillo aprender a usar la otra. Ambas herramientas son portables en todos los sistemas operativos populares. Antes de la versi on 1.5, Subversion no ten a soporte para fusiones. En el momento de la escritura, sus capcidades para llevar cuenta de las funciones son nuevas, complicadas y poco estables2 . Mercurial tiene una ventaja considerable en desempe no sobre Subversion en cualquier operaci on de control de revisiones que yo haya medido. He medido sus ventajas con factores desde dos hasta seis veces comparando con aletodo de acceso m as r apido. En los escenarios macenamiento de cheros ra local Subversion 1.4.3, el cual es el m m as realistas incluyendo almacenamiento con la red de por medio, Subversion se encuentra en desventaja a un mayor. rdenes de Subversion deben tratar con el servidor y Subversion no tiene utilidades de repliDado que casi todas las o caci on adecuadas, la capacidad del servidor y el ancho de banda se convierten en cuellos de botella para proyectos 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 on frente a la revisi on actual (diff). Como resultado, la copia de trabajo de Subversion termina siendo del mismo tama no o m as 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 a bastante atr as en este aspecto. Esta diferencia est a disminuyendo, y algunas de las herramientas GUI3 , eclipsan sus equivalentes de Subversion. Al 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 a constante mientras que el espacio usado por cualquier Sistema Distribuido de Control de Revisiones crecer a r apidamente en proporci on con el n umero de revisiones, debido a que las diferencias entre cada revisi on es grande. Adicionalmente, generalmente es dif cil o m as bien, imposible mezclar diferentes versiones de un chero binario. 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 en puede exportar el 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 on del historial es incremental, de modo que puede aplicar una conversi on inicial, y despu es conversiones peque nas y adicionales posteriormente para traer nuevos 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 no fueron inuenciados por Monotone.
3 N. 2 N.

del T. buggy del T. Interfaz de Usuario Gr aca

rdenes muy grande; en la versi rdenes individuales. Tiene cierta Git tiene un conjunto de o on 1.5.0 ofrece 139 o reputaci on de ser dif cil de aprender. Comparado con Git, Mercurial tiene un fuerte enfoque hacia la facilidad. En t erminos de rendimiento, Git es extremadamente r apido. En muchos casos, es m as r apido que Mercurial, por lo menos en Linux, mientras que Mercurial se comporta mejor en otras operaciones. De todas maneras en Windows, el desempe no y el nivel general de soporte que ofrece Git, al momento de la escritura, est a bastante atr as de Mercurial. Mientras que el repositorio de Mercurial no requiere mantenimiento, el repositorio de Git requiere frecuentes reempaquetados de sus metadatos. Sin estos, el desempe no se degrada y el uso de espacio crece r apidamente. Un servidor que contenga repositorios de Git que no sean reempacados rigurosa y frecuentemente requerir a trabajo intenso de disco durante las copias de seguridad, y ha habido situaciones en copias de seguridad diaria que toman m as de 24 horas como resultado. Un repositorio reci en reempacado de Git es un poco m as peque no que un repositorio de rdenes de magnitud m Mercurial, pero un repositorio sin reempacar es varios o as grande. rdenes de Git est El coraz on de Git est a escrito en C. Muchas o an implementadas como guiones de l nea de comandos o de Perl y la calidad de esos guiones var a ampliamente. He encontrado muchas situaciones en las cuales los guiones no tuvieron en cuenta la presencia de errores que podr an 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 as ampliamente usada en el planeta. Debido a su edad y su poca pulcritud interna, ha sido ligeramente mantenida en muchos a nos. Tiene una arquitectura centralizada cliente/servidor. No agrupa cambios relacionados en consignaciones at omicas, pemitiendo que con facilidad la gente rompa la construcci on: una persona puede consignar exit osamente parte del cambio y estar bloqueada por la necesidad de una mezcla, forzando a otras personas a ver solamente una porci on del trabajo que estaban buscando hacer. Esto afecta tambi en la forma como usted trabaja con el historial del proyecto. Si quiere ver todas las modicaciones que alguien hizo como parte de una tarea, necesitar a inspeccionar manualmente las descripciones y las marcas de tiempo de cambio de cada chero involucrado (esto, si usted saber cu ales eran tales cheros). CVS tiene una noci on confusa de etiquetas y ramas que yo no tratar a incluso de describir. No soporta renombramiento 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 omo se corrompi o un repositorio. Yo no recomendar a 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 en son necesarias para cualquier herramienta importadora de historial de CVS. Debido a la falta de atomicidad de cambios y el no versionamiento de la jerarqu a del sistema de cheros, es imposible reconstruir completamente el historial de CVS con precisi on; hay cierto trabajo de conjetura involucrado y los renombramientos tampoco se mostrar an. Debido a que gran parte de la administraci on avanzada de CVS tiene que hacerse manualmente y por lo tanto es proclive al error, es com un que los importadores de CVS encuentren muchos problemas con repositorios corruptos (marcas de tiempo totalmente desubicadas y cheros que han permanecido con candados por m as de una d ecada son dos de los problemas menos interesantes de los que puedo retomar de mi experiencia personal). 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 e en el 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 nos, pero se degrada r apidamente cuando el n umero de usuarios va m as all a de pocas docenas. Instalaciones modestamente grandes de Perforce requiere la organizaci on de proxies para soportar la carga que sus usuarios generan.

1.6.5.

Elegir una herramienta de control de revisiones

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

1.7.

Migrar de otra herramienta hacia Mercurial

Mercurial viene con una extensi on llamada convert, que puede importar historiales de revisiones de forma incremental 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 es volver a ejecutar la migraci on posteriormente para obtener los nuevos cambios que han sucedido despu es de la migraci on inicial. A continuaci on presentamos las herramientas de revisiones que soporta el comando convert: 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 on total, sin arriesgarse a perder trabajo alguno. 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 a hacer su trabajo. Despu es de la conversi on inicial, basta con invocar de nuevo el comando para importar cambios nuevos.

10

Cap tulo 2

Una gira de Mercurial: lo b asico


2.1. Instalar Mercurial en su sistema

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

2.1.1.

Linux

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

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

2.1.2.

Solaris

SunFreeWare, en http://www.sunfreeware.com, es una buena fuente para un gran n umero de paquetes compilados 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 on compatible de Universal MacPython [BI]. Esto es f acil de hacer; simplemente siga las instrucciones del sitio de Lee. Tambi en es posible instalar Mercurial usando Fink o MacPorts, dos administradores de paquetes gratuitos y populares 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 on de Windows de Mercurial no convierte autom aticamente los nes de l nea entre estilos Windows y Unix. Si usted desea compartir trabajo con usuarios de Unix, deber a hacer un trabajo adicional de conguraci on. XXX Terminar esto.

2.2.

Arrancando

Para empezar, usaremos el comando hg version para revisar si Mercurial est a instalado adecuadamente. La informaci on de la versi on que es impresa no es tan importante; lo que nos importa es si imprime algo en absoluto.
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

sas ocasiones en la que usted est Mercurial provee un sistema de ayuda integrada. Esto es invaluable para e a atorado tratando de recordar c omo ejecutar un comando. Si est a completamente atorado, simplemente ejecute hg help; esto imprimir a una breve lista de comandos, junto con una descripci on de qu e hace cada uno. Si usted solicita ayuda sobre un comando espec co (como abajo), se imprime informaci on m as detallada.
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 as impresionante de detalle (que usted no va a necesitar usualmente) ejecute hg help -v. La opci on -v es la abreviaci on para --verbose, y le indica a Mercurial que imprima m as informaci on de lo que har a usualmente.

2.3.

Trabajar con un repositorio

En Mercurial, todo sucede dentro de un repositorio. El repositorio para un proyecto contiene todos los cheros que se proyecto, junto con un registro hist pertenecen a e orico de los cheros de ese proyecto. rbol de directorios en su sistema No hay nada particularmente m agico acerca de un repositorio; es simplemente un 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 l nea de comandos o su explorador de cheros.

2.3.1.

Hacer una copia local de un repositorio

Copiar un repositorio es s olo ligeramente especial. Aunque usted podr a usar un programa normal de copia de 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 entica de un repositorio existente.
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 xito, deber Si nuestro clonado tiene e amos tener un directorio local llamado hello. Este directorio contendr a algunos 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 a completo, es autocontenido e independiente. Contiene su propia copia de los cheros y el historial de un proyecto. Un repositorio clonado recuerda la ubicaci on de la que fue clonado, pero no se comunica con ese repositorio, ni con ning un otro, a menos que usted le indique que lo haga. 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 a nadie m as.
1 N.

del T. Del t ermino clonar en ingl es.

13

2.3.2.

Qu e hay en un repositorio?

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 terminolog a, el directorio .hg es el repositorio real, y todos los cheros y directorios que l est coexisten con e an en el directorio de trabajo. Una forma sencilla de recordar esta distinci on es que el repositorio contiene el historial de su proyecto, mientras que el directorio de trabajo contiene una instant anea de su proyecto en un punto particular del historial.

2.4.

Vistazo r apido al historial

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 arrafo breve por cada cambio al proyecto que haya sido grabado. Dentro de la terminolog a 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 umero, seguido por un :, seguido por una cadena hexadecimal. Ambos son identicadores para el conjunto de cambios. Hay dos identicadores porque el n umero es m as corto y m as f acil de recordar que la cadena hexadecimal. user3 La identidad de la persona que cre o el conjunto de cambios. Este es un campo en el que se puede almacenar cualquier valor, pero en la mayor a de los casos contiene el nombre de una persona y su direcci on de correo electr onico. 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 o el conjunto de cambios). summary5 La primera l nea del texto que us o la persona que cre o el conjunto de cambios para describir el mismo. El texto impreso por hg log es s olo un sumario; omite una gran cantidad de detalles. La gura 2.1 es una representaci on gr aca del historial del repositorio hello, para hacer m as f acil ver en qu e direcci on est a uyendo el historial. Volveremos a esto varias veces en este cap tulo y en los siguientes.
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 aco del repositorio hello

2.4.1.

Conjuntos de cambios, revisiones, y comunic andose con otras personas

rea de ciencias de la computaci Ya que el ingl es es un lenguaje notablemente desordenado, y el a on tiene una notable historia de confusi on de t erminos (porqu e usar s olo un t ermino cuando cuatro pueden servir?), el control de revisiones tiene una variedad de frases y palabras que tienen el mismo signicado. Si usted habla acerca del historial de Mercurial con alguien, encontrar a que la expresi on conjunto de cambios es abreviada a menudo como cambio o (por escrito) cset6 , y algunas veces un se hace referencia a un conjunto de cambios como una revisi on o rev7 . Si bien no es relevante qu e palabra use usted para referirse al concepto conjunto de cambios, el identicador que 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 umero como una cadena hexadecimal.
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 on changeset en ingl es. 7 N. del T. De nuevo, como abreviaci on para el t ermino en ingl es para revisi on (revision).
3 N. 2 N.

15

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

2.4.2.

Ver revisiones espec cas

Para reducir la salida de hg log a una sola revisi on, use la opci on -r (o --rev). Puede usar un n umero de revisi on o un identicador hexadecimal de conjunto de cambios, y puede pasar tantas revisiones como desee.
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 on de 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 en respeta el orden en que usted especica las revisiones, as que hg log -r 2:4 muestra 2, 3, 4 mientras que hg log -r 4:2 muestra 4, 3, 2.

2.4.3.

Informaci on m as detallada

til si usted sabe de antemano qu Aunque la informaci on presentada por hg log es u e est a buscando, puede que necesite ver una descripci on completa del cambio, o una lista de los cheros que cambiaron, si est a tratando de averiguar si un conjunto de cambios dado es el que usted est a buscando. La opci on -v (or --verbose) del comando 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 on como el contenido de un cambio, a nada la opci on -p (o --patch). Esto muestra el contenido de un cambio como un diff unicado (si usted nunca ha visto un diff unicado antes, vea la secci on 12.4 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 on en la til tener esto en mente a medida que avanza nuestra gira. manera en que trabajan; ser au 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 on tiene un nombre largo. Por ejemplo, el comando hg log acepta la opci on --rev, como ya hemos visto. Muchas opciones tienen tambi en un nombre corto. En vez de --rev, podemos usar -r. (El motivo para que 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 umero de revisi on acepta tanto la opci on -r como la --rev. En los ejemplos en este libro, uso las opciones cortas en vez de las largas. Esto s olo muestra mis preferencias, as que no le d e signicado especial a eso. Muchos de los comandos que generan salida de alg un tipo mostrar an m as salida cuando se les pase la opci on -v (o --verbose8 ), y menos cuando se les pase la opci on -q (o --quiet9 ).

2.6.

Hacer y repasar cambios

Ahora que tenemos una comprensi on adecuada sobre c omo revisar el historial en Mercurial, hagamos algunos cambios y veamos c omo examinarlos. Lo primero que haremos ser a aislar nuestro experimento en un repositorio propio. Usaremos el comando hg 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 as r apido que clonar a trav es de la red, y en la mayor a de los casos clonar un repositorio local usa menos espacio en disco tambi en.
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 on, es considerado buena pr actica mantener una copia pr stina de un repositorio remoto 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 ultiples tareas en paralelo, teniendo cada una de ellas aislada de las otras hasta que est en completas y usted est e listo para integrar los cambios de vuelta. Como los clones locales son tan baratos, clonar y 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 asico programa hello, world10 . Usaremos el cl asico y venerado comando sed para editar este chero y hacer que imprima una segunda l nea de l. salida. (Estoy usando el comando sed para hacer esto s olo porque es f acil escribir un ejemplo automatizado con e Dado que usted no tiene esta restricci on, probablemente no querr a usar sed; use su editor de texto preferido para hacer 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 olo una l nea empezando con M para el chero hello.c. A menos que usted lo indique expl citamente, hg status no imprimir a nada respecto a los cheros que 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; l fue capaz de darse cuenta de esto por s e mismo. til saber que hemos modicado el chero hello.c, pero preferir Es algo u amos saber exactamente qu e cambios 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 a garantizado que lo logre. Mercurial registra su nombre y direcci on en cada cambio que usted consigna, para que m as adelante otros puedan saber qui en es el responsable de cada cambio. Mercurial trata de encontrar un nombre de usuario adecuado con el cual registrar la consignaci on. Se intenta con cada uno de los siguientes m etodos, en el orden presentado.
11 N. 10 N.

del T. Hola, mundo. del T. Hacer una consignaci on

19

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

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

del T. Personas que env an correo no solicitado, tambi en conocido como correo basura

2.7.2.

Escribir un mensaje de consignaci on

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 on. Ser a un registro de lo que hicimos y porqu e lo hicimos, y ser a impreso por hg log una vez hayamos hecho la consignaci on.
1

$ hg commit 20

El editor en que hg commit nos ubica contendr a una l nea vac a, seguida de varias l neas que empiezan con la cadena HG:.
1 2

l nea vac a HG: changed hello.c Mercurial ignora las l neas que empiezan con HG:; s olo las usa para indicarnos para cu ales cheros est a registrando los cambios. Modicar o borrar estas l neas no tiene ning un efecto.

2.7.3.

Escribir un buen mensaje de consignaci on

Ya que por defecto hg log s olo muestra la primera l nea de un mensaje de consignaci on, lo mejor es escribir un mensaje cuya primera l nea tenga signicado por s misma. A continuaci on se encuentra un ejemplo de un mensaje de consignaci on que no sigue esta pauta, y debido a ello tiene un sumario que no es legible.
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. A nade un m odulo

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

2.7.4.

Cancelar una consignaci on

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

2.7.5.

Admirar nuestro trabajo

Una vez hemos terminado la consignaci on, podemos usar el comando hg tip12 para mostrar el conjunto de cambios que acabamos de crear. La salida de este comando es id entica a la de hg log, pero s olo muestra la revisi on m as reciente en el repositorio.
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 on m as reciente en el repositorio como la revisi on de punta, o simplemente la punta.

2.8.

Compartir cambios

Anteriormente mencionamos que los repositorios en Mercurial est an auto contenidos. Esto quiere decir que el conjunto de cambios que acabamos de crear s olo existe en nuestro repositorio my-hello. Veamos unas cuantas formas 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 e cambios jalar a el comando hg pull al repositorio, 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 podr a enviar m as conjuntos de cambios al repositorio en el tiempo que pasa entre la ejecuci on de hg incoming y la ejecuci on de hg pull para jalar los cambios, as que es posible que terminemos jalando cambios que no esper abamos.) Traer cambios al repositorio simplemente es cuesti on de ejecutar el comando hg pull, indic andole de qu e repositorio 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 es de hg tip, hemos jalado exitosamente los cambios en nuestro repositorio. A un falta un paso para que podamos ver estos cambios en nuestro directorio de trabajo.

2.8.2.

Actualizar el directorio de trabajo

Hasta ahora hemos pasado por alto la relaci on entre un repositorio y su directorio de trabajo. El comando hg pull que ejecutamos en la secci on 2.8.1 trajo los cambios al repositorio, pero si revisamos, no hay rastro de esos 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 aticamente. De hecho, hay una buena raz on para esto: usted puede usar hg update para actualizar el directorio de trabajo al estado en que se encontraba en cualquier revisi on del historial del repositorio. Si usted hubiera actualizado el directorio de trabajo a una revisi on anteriordigamos, para buscar el origen de un falloy hubiera corrido un hg pull que hubiera actualizado el directorio de trabajo autom aticamente a la nueva revisi on, puede que no estuviera particularmente contento. Sin embargo, como jalar-y-actualizar es una secuencia de operaciones muy com un, Mercurial le permite combinarlas al pasar la opci on -u a hg pull.

hg pull -u
14 N.

del T. Actualizar.

23

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

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

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 a echas conectando cada conjunto de cambios. En cada caso, el nodo del que la echa sale es un padre, y el nodo al que la echa llega es su hijo. El directorio de trabajo tiene un padre exactamente se es el conjunto de cambios que contiene actualmente el directorio de trabajo. de la misma manera; e Para actualizar el conjunto de trabajo a una revisi on particular, pase un n umero de revisi on o un ID de conjunto de 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 expl citamente una revisi on, hg update actualizar a hasta la revisi on de punta, como se vio en la segunda 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 nuestros 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 e cambios ser an empujados en el otro repositorio.

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 on -u para actualizar el directorio de trabajo del otro repositorio.) Qu e pasa si tratamos de jalar o empujar cambios y el repositorio receptor ya tiene esos cambios? Nada emocionante.

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 es de una red

Los comandos que hemos presentando en las pocas secciones anteriores no est an limitados a trabajar con repositorios locales. Cada uno de ellos funciona exactamente de la misma manera a trav es de una conexi on de red. Simplemente 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 e cambios empujar amos al repositorio remoto, aunque, de manera entendible, el l. repositorio remoto est a congurado para no permitir a usuarios an onimos empujar cambios a e

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

Cap tulo 3

Una gira de Mercurial: fusionar trabajo


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

3.1.

Fusionar l neas de trabajo


Alicia y Roberto tienen cada uno una copia personal del repositorio de un proyecto en el que est an trabajando. Alicia arregla un fallo en su repositorio; Roberto a nade una nueva caracter stica en el suyo. Ambos desean que el repositorio compartido contenga el arreglo del fallo y la nueva caracter stica. 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 on tan necesaria y com un, Mercurial la facilita. Revisemos el proceso. Empezaremos l. clonando (otro) repositorio (ve lo seguido que aparecen?) y haciendo un cambio en e
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 deber amos 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 a efecto en el directorio de trabajo.
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 en se les conoce. La revisi on de punta es, por tanto, un frente, porque la revisi on m as reciente en un repositorio no tiene ning un hijo. Sin embargo, un repositorio puede contener m as de un frente.
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 es de jalar my-hello a my-new-hello 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 exist a en my-new-hello se mantiene intacto, pero fue a nadida una nueva revisi on. Reri endonos a la gura 3.1, podemos ver que el ID del conjunto de cambios se mantiene igual en el nuevo repositorio, pero el n umero de revisi on ste es un buen ejemplo de porqu ha cambiado. (Incidentalmente, e e no es seguro usar n umeros de revisi on cuando se 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 on

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

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

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 on, y consignaci on consecuente 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 on

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

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

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 on de lo que pasa en el directorio de trabajo durante la fusi on cuando se hace la consignaci on. Durante la fusi on, el directorio de trabajo tiene dos conjuntos de cambios como sus stos se vuelven los padres del nuevo conjunto de cambios. padres, y e

3.2.

Fusionar cambios con conictos

La mayor a de las fusiones son algo simple, pero a veces usted se encontrar a fusionando cambios donde m as de uno de ellos afecta las mismas secciones de los mismos cheros. A menos que ambas modicaciones sean id enticas, el resultado es un conicto, en donde usted debe decidir c omo reconciliar ambos cambios y producir un resultado 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 on del chero; luego hicimos algunos cambios; mientras tanto, alguien m as hizo cambios diferentes en el mismo texto. Lo que debemos hacer para resolver el conicto causado por ambos cambios es decidir c omo debe quedar 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 on de l nea de comandos que es instalado junto con Mercurial; usted puede modicarlo 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 en instaladas en su sistema. Primero se intenta con unas herramientas para fusionar xito (porque la fusi cambios autom aticamente; si esto no tiene e on demanda una gu a humana) o dichas herramientas no est an presentes, el gui on intenta con herramientas gr acas para fusionar. Tambi en es posible hacer que Mercurial ejecute otro programa o gui on en vez de hgmerge, deniendo la variable de entorno HGMERGE con el nombre del programa de su preferencia.

3.2.1.

Usar una herramienta gr aca para fusi on

Mi herramienta favorita para hacer fusiones es kdiff3, y la usar e para describir las caracter sticas comunes de las herramientas gr acas para hacer fusiones. Puede ver una captura de pantalla de kdiff3 ejecut andose, en la gura 3.5. El tipo de fusi on que la herramienta hace se conoce como fusi on de tres v as, porque hay tres versiones diferentes del chero en que estamos interesados. Debido a esto la herramienta divide la parte superior de la ventana en tres paneles. A la izquierda est a la revisi on base del chero, p.ej. la versi on m as reciente de la que descienden las dos versiones que estamos tratando de fusionar. En la mitad est a nuestra versi on del chero, con las modicaciones que hemos hecho. A la derecha est a la versi on del chero de ellos, la que forma parte del conjunto de cambios que estamos tratando de fusionar. En el panel inferior se encuentra el resultado actual de la fusi on. Nuestra tarea es reemplazar todo el texto rojo, que muestra los conictos sin resolver, con una fusi on adecuada de nuestra versi on del chero y la de ellos. Los cuatro paneles est an enlazados; si avanzamos vertical o horizontalmente en cualquiera de ellos, los otros son 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 on del texto de la revisi on base, la nuestra, o la de ellos. Tambi en podemos editar manualmente el chero en que queda la fusi on, si es necesario hacer cambios adicionales. Hay muchas herramientas para fusionar cheros disponibles. Se diferencian en las plataformas para las que est an disponibles, y en sus fortalezas y debilidades particulares. La mayor a est an anadas para fusionar texto plano, mientras que otras est an pensadas para formatos de cheros especializados (generalmente XML).

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 on base de nuestro documento.
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 as haciendo un cambio al mismo chero. (Esto introduce la idea de que no es tan inusual hacer fusiones consigo mismo, cuando usted a sla 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 on.

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 e el comando normal de Mercurial para hacer la fusi on (hgmerge), porque lanzar a mi linda herramienta automatizada para correr ejemplos dentro de una interfaz gr aca de usuario. En vez de eso, denir e la variable de entorno HGMERGE para indicarle a Mercurial que use el comando merge. Este comando forma parte de la instalaci on base de muchos sistemas Unix y similares. Si usted est a ejecutando este ejemplo en su computador, no se 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. l deja marcadores de fusi Debido a que merge no puede resolver los conictos que aparecen, e on en el chero con conictos, indicando si provienen de nuestra versi on o de la de ellos. Mercurial puede saber por el c odigo de salida del comando merge que no fue posible hacer la fusi on exitosa til si, por mente, as que nos indica qu e comandos debemos ejecutar si queremos rehacer la fusi on. Esto puede ser u ejemplo, estamos ejecutando una herramienta gr aca de fusi on y salimos de ella porque nos confundimos o cometimos un error. Si la fusi on autom atica o manual falla, no hay nada que nos impida arreglar los cheros afectados por nosotros mismos, y consignar los resultados de nuestra fusi on:

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 on de tres comandos en sucesi on.
1 2 3

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

1 2

[extensions] fetch = (Normalmente, a la derecha del = deber a aparecer la ubicaci on de la extensi on, pero como el comando fetch es parte de la distribuci on est andar, Mercurial sabe d onde buscarla.)

3 N.

del T. Descargar, traer.

35

Cap tulo 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 acilmente c omo funciona el software. Saber esto no es necesario, pero til tener un modelo mental de qu considero u e es lo que sucede. Comprender esto me da la conanza de que Mercurial ha sido cuidadosamente dise nado para ser tanto seguro como eciente. Y tal vez con la misma importancia, si es f acil para m hacerme a una idea adecuada de qu e est a haciendo el software cuando llevo a cabo una tarea relacionada con control de revisiones, es menos probable que me sosprenda su comportamiento. En este cap tulo, cubriremos inicialmente los conceptos centrales del dise no de Mercurial, y luego discutiremos algunos detalles interesantes de su implementaci on.

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 on para reconstruir una revisi on del chero que se est a siguiendo. Los cheros de registro son almacenados como cheros el el directorio .hg/store/data. Un chero de registro contiene dos tipos de informaci on: datos de revisiones, y un ndice para 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 nos con un historial peque no, los datos de nico chero .i. La correspondencia entre un chero en el directorio revisiones y el ndice son combinados en un u 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 on de cheros monitoreados

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

4.1.3.

Registro de informaci on del conjunto de cambios

La bit acora de cambios contiene informaci on acerca de cada conjunto de cambios. Cada revisi on indica qui en consign o un cambio, el comentario para el conjunto de cambios, otros datos relacionados con el conjunto de cambios, y la revisi on del maniesto a usar.
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 on entre cheros en el directorio de trabajo y cheros de registro en el repositorio

4.1.4.

Relaciones entre revisiones

Dentro de una bit acora de cambios, un maniesto, o un chero de registro, cada revisi on conserva un apuntador a su padre inmediato (o sus dos padres, si es la revisi on de una fusi on). Como mencio ne anteriormente, tambi en hay relaciones entre revisiones a trav es de estas estructuras, y tienen naturaleza jer arquica. Por cada conjunto de cambios en un repositorio, hay exactamente una revisi on almacenada en la bit acora de nica revisi cambios. Cada revisi on de la bit acora de cambios contiene un apuntador a una u on del maniesto. Una nica revisi revisi on del maniesto almacena un apuntador a una u on de cada chero de registro al que se le hac a 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 on uno a uno entre las revisiones en el conjunto de cambios, el 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 acora de cambios para esos conjuntos de cambios apuntar an a la misma revisi on del maniesto. Si un chero monitoreado por Mercurial no sufre ning un cambio de un conjunto de cambios a otro, la entrada para dicho chero en las dos revisiones del maniesto apuntar a a la misma revisi on de su chero de registro. 37

4.2.

Almacenamiento seguro y eciente

nica La base com un de las bit acoras de cambios, los maniestos, y los cheros de registros es provista por una u 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 on, almacena los cambios necesarios para transformar una revisi on anterior en la nueva revisi on. Para muchos tipos de chero, estos deltas son t picamente de una fracci on porcentual del tama no de una copia completa del chero. Algunos sistemas de control de revisiones obsoletos s olo pueden manipular deltas de cheros de texto plano. Ellos o bien almacenan los cheros binarios como instant aneas completas, o codicados en alguna representaci on de texto 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 on segura

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

4.2.3.

Recuperaci on r apida de datos

Mercurial evita ingeniosamente un problema com un a todos los sistemas de control de revisiones anteriores el problema de la recuperaci on4 ineciente de datos. Muchos sistemas de control de revisiones almacenan los contenidos de una revisi on como una serie incremental de modicaciones a una instant anea. Para reconstruir una versi on cualquiera, primero usted debe leer la instant anea, y luego cada una de las revisiones entre la instant anea y su versi on objetivo. Entre m as largo sea el historial de un chero, m as revisiones deben ser le das, y por tanto toma m as tiempo reconstruir una versi on particular. La innovaci on que aplica Mercurial a este problema es simple pero efectiva. Una vez la cantidad de informaci on de ltima instant deltas acumulada desde la u anea excede un umbral jado de antemano, se almacena una nueva instant anea (comprimida, por supuesto), en lugar de otro delta. Esto hace posible reconstruir cualquier versi on de un chero r apidamente. Este enfoque funciona tan bien que desde entonces ha sido copiado por otros sistemas de control de 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 on en particular. Nota al margen: la inuencia de la compresi on de v deo Si le es familiar la compresi on de v deo, o ha mirado alguna vez una emisi on de TV a trav es de cable digital o un servicio de sat elite, puede que sepa que la mayor parte de los esquemas de compresi on de v deo almacenan
del T. Contracci on de revision log, registro de revisi on. del T. Diferencias. 4 N. del T. Retrieval. Recuperaci on en el sentido de traer los datos, o reconstruirlos a partir de otros datos, pero no debido a una falla o calamidad, sino a la operaci on normal del sistema.
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 anea de un revlog, con deltas incrementales cada cuadro del mismo como un delta contra el cuadro predecesor. Adicionalmente, estos esquemas usan t ecnicas de compresi on con p erdida para aumentar la tasa de compresi on, por lo que los errores visuales se acumulan a lo largo de una cantidad de deltas inter-cuadros. Ya que existe la posibilidad de que un ujo de v deo se pierda ocasionalmente debido a fallas en la se nal, y para limitar la acumulaci on de errores introducida por la compresi on con p erdidas, los codicadores de v deo insertan peri odicamente un cuadro completo (tambi en llamado cuadro clave) en el ujo de v deo; el siguiente delta es generado con respecto a dicho cuadro. Esto quiere decir que si la se nal de v deo se interrumpe, se reanudar a una vez se reciba el siguiente cuadro clave. Adem as, la acumulaci on de errores de codicaci on se reinicia con cada cuadro clave.

4.2.4.

Identicaci on e integridad fuerte

Adem as de la informaci on de deltas e instant aneas, una entrada en un revlog contiene un hash criptogr aco de los datos que representa. Esto hace dif cil falsicar el contenido de una revisi on, y hace f acil detectar una corrupci on accidental. Los hashes proveen m as que una simple revisi on de corrupci on: son usados como los identicadores para las revisiones. Los hashes de identicaci on de conjuntos de cambios que usted ve como usuario nal son de las revisiones de la bit acora de cambios. Aunque los cheros de registro y el maniesto tambi en usan hashes, Mercurial s olo los usa 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 a y detendr a cualquier operaci on que est e haciendo. Adem as del efecto que tiene en la eciencia en la recuperaci on, el uso peri odico de instant aneas de Mercurial lo hace m as robusto frente a la corrupci on parcial de datos. Si un chero de registro se corrompe parcialmente debido a un error de hardware o del sistema, a menudo es posible reconstruir algunas o la mayor a de las revisiones a partir de las secciones no corrompidas del chero de registro, tanto antes como despu es de la secci on corrompida. Esto no ser a nicamente en deltas. posible con un sistema de almacenamiento basado u

39

4.3.

Historial de revisiones, ramas y fusiones

Cada entrada en el revlog de Mercurial conoce la identidad de la revisi on de su ancestro inmediato, al que se conoce usualmente como su padre. De hecho, una revisi on contiene sitio no s olo para un padre, sino para dos. Mercurial usa 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 acoras de cambios comparten la misma estructura; s olo dieren en el tipo de datos almacenados en cada delta o instant anea. La primera revisi on en un revlog (al nal de la imagen) tiene como padre al ID nulo, en las dos ranuras disponibles para padres. En una revisi on normal, la primera ranura para padres contiene el ID de la revisi on padre, y la segunda contiene el ID nulo, se nalando as que la revisi on s olo tiene un padre real. Un par de revisiones que tenga el mismo ID padre son ramas. Una revisi on que representa una fusi on entre ramas tiene dos IDs de revisi on normales en sus ranuras para padres.

4.4.

El directorio de trabajo

En el directorio de trabajo, Mercurial almacena una instant anea de los cheros del repositorio como si fueran los de un conjunto de cambios particular. El directorio de trabajo sabe qu e conjunto de cambios contiene. Cuando usted actualiza el directorio de trabajo para que contenga un conjunto de cambios particular, Mercurial busca la revisi on adecuada del maniesto para averiguar qu e cheros estaba monitoreando cuando se hizo la consignaci on del conjunto de cambios, y qu e revisi on 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 ten an 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 e conjunto de cambios es actualizado el directorio de trabajo, y todos los cheros que Mercurial est a monitoreando en este directorio. Tal como la revisi on de un revlog tiene espacio para dos padres, para que pueda representar tanto una revisi on normal (con un solo padre) o una fusi on de dos revisiones anteriores, el estado de directorio tiene espacio para dos 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 on (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 on. El comando hg parents le indica cu ales son los padres del estado de directorio.

4.4.1.

Qu e pasa en una consignaci on

El estado de directorio almacena informaci on sobre los padres para algo m as que mero registro. Mercurial usa los padres del estado de directorio como los padres de un nuevo conjunto de cambios cuando usted hace una consignaci on. nico conjunto de cambios como La gura 4.5 muestra el estado normal del directorio de trabajo, que tiene un u padre. Dicho conjunto de cambios es la punta, el conjunto de cambios m as reciente en el repositorio que no tiene hijos. til pensar en el directorio de trabajo como en el conjunto de cambios que estoy a punto de enviar. Cualquier Es u chero que usted le diga a Mercurial que fue a nadido, borrado, renombrado o copiado, se ver a reejado en ese conjunto de cambios, como tambi en se ver an las modicaciones a cualquiera de los cheros que Mercurial ya est e monitoreando; el nuevo conjunto de cambios dentr a los padres del directorio de trabajo como propios. Luego de una consignaci on, Mercurial actualizar a los padres del directorio de trabajo, de tal manera que el primer 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 on; s olo modica el estado de directorio para anotar sus nuevos padres.
5 N.

del T. dirstate, en ingl es en el original.

40

4.4.2.

Creaci on de un nuevo frente

Es perfectamente normal actualizar el directorio de trabajo a un conjunto de cambios diferente a la punta actual. Por ejemplo, usted podr a desear saber en qu e estado se encontraba su proyecto el martes pasado, o podr a estar buscando stos, la acci en todos los conjuntos de cambios para saber cu ando se introdujo un fallo. En casos como e on natural es actualizar el directorio de trabajo al conjunto de cambios de su inter es, y examinar directamente los cheros en el directorio de trabajo para ver sus contenidos tal como estaban en el momento de hacer la consignaci on. El efecto que 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 e pasa si se hacen cambios, y luego se hace una consignaci on? Mercurial se comporta en la misma forma que describ anteriormente. Los padres 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 stos los llamamos frentes. Usted puede apreciar la estructura que esto crea en la gura 4.8. tienen hijos; a e Nota: Si usted es nuevo en Mercurial, deber a tener en mente un error com un, que es usar el comando hg pull sin ninguna opci on. Por defecto, el comando 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 ten a antes de jalar. Si usted hace algunos cambios, y luego hace una consignaci on, estar a creando un nuevo frente, 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 on es hacer una fusi on (hg merge), y luego una consignaci on (hg commit). En otras palabras, esto casi nunca tiene consecuencias negativas; s olo sorprende a la gente. Discutir e otras formas de evitar este comportamiento, y porqu e Mercurial se comporta de esta forma, inicialmente sorprendente, m as adelante.

4.4.3.

Fusi on de frentes

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 a haciendo la fusi on, como se muestra en la gura 4.9. l monitorea en los dos Mercurial tambi en debe modicar el directorio de trabajo, para fusionar los cheros que 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 un conjunto de cambios ha modicado un chero, no se hace nada con el mismo. 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 en lo borr o), se borra dicho chero 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 e hacer: conservar el chero modicado, o borrarlo? Si ambos conjuntos de cambios han modicado un chero, se invoca el programa externo de fusi on para denir el nuevo contenido del chero fusionado. Esto puede requerir interacci on directa de parte del usuario. 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

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

4.5.

interesantes Otras caracter sticas de diseno

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

4.5.1.

Compresi on ingeniosa

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

4.5.2.

Reordenado de lectura/escritura y atomicidad

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

revisiones en el maniesto apuntan a revisiones en cheros de registro. Esta jerarqu a es deliberada. Un escritor inicia una transacci on al escribir los datos del cheros del chero de registro y el maniesto, y no escribe nada en la bit acora de cambios hasta que dichas escrituras hayan terminado. Un lector empieza leyendo datos de la bit acora de cambios, luego del maniesto, y nalmente del chero de registro. Como el escritor siempre termina de escribir los datos en el chero de registro y en el maniesto antes de escribir a la bit acora de cambios, un lector nunca ver a un apuntador a una versi on parcialmente escrita de revisiones del maniesto desde la bit acora de cambios, y nunca leer a un apuntador a una revisi on parcialmente escrita del chero de 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 a leyendo datos, a un si se est a escribiendo al repositorio mientras se hace la lectura. Esto tiene un gran 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 a escribiendo al mismo o no. La naturaleza carente de bloqueos de la lectura signica que si usted est a compartiendo un repositorio en un sistema multiusuario, no necesita dar a los usuarios locales permisos de escritura a su repositorio para que ellos puedan clonarlo o jalar cambios; s olo necesitan permisos de lectura. (Esta no es una caracter stica com un entre los sistemas de control de revisiones, as que no la d e por hecha! Muchos de ellos requieren que los lectores sean capaces 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 olo un proceso pueda escribir a un repositorio al mismo tiempo (el mecanismo de bloqueo es seguro incluso sobre sistemas de cheros notoriamente hostiles al bloqueo, como NFS). Si un repositorio est a bloqueado, los escritores esperar an un buen rato para revisar si el repositorio ya ha sido desbloqueado, pero si el repositorio sique bloqueado por mucho tiempo, el proceso que intenta escribir fallar a por tiempo de espera m aximo. Esto signica que sus guiones autom aticos diarios no se quedar an esperando para siempre, apil andose si el sistema se cay o sin que nadie se diera cuenta, por ejemplo. (S , el tiempo de espera m aximo es congurable, de cero a innito). Acceso seguro al estado de directorio Al igual que con los datos de revisi on, Mercurial no requiere un bloqueo para leer el chero de estado de directorio; l. Para evitar la posibilidad de leer una copia parcialmente escrita del chero de s se usa un bloqueo para escribir a e nico en el mismo directorio del chero de estado estado de directorio, Mercurial escribe a un chero con un nombre u de directorio, y luego renombra at omicamente este chero temporal a dirstate6 . As se garantiza que el chero llamado dirstate est e completo, y no parcialmente escrito.

4.5.4.

Evitar movimientos de brazo

Un aspecto cr tico para el desempe no de Mercurial es evitar los movimientos del brazo de lectura del disco duro, ya que cualquier movimiento de brazo es mucho m as costoso que incluso una operaci on de lectura relativamente grande. 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 har a un movimiento de brazo por cada directorio. En cambio, Mercurial lee el estado de directorio completo en un solo paso. Mercurial tambi en usa un esquema de copiar al escribir cuando clona un repositorio en un mismo medio de 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 a punto de escribir a uno de los cheros de revlog, revisa si la cantidad de nombres apuntando al chero es de m as de uno. Si lo es, m as de un repositorio est a usando el chero, as que Mercurial hace una nueva copia del chero, privada para este 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 etodo brinda el m aximo rendimiento al tiempo que delega la mayor parte del trabajo de manejo de cheros al sistema operativo. Un esquema alternativo seguramente reducir a el desempe no y aumentar a la complejidad del software, cada uno de los cuales es mucho m as importante para la sensaci on que se tiene del software en el trabajo d a a d a.

4.5.5.

Otros contenidos del estado de directorio

Debido a que Mercurial no lo fuerza a indicar si usted est a modicando un chero, se usa el estado de directorio para almacenar informaci on extra para poder determinar efecientemente si usted ha modicado un chero. Por cada ltima vez el chero, y el chero en el directorio de trabajo, se almacena el momento en que Mercurial modic o por u tama no del chero en ese momento. Cuando usted a nade (hg add), remueve (hg remove), renombra (hg rename) o copia (hg copy) cheros, Mercurial actualiza el estado de directorio para saber qu e hacer con dichos cheros cuando usted haga la consignaci on. Cuando Mercurial est a revisando el estado de los cheros en el directorio de trabajo, revisa primero la fecha de modicaci on del chero. Si no ha cambiado, el chero no ha sido modicado. Si el tama no del chero ha cambiado, el chero ha sido modicado. S olo en el caso en que el tiempo de modicaci on ha cambiado, pero el tama no no, es necesario leer el contenido del chero para revisar si ha cambiado. Almacenar estos pocos datos reduce dram aticamente 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 on

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 es de una consignaci on hecha mientras se usaba un conjunto de cambios anterior

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 on de dos frentes

48

Cap tulo 5

Mercurial d a a d a
5.1. C omo indicarle a Mercurial qu e cheros seguir

Mercurial no trabaja con cheros en su repositorio a menos que usted se lo indique expl citamente. La orden hg status le mostrar a cu ales cheros son desconocidos para Mercurial; se emplea un ? para mostrar tales cheros. Para indicarle a Mercurial que tenga en cuenta un chero, emplee la orden hg add. Una vez que haya adicionado el chero, la l nea 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 es de invocar hg commit, los cheros que haya adicionado antes de consignar no se listar an en la salida de hg status. La raz on para esto es que hg status solamente le muestra aquellos cheros interesantes 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 a saber cu ales de ellos est an siendo seguidos por Mercurial, pero que no han cambiado. (De todas maneras, puede obtener tal informaci on; m as adelante hablaremos de ello.) l inmediatamente. En cambio, tomar Cuando usted a nade un chero, Mercurial no hace nada con e a una instant anea del estado del chero la pr oxima vez que usted consigne. Continuar a haciendo seguimiento a los cambios que haga sobre el chero cada vez que consigne, hasta que usted lo elimine.

5.1.1.

Nombramiento expl cito e impl cito de cheros

til en el cual si a una orden, le pasa el nombre de un directorio, todas las Mercurial tiene un comportamiento u rdenes lo interpretar o an como Deseo operar en cada chero de este directorio y sus subdirectorios.
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 o los nombres de los cheros que se adicionaron, mientras que no lo hizo en el ejemplo anterior cuando adicionamos el chero con nombre a. ltimo caso hicimos expl rdenes, y En el u cito el nombre del chero que dese abamos adicionar en la l nea de o Mercurial asume en tales casos que usted sabe lo que est a haciendo y no imprime informaci on alguna. Cuando hacemos impl citos los nombres de los cheros dando el nombre de un directorio, Mercurial efect ua el paso extra de imprimir el nombre de cada chero con el que va a hacer algo. Esto para aclarar lo que est a sucediendo, rdenes en y reducir en lo posible una sorpresa silenciosa pero fatal. Este comportamiento es com un a la mayor a de o Mercurial.

5.1.2.

Nota al margen: Mercurial trata cheros, no directorios

Mercurial no da seguimiento a la informaci on de los directorios. En lugar de eso tiene en cuenta las rutas de los cheros. Antes de crear un chero, primero crea todos los directorios que hagan falta para completar la ruta del mismo. Despu es de borrar un chero, borra todos los directorios vac os que estuvieran en la ruta del chero borrado. Suena como una diferencia trivial, pero tiene una consecuencia pr actica menor: no es posible representar un directorio completamente vac o en Mercurial. tiles, y hay soluciones alternativas no intrusivas que usted puede emplear para Los directorios vac os rara vez son u obtener el efecto apropiado. Los desarrolladores de Mercurial pensaron que la complejidad necesaria para administrar directorios vac os no val a la pena frente al benecio limitado que esta caracter stica podr a traer. Si necesita un directorio vac o en su repositorio, hay algunas formas de lograrlo. Una es crear un directorio, despu es hacer hg add a un chero oculto dentro de ese directorio. En sistemas tipo Unix, cualquier chero cuyo nombre comience con un punto (.) es tratado como oculto por la mayor a de comandos y herramientas GUI. Esta aproximaci on se ilustra en la gura 5.1.
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 vac o con un chero oculto Otra forma de abordar la necesidad de un directorio vac o es simplemente crear uno en sus guiones de construcci on antes de que lo necesiten. 50

5.2.

C omo dejar de hacer seguimiento a un chero

Si decide que un chero no pertenece a su repositorio, use la orden hg remove; se borrar a el chero y le indicar a a Mercurial que deje de hacerle seguimiento. Los cheros eliminados se representan con R al usar hg 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 es de hacer hg remove a un chero, Mercurial dejar a de hacer seguimiento al mismo, incluso si recrea el 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 a que el chero recientemente adicionado no est a relacionado con el chero anterior que ten a el mismo nombre.

5.2.1.

Al eliminar un chero no se afecta su historial

Es preciso tener en cuenta que eliminar un chero tiene s olo dos efectos. Se elimina la versi on actual del chero del directorio de trabajo. Mercurial deja de hacer seguimiento a los cambios del chero desde la pr oxima consignaci on. 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 o a un era tenido en ste reaparecer cuenta, e a en el directorio de trabajo, con los contenidos que este ten a cuando se consign o tal conjunto de cambios. Si usted actualiza el directorio de trabajo a un conjunto de cambios posterior en el cual el chero hab a sido eliminado, Mercurial lo eliminar a de nuevo del directorio de trabajo.

5.2.2.

Ficheros perdidos

Mercurial considera como perdido un chero que usted borr o, pero para el que no se us o hg remove. Los rdenes de Mercurial generalmente no har cheros perdidos se representan con ! al visualizar hg status. Las o an 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 o un chero perdido por accidente, puede usar hg revert nombre de fichero para recuperar el chero. Reaparecer a, sin modicaciones.

1 2 3 4

$ hg revert a $ cat a a $ hg status

5.2.3.

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

Es posible que se haya preguntado por qu e Mercurial exige que usted le indique expl citamente que est a borrando un chero. Al principio del desarrollo de Mercurial, este permit a que usted borrara el chero sin m as; Mercurial se dar a cuenta de la ausencia del chero autom aticamente despu es de la ejecuci on de hg commit, y dejar a de hacer seguimiento al chero. En la pr actica, resultaba muy sencillo borrar un chero accidentalmente sin darse cuenta.

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 on -A que aplica el mismo agregar-eliminar, seguido inmediatamente de una consignaci on.

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 on con el trabajo de alguien m as.

52

5.3.1.

Resultados de copiar un chero durante una fusi on

Durante una fusi on los cambios siguen una copia. Para ilustrar lo que esto signica, haremos un ejemplo. Comenzaremos 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 nadido normalmente.

1 2

$ hg status A new-file Pero si usamos la opci on -C de la orden hg status, se imprimir a otra l nea: el chero desde el cual fue copiado nuestro chero reci en a nadido.

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 l nea 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 a los cambios que hemos hecho localmente en file a su copia, new-file.

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 e los cambios se reejan en las copias?

Este comportamiento de cambios en cheros que se propagan a las copias de los cheros parecer a esot erico, pero en la mayor a de casos es absolutamente deseable. Es indispensable recordar que esta propagaci on solamente sucede 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. nicamente si los Lo segundo a tener en cuenta es que las modicaciones solamente se propagar an en las copias u repositorios de los cuales est a jalando los cambios no saben de la copia. Explicaremos a continuaci on la raz on de este comportamiento de Mercurial. Digamos que yo he aplicado un arreglo de un fallo importante a un chero fuente y consign e los cambios. Por otro lado, usted decidi o hacer hg 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 tendr a el fallo, a menos que usted haya recordado propagar el arreglo del fallo a mano, el mismo permanecer a en su copia del chero. Mercurial previene esta clase de problemas, gracias a la propagaci on autom atica del cambio que arregl o el fallo del chero original. Hasta donde s e, Mercurial es el u nico sistema de control de revisiones que propaga los cambios en las copias de esta forma. Cuando su historial de cambios tiene un registro de la copia y la subsecuente fusi on, usualmente no es necesario nicamente los propagar los cambios el chero original a las copias del mismo, y por esta raz on Mercurial propaga u cambios en las copias hasta este punto y no m as all a.

5.3.3.

C omo hacer que los cambios no sigan a la copia?

Si por alg un motivo usted decide que esta caracter stica de propagaci on autom atica de cambios en las copias 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 on 5.3.2, y tome una decisi on asegur andose que este comportamiento no es el apropiado para su caso espec co.

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 a tambi en las modicaciones que haya hecho hasta ese punto. (Este comportamiento me parece poco intuitivo, y por tal motivo lo menciono.) La orden hg copy act ua de forma parecida a la orden cp de Unix (puede usar el alias hg cp si le es m as ltimo argumento es el destino, y todos los argumentos previos son las fuentes. Si solamente indica un c omodo). El u 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 ste. Si el destino es un directorio, Mercurial copia las fuentes en e

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 on --after a la orden hg copy.

1 2

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

5.4.

Renombrar cheros

La necesidad de renombrar un chero es m as com un que hacer una copia del mismo. La raz on por la cual discut la 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 e esperar cuando renombra un chero. 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 nadida y el chero inicial de la copia, como eliminado.

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 on -C de la orden hg status para vericar que el chero a nadido realmente comienza a ser seguido por Mercurial como una copia del chero original, 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 arsele a Mercurial acerca de un renombramiento inmediato con la opci on --after. El comportamiento de la orden hg rename y las opciones que acepta, son similares a la 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 on de cambios ocurre cuando usted fusiona despu es de renombrar como despu es de hacer una copia. Si yo modico un chero y usted lo renombra a un nuevo chero, y posteriormente fusionamos nuestros respectivos cambios, mi modicaci on al chero bajo su nombre original se propagar a en el chero con el nuevo nombre. (Es lo que se esperar a 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 caracter stica respecto a la cual usted puede estar til, deber de acuerdo y decir si, puede ser u a ser claro que el seguimiento de cambios de un renombramiento es denitivamente importante. Sin esto, ser a muy sencillo que los cambios se quedaran atr as cuando los cheros se renombran.

5.4.2.

Cambios de nombre divergentes y fusi on

El caso de renombramiento con nombres divergentes ocurre cuando dos desarrolladores comienzan con un chero llam emoslo fooen sus repositorios respectivos.
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 omo considera deber a haberse nombrado el chero. Qu e cree que deber a pasar cuando fusionen su trabajo? El comportamiento de Mercurial es que siempre preserva 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 e hacer con la divergencia despu es de la fusi on.

5.4.3.

Cambios de nombre convergentes y fusi on

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 on usual, y le permite a usted guiar la situaci on a una resoluci on adecuada.

5.4.4.

Otros casos l mite 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 a documentado como Fallo de 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

rdenes poderosas que le ayudar Mercurial tiene unas o an a recuperarse de equivocaciones comunes. La orden hg revert le permite deshacer cambios que haya hecho a su directorio de trabajo. Por ejemplo, si aplic o hg add a un chero por accidente, ejecute hg revert con el nombre del chero que a nadi o, y en tanto que el chero no haya sido tocado de forma alguna, no ser a adicionado, ni seguido por Mercurial. Tambi en puede usar hg revert para deshacerse de cambios err oneos a un chero. 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 todav a, pero sus opciones pueden estar m as limitadas. Para obtener informaci on acerca de la orden hg revert y detalles de c omo tratar con cambios consignados, vea el cap tulo 9.

58

Cap tulo 6

Colaborar con otros


Debido a su naturaleza descentralizada, Mercurial no impone pol tica alguna de c omo deben trabajar los grupos 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

tiles. Mercurial tiene una poderosa interfaz web que provee bastantes capacidades u 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 aticamente de la actividad en el repositorio tan pronto como sucede. Me gusta mucho m as este modelo que el estar suscrito a una lista de correo a la cual se env an las noticaciones, dado que no requiere conguraci on adicional de parte de quien sea que est a administrando el repositorio. La interfaz web tambi en permite a los usuarios remotos clonar repositorios, jalar cambios, y (cuando el servidor est a congurado para permitirlo) empujar cambios al mismo. El protocolo de entunelamiento HTTP de Mercurial comprime datos agresivamente, de forma que trabaja ecientemente incluso en conexiones de red con poco ancho de banda. La forma m as sencilla de empezar a trabajar con la interfaz web es usar su navegador para visitar un repositorio existente, como por ejemplo el repositorio principal de Mercurial en http://www.selenic.com/repo/hg?style= gitweb. Si est a interesado en proveer una interfaz web a sus propios repositorios, Mercurial ofrece dos formas de hacerlo. La primera es usando la orden hg serve, que est a enfocada a servir de forma liviana y por intervalos cortos. Para m as detalles de c omo usar esta orden vea la secci on 6.4 m as adelante. Si tiene un repositorio que desea hacer disponible de forma permanente, Mercurial tiene soporte embebido para el est andar CGI (Common Gategay Interface), que es manejado por todos los servidores web comunes. Vea la secci on 6.6 para los detalles de la conguraci on a trav es de CGI.

6.2.

Modelos de colaboraci on

Con una herramienta adecuadamente exible, tomar decisiones acerca del ujo de trabajo es mucho m as un reto de ingenier a social que un problema t ecnico. Mercurial impone pocas limitaciones sobre c omo puede estructurar el 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 as importante que usted debe considerar de cualquier modelo es qu e tan bien se ajusta a las necesidades y capacidades de la gente que lo usar a. Esto puede parecer auto-evidente; a un as , usted no puede permitirse olvidarlo ni por un momento. Una vez den un modelo de ujo de trabajo que parec a ser perfectamente adecuado para m , pero que caus o una cantidad considerable de consternaci on y fricci on dentro de mi equipo de desarrollo. A pesar de mis intentos de explicar porqu e necesit abamos un conjunto complejo de ramas, y de c omo deb an uir los cambios entre ellas, algunos miembros del equipo se molestaron. Aunque ellos eran personas inteligentes, no quer an prestar atenci on a las limitaciones bajo las cuales est abamos operando, o comparar las consecuencias de esas limitaciones con los detalles del modelo que yo estaba proponiendo. No esconda bajo la alfombra los problemas sociales o t ecnicos que usted pueda preveer. Sin importar el esquema que usted use, debe hacer planes para enfrentar posibles errores o problemas. Considere a nadir procedimientos automatizados para prevenir, o recuperarse r apidamente de, los problemas que usted pueda anticipar. A manera de ejemplo, si usted planea tener una rama en la vayan los cambios que no est en listos para producci on, har a bien en pensar en la posibilidad de que alguien fusione accidentalmente dichos cambios en una rama para publicaci on. Usted podr a evitar este problema en particular escribiendo un gancho que evite que se fusionen cambios desde ramas inapropiadas.

6.2.2.

Anarqu a informal

No sugerir a un enfoque de todo vale como algo sostenible, pero es un modelo que es f acil de entender, y que funciona perfectamente bien en unas cuantas situaciones inusuales. Como un ejemplo, muchos proyectos tienen un grupo informal de colaboradores que rara vez se re unen f sicamente. A algunos grupos les gusta evitar el aislamiento de trabajar a distancia organizando sprints ocasionales. En un sprint, una cantidad de gente se re une en un mismo sitio (el cuarto de conferencias de una empresa, el cuarto de se tipo de lugares) y pasar varios d reuniones de un hotel, e as m as o menos encerrados all , trabajando intensamente en un pu nado de proyectos. 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 on 6.4 m as abajo. Luego simplemente d gale a las personas cerca suyo que usted est a ejecutando un servidor, env eles la URL a trav es de un mensaje instant aneo, y tendr a de inmediato una forma r apida de trabajar juntos. Ellos pueden escribir su URL en un navegador web y revisar sus cambios r apidamente; o ellos pueden jalar un arreglo de fallo que usted haya hecho y vericarlo; o pueden clonar una rama que contiene una nueva caracter stica y probarla. Lo bueno, y lo malo, de hacer cosas de manera ad hoc como aqu , es que s olo las personas que saben de sus cambios, y d onde est an, pueden verlos. Un enfoque tan informal sencillamente no puede escalarse m as all a de un pu nado de personas, porque cada individuo tiene que saber de n repositorios diferentes de los cuales jalar.

6.2.3.

Un repositorio central unico

Para proyectos peque nos migrando desde una herramienta centralizada de control de revisiones, tal vez la forma es tambi m as f acil de empezar es hacer que los cambios vayan a trav es de un repositorio central compartido. Este en el bloque base para esquemas m as ambiciosos de ujo de trabajo. l siempre que Los colaboradores empiezan clonando una copia de este repositorio. Ellos pueden jalar cambios de e lo necesiten, y algunos (o tal vez todos los) desarrolladores tienen permiso para empujar cambios de vuelta cuando est en listos para que los dem as los vean. Bajo este modelo, para los usuarios tiene sentido jalar cambios directamente entre ellos, sin ir a trav es del repositorio central. Considere un caso en el que yo tengo un arreglo tentativo de fallo, pero me preocupa que al publicarlo en rboles de todos los dem el repositorio central rompa los a as cuando lo jalen. Para reducir el potencial de da no, puedo 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 on 6.5. Tambi en es usual publicar una copia de s olo lectura del 60

repositorio sobre HTTP usando CGI, como en la secci on 6.6. Publicar a trav es de HTTP satisface las necesidades de 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 anea en varios frentes. En el caso del software, es com un que un proyecto tenga versiones peri odicas ociales. Una versi on puede entrar a modo mantenimiento por un tiempo despu es de su primera publicaci on; las versiones de mantenimiento tienden a contener solamente arreglos de fallos, no nuevas caracter sticas. 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 a especialmente preparado para administrar un buen n umero de ramas simult aneas pero no id enticas. Cada direcci on de desarrollo puede vivir en su propio repositorio central, y usted puede mezclar los cambios de una a otra cuando sea necesario. Dado que los repositorios son independientes entre s , los cambios inestables de una rama de desarrollo nunca afectar an una rama estable a menos que alguien mezcle expl citamente los cambios. A continuaci on hay un ejemplo de c omo podr a hacerse esto en la pr actica. Digamos que tiene una rama principal 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 on del hito.

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 as desarrollo.


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 o la versi on, la gente que clone el repositorio en el futuro puede usar hg update para obtener una copia del directorio de trabajo igual a cuando se cre o la etiqueta de la revisi on que se 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 es de que la rama principal se etiquete, alguien puede clonarla en el servidor a una nueva rama estable, tambi en en el servidor.

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 aticamente, las ramas estable y principal est an aisladas la una de la otra. Los cambios que haga en la rama 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 en. En lugar de 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 a tales arreglos por usted.

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 un contendr a los cambios que no est an en la estable y contendr a adem as todos los arreglos de fallos de la rama estable. La rama estable permanece inc olume a tales cambios.

6.2.5.

Ramas de caracter sticas

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

maestro

cripto

sistemadearchivos

ipc

memoria

red

seguridad

Figura 6.1: Ramas de Caracter sticas se equipo de caracter Cuando se considera que una caracter stica particular est a en buena forma, alguien de e sticas jala y fusiona de la rama principal a la rama de caracter sticas y empuja de vuelta a la rama principal.

6.2.6.

El tren de publicaci on

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

6.2.7.

El modelo del kernel Linux

El desarrollo del kernel Linux tiene una estructura jer arquica bastante horizontal, rodeada de una nube de caos aparente. Dado que la mayor a 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 stas ideas, la aproximaci ambiente; si le gustan e on se traduce bien de Git a Mercurial. publica un u nico repositorio que es En el centro de la comunidad est a Linus Torvalds, el creador de Linux. El rbol ocial actual por la comunidad completa de desarrolladores. Cualquiera puede clonar el a rbol considerado el a l es muy selectivo respecto a los a rboles de los cuales jala. de Linus, pero e 63

l jala todos los cambios que ellos publican, en la Linus tiene varios lugartenientes de conanza. Como regla, e mayor a de los casos sin siquiera revisarlos. Algunos de sus lugartenientes generalmente aceptan ser los mantenedores, responsables de subsistemas espec cos dentro del kernel. Si un hacker cualquiera desea hacer un cambio a un rbol de Linus, debe encontrar qui subsistema y busca que termine en el a en es el mantenedor del subsistema y solici stos pasar rbol de tarle que tome su cambio. Si el mantenedor revisa los cambios y est a de acuerdo en tomarlos, e an al 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 ositos distintos. Por ejemplo, algunas personas mantienen repositorios estables de versiones anteriores del kernel, a los cuales aplican rboles: uno para cambios arreglos de fallos cr ticos cuando es necesario. Algunos mantenedores publican varios a experimentales; uno para cambios que van a ofrecer al mantenedor principal; y as sucesivamente. Otros publican solo rbol. un a Este modelo tiene dos caracter sticas notables. La primera es que es de jalar exclusivamente. Usted debe solicitar, rboles en los cuales convencer o incluso rogar a otro desarrollador para que tome sus cambios, porque casi no hay a rbol que alguien m m as de una persona pueda publicar, y no hay forma de publicar cambios en un a as controla. La segunda es que est a basado en reputaci on y meritocracia. Si usted es un desconocido, Linus probablemente ignorar a sus cambios, sin siquiera responderle. Pero el mantenedor de un subsistema probablemente los revisara, y los acoger a en caso de que aprueben su criterio de aplicabilidad. A medida que usted ofrezca mejores cambios a un mantenedor, habr a m as posibilidad de que se conf e en su juicio y se acepten los cambios. Si usted es reconocido 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 d a con su trabajo. La reputaci on y meritocracia no necesariamente son transversales entre personas de diferentes subsistemas. Si 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 har a a un completo extra no. Personas que vienen de proyectos con un ordenamiento distinto, sienten que el proceso comparativamente ca otico del Kernel Linux es completamente lun atico. Es objeto de los caprichos individuales; la gente desecha cambios cuando 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 on publica

Una fuente perpetua de discusiones en la comunidad de c odigo abierto yace en la armaci on de que el modelo de 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. T picamente 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 e modelo va a usar: la herramienta le ofrece publicaci on compartida, y si desea hacer cualquier otra cosa, va a tener que tomar una aproximaci on articial (tal como aplicar parches a mano). Una buena herramienta de control de versiones distribuida, tal como Mercurial, soportar a los dos modelos. Usted y sus colaboradores pueden estructurar c omo trabajar an juntos basados en sus propias necesidades y preferencias, sin tener que llevar a cabo las peripecias que la herramienta les obligue a hacer.

6.2.9.

Cuando la colaboraci on encuentra la administraci on ramicada

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 a encarar un reto relacionado, pero un poco distinto: administrar las direcciones en las cuales su equipo puede moverse. A pesar de que est a ntimamente ligado acerca de c omo interact ua su equipo, este es un tema lo sucientemente denso para ameritar un tratamiento aparte, en el cap tulo 8.

64

6.3.

Aspectos t ecnicos de la colaboraci on

Lo que resta del cap tulo 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 no, acoplado gil. Tambi ya en sirve como una demostraci on de c omo se siente usar los comandos usando la red. Ejecute hg serve dentro de un repositorio, y en pocos segundos se iniciar a un servidor HTTP especializado; aceptar a conexiones desde cualquier cliente y servir a datos de este repositorio mientras lo mantenga funcionando. Todo el que conozca la URL del servidor que usted ha iniciado, y que pueda comunicarse con su computador a trav es de la red, puede usar un navegador web o Mercurial para leer datos del repositorio. Un URL para una instancia de hg serve ejecut andose en un port atil deber a lucir similar a http://my-laptop.local:8000/. La orden hg serve no es un servidor web de prop osito general. Solamente puede hacer dos cosas: Permitir la visualizaci on del historial del repositorio que est a sirviendo, desde un navegador web. Hablar el protocolo de conexi on de Mercurial, para que la gente pueda hacer hg clone o hg pull (jalar) cambios desde tal repositorio. En particular, hg serve no permitir a que los usuarios remotos modiquen su repositorio. Es de tipo s olo lectura. Si est a familiariz andose con Mercurial, no hay nada que le impida usar hg serve para servir un repositorio en rdenes como hg clone, hg incoming, para comunicarse con el su propio computador, y posteriormente usar o servidor como si el repositorio estuviera alojado remotamente. Esto puede ayudarle a adecuarse r apidamente a usar comandos en repositorios alojados en la red.

6.4.1.

Cuestiones adicionales para tener en cuenta

Dado que permite lectura sin autenticaci on a todos sus clientes, deber a usar hg serve exclusivamente en ambientes en los cu ales esto no sea importante, o en los cuales tenga control completo acerca de qui en puede acceder a 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 deber a hacer (despu es de asegurarse que tienen el URL correcto) es vericar su conguraci on de cortafuegos. De forma predeterminada, hg serve escucha conexiones entrantes en el puerto 8000. Si otro proceso est a escuchando en tal puerto, usted puede especicar un puerto distinto para escuchar con la opci on -p. Normalmente, cuando se inicia hg serve, no muestra ning un mensaje, lo cual puede ser algo desconcertante. Si desea conrmar que en efecto est a ejecut andose correctamente, y averiguar qu e URL deber a enviar a sus colaboradores, in cielo con la opci on -v.

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 a que hacer algo de conguraci on a nivel de cliente o de servidor. Si no est a familiarizado con ssh, es un protocolo de red que le permite comunicarse de manera segura con otro computador. Para usarlo con Mercurial, deber a crear una o m as cuentas de usuario en un servidor de forma tal que los rdenes. usuarios remotos puedan entrar y ejecutar o (Si ssh le es familiar, probablemente encontrar a elemental una porci on del material a continuaci on.)

65

6.5.1.
1

C omo leer y escribir URLs de ssh

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 a entrando al servidor. Puede omitirlo si el usuario 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 umero del puerto en el servidor al cual se conectar a. El predeterminado es el 22, as que solamente necesitar a especicar esa porci on si no est a usando el puerto 22. ltima porci 5. La u on del URL es la ruta local del repositorio en el servidor. El componente de la ruta del URL para ssh es una fuente de confusi on, puesto que no hay una forma est andar para que las herramientas puedan interpretarlo. Algunos programas se comportan de manera distinta a otros cuando manipulan estas rutas. No es la situaci on ideal, pero es muy poco probable que vaya a cambiar. Por favor lea los p arrafos siguientes cuidadosamente. 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 emosle otrousuario), as
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 a usando un sistema de estos, ejecute which ssh para identicar d onde est a instalada la orden ssh (usualmente estar a en /usr/bin). Si por casualidad no est a presente, vea la documentaci on de sus sistema para averiguar c omo instalarlo. En Windows, primero tendr a que descargar un cliente adecuado. Hay dos alternativas: rdenes de cliente El excelente paquete PuTTY [Tat] de Simon Tatham, que ofrece un conjunto completo de o ssh. Si tiene alta tolerancia al dolor, puede usar el porte de Cygwin para OpenSSH. En cualquier caso, tendr a que editar su chero Mercurial.ini para indicarle a Mercurial d onde encontrar la orden real del cliente. Por ejemplo, si est a usando PuTTY, tendr a que usar la orden plink como un cliente de l nea de 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 deber a contener espacios o caracteres en blanco, o Mercurial no podr a encontrarlo correctamente (por lo tanto, probablemente no ser a buena idea colocarlo en C:\Program Filesa
a N.

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

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 a de la tarea. En Windows, si est a usando PuTTY, necesitar a la orden puttygen. nica oportunidad Cuando genera un par de llaves, se aconseja comedidamente protegerlas con una frase clave. (La u en la cual usted no querr a hacerlo, es cuando est a usando el protocolo ssh para tareas automatizadas en una red segura.) No basta con generar un par de llaves. Se requiere adicionar la llave p ublica al conjunto de llaves autorizadas del usuario que usted usa para acceder a la m aquina remota. Para aquellos servidores que usen OpenSSH (la gran mayor a), signicar a a nadir la llave p ublica a la lista en el chero llamado authorized keys en su directorio .ssh. En sistemas tipo Unix, su llave p ublica tendr a la extensi on .pub. Si usa puttygen en Windows, puede guardar la llave p ublica en un chero de su elecci on, o pegarla desde la ventana en la cual se despliega directamente en el chero authorized keys.

6.5.4.

Uso de un agente de autenticaci on

Un agente de autenticaci on es un demonio que almacena frases clave en memoria (olvidar a las frases clave si sale de su sesi on y vuelve a entrar). Un cliente ssh notar a si el agente est a corriendo, y le solicitar a una frase clave. Si no hay un agente de autenticaci on corriendo, o el agente no almacena la frase clave necesaria, tendr a que teclear su 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 on si es un 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 aticamente cuando usted inicia sesi on. Tendr a que usar la orden ssh-add para a nadir frases claves al agente. En Windows, si est a usando PuTTY, la a orden pageant act ua como el agente. El nade un icono a su barra del sistema que le permitir a administrar las frases 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 podr an ir mal. A nada a eso Mercurial y hay mucho m as en qu e pensar. La mayor parte de estos problemas potenciales ocurren en el lado del servidor, no en el cliente. Las buenas noticias es que una vez tiene una conguraci on funcional, usualmente sta continuar e a trabajando indenidamente. Antes de intentar que Mercurial hable con un servidor ssh, es mejor asegurarse de que puede usar la orden normal rdenes directamente, de ssh o putty para comunicarse primero con el servidor. Si tiene problemas usando estas o seguro Mercurial no funcionar a. Pero a un, esto esconder a el problema subyacente. Cuando desee revisar un problema rdenes de ssh en el lado del cliente funcionan relacionado con ssh y Mercurial, deber a asegurarse primero que las o 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 on desde otra m aquina. Si no puede entrar usando ssh o putty, el mensaje de error que obtenga le puede dar pistas de qu e ha ido mal. Los problemas m as comunes son los siguientes: Si obtiene un error de conexi on rehusada, es posible que no haya un demonio SSH corriendo en el servidor o l debido a la conguraci que no pueda accederse a e on de cortafuegos. Si obtiene un error de no hay ruta hasta el servidor, puede tener una direcci on incorrecta para el servidor o un cortafuegos con bloqueo agresivo que negar a la existencia del servidor. 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 urese de que se est e ejecutando. En muchos sistemas estar a instalado, pero deshabilitado de forma predeterminada. Una vez que haya hecho esto tendr a que revisar si el cortafuegos del servidor est a congurado para recibir conexiones entrantes en el puerto en el cual est a escuchando el demonio de ssh (usualmente el 22). No trate de buscar otras posibilidades ex oticas o conguraciones erradas hasta que haya revisado primero estas dos. Si est a usando un agente de autenticaci on en el lado del cliente para almacenar las frase claves de sus contrase nas, deber a poder entrar al servidor sin necesidad de que se le soliciten frases claves o contrase nas. Si se le pregunta alguna, a continuaci on algunas posibilidades: 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 a ni leer a su chero authorized keys. Por ejemplo, un directorio personal o .ssh con permisos de escritura para grupo mostrar a a veces este s ntoma. El chero authorized keys del usuario puede tener un problema. Si alguien distinto al usuario es due no del l y no lo leer mismo o puede escribir en el chero, el demonio ssh no conar a en e a. En un mundo ideal, deber a poder ejecutar la siguiente orden exitosamente, y deber a imprimir exactamente una l nea de salida, la fecha y hora actual.
1

ssh miservidor date Si en su servidor tiene gui on que se ejecuta a la entrada e imprime letreros o cualquier otra cosa, incluso cuando se rdenes no interactivas como esta, deber ejecutan o a arreglarlo antes de continuar, de forma que solamente imprima algo si se ejecuta interactivamente. De otra forma estos letreros al menos llenar an la salida de Mercurial. Incluso podr an rdenes de forma remota. Mercurial intenta detectar e ignorar los causar problemas potenciales cuando se ejecuten o 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 on de l nea de comandos se ejecuta en un int erprete interactivo es vericar el c odigo de retorno de la orden tty -s.) 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 deber a ejecutarse satisfactoriamente:

ssh miservidor hg version Si ve un mensaje de error en lugar de la salida usual de hg version, ser a porque Mercurial no fue instalado en /usr/bin. Si este es el caso, no se preocupe; no necesita hacerlo. Pero deber a revisar los posibles problemas: Est a instalado Mercurial en el servidor? S e que suena trivial pero es mejor revisar! rdenes (normalmente v Tal vez la ruta de b usqueda de la interfaz de o a la variable de entorno PATH) simplemente est a mal congurada. Puede ser que su variable de ambiente PATH solamente apunte al lugar en el cual est a el ejecutable hg si la sesi on de entrada es interactiva. Esto puede suceder si establece la ruta en el gui on de l nea de comandos de entrada rdenes. incorrecto. Consulte la documentaci on de su int erprete de o La variable de ambiente PYTHONPATH puede requerir contener la ruta a los m odulos de Mercurial en Python. nicamente cuando Puede que ni siquiera est a establecida; podr a estar incorrecta; o puede ser que se establezca u hay entradas interactivas. Si puede ejecutar hg version sobre una conexi on ssh, felicitaciones! Ha logrado la interacci on entre el cliente y el servidor. Ahora deber a 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 on --debug para tener informaci on m as clara de lo que est a sucediendo. 68

6.5.6.

Compresi on con ssh

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 on. Sobre cualquier red distinta a una LAN r apida (incluso con una red inal ambrica), hacer uso de compresi on puede mejorar el rendimiento de las operaciones de Mercurial que involucren la red. Por ejemplo, sobre WAN, alguien ha medido que la compresi on reduce la cantidad de tiempo requerido para clonar un repositorio particularmente grande de 51 minutos a 17 minutos. Tanto ssh como plink aceptan la opci on -C para activar la compresi on. Puede editar f acilmente su hgrc para habilitar la compresi on para todos los usos de Mercurial con el protocolo ssh.
1 2

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

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 a que ssh se conecte a hg.ejemplo.com usando compresi on. Esto le brindar a un nombre m as corto para teclear, junto con compresi on, los cuales por derecho propio son buenos.

6.6.

Servir sobre HTTP usando CGI

Dependiendo de qu e tan ambicioso sea, congurar la interfaz CGI de Mercurial puede tomar desde unos minutos hasta varias horas. Comenzaremos con el ejemplo m as sencillo, y nos dirigiremos hacia conguraciones m as complejas. Incluso para el caso m as b asico necesitar a leer y modicar la conguraci on de su servidor web. 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 on y juicio respecto a las siguientes secciones. Prep arese para cometer muchas equivocaciones, y emplear bastante tiempo leyendo las bit acoras de error de su servidor.

6.6.1.

Lista de chequeo de la conguraci on del servidor web

Antes de continuar, t omese un tiempo para revisar ciertos aspectos de la conguraci on de su sistema: 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 a ejecut andose? En la mayor a de sistemas, aunque est e presente, puede no estar habilitado de forma predeterminada. 3. Est a congurado su servidor para permitir ejecutar programas CGI en el directorio donde planea hacerlo? Casi todos los servidores de forma predeterminada deshabilitan expl citamente la habilidad de ejecutar programas CGI.

69

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

6.6.2.

Conguraci on b asica de CGI

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

cp .../hgweb.cgi /public_html chmod 755 /public_html/hgweb.cgi El argumento 755 de la orden chmod es un poco m as general que hacerlo ejecutable: asegura que el gui on sea ejecutable 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 negar a a ejecutar el gui on. De hecho, suexec tambi en insiste en que el directorio en el cual reside el gui on no tenga permiso de escritura para otros.

chmod 755 /public_html

Qu e podr a resultar mal? 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, podr a toparse con cada uno de los errores que describimos a continuaci on, as que no deje de leerlos cuidadosamente. A continuaci on presento los problemas que yo tuve en un sistema con Fedora 7, con una instalaci on nueva de Apache, y una cuenta de usuario que cre e espec camente para desarrollar este ejercicio. Su servidor web puede tener directorios por usuario deshabilitados. Si usa Apache, busque el chero de conguraci on que contenga la directiva UserDir. Si no est a presente en sitio alguno, los directorios por usuario est an deshabilitados. Si la hay, pero su valor es disabled, los directorios por usuario estar an deshabilitados. En caso contrario, la directiva UserDir tendr a el nombre del subdirectorio bajo el cual Apache mirar a en el directorio de cada 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 en bajo public html, adem as de tener permiso para leer aquellos que est en adentro. A continuaci on una receta r apida para hacer que sus permisos est en acordes con las necesidades b asicas.
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 on. En este caso, es posible que los permisos que tiene son demasiado permisivos. El subsistema suexec de Apache no ejecutar a un gui on que tenga permisos de escritura para el grupo o el planeta, por ejemplo. Su servidor web puede estar congurado para evitar la ejecuci on de programas CGI en los directorios de usuario. A continuaci on presento una conguraci on predeterminada por usuario en mi sistema Fedora. 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 on de Apache, la directiva a revisar 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 on CGI en lugar de ejecutarlo, necesitar a o bien descomentar (si 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 odulo relacionado con mercurial. Esto es un gran progreso! El servidor es capaz de ejecutar su gui on CGI. Este error solamente ocurrir a si est a ejecutando una instalaci on privada de Mercurial en lugar de una instalaci on para todo el 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 on interactiva. Si este error le ocurre, edite su copia de hgweb.cgi y siga las indicaciones dentro 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 a que no puede encontrar /path/to/repository1 . Edite su gui on hgweb.cgi y reemplace la cadena /path/to/repository con la ruta completa al repositorio que desea servir. En este punto, cuando trate de recargar la p agina, deber a tener una linda vista HTML del historial de su repositorio. Uff! Conguraci on de lighttpd En mi intenci on de ser exhaustivo, intent e congurar lighttpd, un servidor web con creciente aceptaci on, para servir los repositorios de la misma forma en que lo describ anteriormente con Apache. Ya super e los problemas que mostr e con Apache, muchos de los cu ales no son espec cos del servidor. Por lo tanto estaba seguro de que mis permisos para directorios y cheros eran correctos y que mi gui on hgweb.cgi tambi en lo era. Dado que ya Apache estaba en ejecuci on correctamente, lograr que lighttpd sirviera mi repositorio fue r apido (en otras palabras, si est a tratando de usar lighttpd, deber a leer la secci on de Apache). Primero tuve que editar la secci on mod access para habilitar mod cgi y mod userdir, los cuales estaban inhabilitados en mi instalaci on predeterminada. A nad posteriormente unas l neas al nal del chero de conguraci on, para hacer lo propio con los m odulos.

1 2

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

del T. Ruta al repositorio.

71

6.6.3.

Compartir varios repositorios con un gui on CGI

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

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

1 2

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

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 a en el URL) est a en el lado derecho de cada denici on, mientras que la ruta al repositorio est a a la derecha. Note que no tiene que haber relaci on alguna entre la ruta virtual que elija y el lugar del repositorio en su sistema de cheros. Si lo desea, puede usar tanto collections como paths simult aneamente en un solo chero de conguraci on. Nota: Si varios repositorios tienen la misma ruta virtual, hgwebdir.cgi no reportar a ning un error. Pero se comportar a de manera impredecible.

6.6.4.

Descarga de cheros fuente

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

6.6.5.

Opciones de conguraci on en Web

Las interfaces web de Mercurial (la orden hg serve, y los guiones hgweb.cgi y hgwebdir.cgi) tienen varias opciones de conguraci on disponibles. Todas ellas van en la secci on [web]. e mecanismos de descarga soportar a Mercurial. Si habilita esta caracter stica, los usuarios de allow archive Determina qu la interfaz web podr an descargar una copia de la revisi on del repositorio que est en viendo. Para activar la caracter stica de descarga de conjunto, el valor tendr a una secuencia de palabras extra das de la lista de abajo. bz2 Un chero tar con el m etodo de compresi on bzip2. Tiene la mejor tasa de compresi on, pero usa m as 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 on, pero es muy usado en el mundo Windows. Si da una lista vac a o no tiene la entrada allow archive, esta caracter stica se deshabilitar a. A continuaci on se presenta un ejemplo de c omo habilitar los tres formatos soportados.
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 on de los procesos orientados-ahumanos 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 on de correo electr onico de una persona o de una lista de correo. A veces tiene sentido colocar esta opci on en el chero .hg/hgrc del repositorio, pero en otras nico mantenedor. oportunidades es mejor hacerlo en el hgrc global si todos los repositorios tienen un u maxchanges Entero. La cantidad m axima de conjuntos de cambios a mostrar de forma predeterminada en cada p agina. maxfiles Entero. La cantidad m axima predeterminada de cheros modicados a desplegar en una p agina. stripes Entero. Si la interfaz web despliega franjas para facilitar la visualizaci on alineada de las cuando se ve una 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 as atractiva visualmente). Puede especicar una plantilla propia; consulte el cap tulo 11. A continuaci on mostramos c omo habilitar el estilo gitweb. 73

1 2

[web] style = gitweb

templates Ruta. Directorio en el que se buscar an los cheros plantilla. De forma predeterminada, el gui on busca en el directorio en el cual fue instalado. Si usa hgwebdir.cgi, puede a nadir otras opciones de conguraci on en la secci on [web] del chero hgweb.config en lugar del chero hgrc si lo considera m as conveniente. Estas opciones son motd y style. Opciones espec cas para repositorios individuales Ciertas opciones de conguraci on de [web] deben estar ubicadas en el .hg/hgrc de un repositorio en lugar del chero del usuario o el hgrc global. description Cadena. Una cadena de forma libre (preferiblemente corta) que describa los contenidos o el prop osito del repositorio. name Cadena. El nombre para visualizar en la interfaz web del repositorio. Sustituye el nombre predeterminado, el ltimo componente de la ruta del repositorio. cual es el u Opciones espec cas a la orden hg serve Algunas opciones en la secci on [web] de un chero hgrc son de uso exclusivo de la orden hg serve. accesslog Ruta. El nombre del chero en el cual se escribe la bit acora de acceso. En principio, la orden hg serve escribe esta informaci on a la salida est andar, no a un chero. Las l neas de la bit acora se escriben en un formato de chero combinado est andar, usado por casi todos los servidores web. address Cadena. La direcci on local en la cual el servidor debe escuchar peticiones entrantes. De forma predeterminada, el servidor escucha en todas las direcciones. errorlog Ruta. El nombre de un chero en el cual escribir la bit acora de error. En principio, la orden hg serve escribe esta informaci on en la salida de error est andar, no a un chero. ipv6 Booleano. Si se usa o no el protocolo IPv6. IPv6 no se usa de manera predeterminada. port Entero. El n umero del puerto TCP en el cu al el servidor esperar a conexiones. El puerto predeterminado es 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 a bajo un ID de usuario que generalmente no es el suyo Los guiones CGI ejecutados por su servidor, tales como hgweb.cgi, se ejecutar an tambi en se ID de usuario. con e Si a nade opciones [web] a su chero personal hgrc los guiones CGI no leer an tal chero hgrc. Tales conguraciones solamente afectar an el comportamiento de la orden hg serve cuando usted la ejecuta. Para logar que los 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 nada tales opciones al chero global hgrc.

74

Cap tulo 7

Nombres de cheros y asociaci on de 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 o para manejar nombres de cheros. Cada comando se comporta de manera uniforme con respecto a los nombres de chero. La manera en que los comandos operan con nombres de chero es la siguiente. nicamente Si usted especica expl citamente nombres reales de cheros en la l nea de comandos, Mercurial opera u sobre dichos cheros, como usted esperar a.
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 etico. Cuando encuentra un subdirectorio, lo recorrer a antes de continuar con el directorio actual.

1 2 3 4 5

$ ? ? ? ?

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

7.2.

nombre de chero Ejecuci on de comandos sin ningun

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

75

Si el comando tiene efectos dif ciles o incluso imposibles de revertir, se le obligar a a usted a proveer expl citamente al menos un nombre o patr on (ver m as abajo). Esto lo proteje a usted de, por ejemplo, borrar cheros accidentalmente al ejecutar hg remove sin ning un argumento. Es f acil evitar este comportamiento por defecto, si no es el adecuado para usted. Si un comando opera normalmente en todo el directorio de trabajo, usted puede llamarlo para que trabaje s olo en el directorio actual y sus subdirectorio pas andole el nombre ..
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 l nea, algunos comandos normalmente imprimen las rutas de cheros con respecto a la ra z del repositorio, a un si usted los llama dentro de un subdirectorio. Dichos comandos imprimir an las rutas de los cheros respecto al directorio en que usted se encuentra si se les pasan nombres expl citos. 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 andole la salida del comando hg root.

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 a pasando

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

7.4.

Uso de patrones para identicar cheros

Adem as de trabajar con nombres de cheros y directorios, Mercurial le permite usar patrones para identicar 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 erprete de comandos. En estos sistemas, usted debe indicarle expl citamente a Mercurial que el nombre que se le pasa es un patr on. En Windows, el int erprete no expande los patrones, as que Mercurial identicar a autom aticamente los nombres que son patrones, y har a la expansi on necesaria. Para pasar un patr on en vez de un nombre normal en la l nea de comandos, el mecanismo es simple:
1

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

7.4.1.

Patrones glob estilo int erprete

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

$ hg add glob:*.py adding main.py La secuencia ** se asocia con cualquier cadena, y cruza los l mites de los directorios. No es una elemento til. est andar de los tokens de glob de Unix, pero es aceptado por varios int erpretes Unix populares, y es muy u

1 2

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

del T. Grupo, colecci on, aglomeraci on. 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 ultiples rangos de la forma a-f, que en este caso es una abreviaci on para abcdef.

1 2 3

$ hg status glob:**[nr-t] ? MANIFEST.in ? src/xyzzy.txt Si el primer caracter en aparecer despu es de [ en la clase de caracteres es un !, se niega la clase, haciendo que se 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 on en 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 on con cualquier directorio, no deber a usar el elemento para asociar ste s con cualquier cadena *, ya que e olo generar a asociaciones dentro de un solo directorio. En vez de eso, use el caracter para asociar con cualquier cadena **. Este peque no ejemplo ilustra la diferencia entre los dos.

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 on con patrones de expresiones regulares re

Mercurial acepta la misma sintaxis para expresiones regulares del lenguaje de programaci on Python (internamente se usa el motor de expresiones regulares de Python). Esta sintaxis est a basada en la misma del lenguaje Perl, que es el dialecto m as popular en uso (por ejemplo, tambi en se usa en Java). No discutir e el dialecto de expresiones regulares de Mercurial en detalle aqu , ya que las mismas no son usadas 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 e en unas cuantas cosas que usted deber a conocer si tiene la necesidad de usar expresiones regulares en Mercurial. 78

Una expresi on regular es comparada contra un nombre de chero completo, relativo a la ra z del repositorio. En otras palabras, a un si usted se encuentra en un subdirectorio foo, si desea asociar cheros en este directorio, su patr on 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 an enra zadas. Esto es, que la asociaci on de una expresi on se hace desde el inicio de la cadena; no se buscan coincidencias dentro de la cadena. Para buscar coincidencias en cualquier sitio dentro de una cadena, empiece su patr on con un .*.

7.5.

Filtrado de cheros

Mercurial no s olo le provee una variedad de formas para especicar cheros; le permite limitar a un m as dichos 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 on con el que deben coincidir los cheros para ser procesados. -X, o --exclude, le brinda una manera de evitar procesar cheros, si coinciden con este patr on. Usted puede pasar m ultiples veces las opciones -I y -X en la l nea de comandos, e intercalarlos como desee. Por 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 nicamente los cheros que no coincidan con este patr El ltro -X puede verse como procese u on.

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 a trabajando en un ambiente de desarrollo mixto que contiene tanto sistemas Linux (u otro Unix) y sistemas Mac o Windows, deber a 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 usculas. Los nombres de chero son traducidos para que puedan ser almacenados de manera segura tanto en a may sistemas sensibles como insensibles a may usculas. Esto signica que usted puede usar herramientas normales de 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 on de conictos de mayusculas/min usculas

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

7.7.3.

Arreglar un conicto de mayusculas/min usculas

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

80

Cap tulo 8

Administraci on de versiones y desarrollo ramicado


Mercurial ofrece varios mecanismos que le permiten administrar un proyecto que avanza en m ultiples frentes simult aneamente. Para entender estos mecanismos, demos un vistazo a la estructura usual de un proyecto de software. Muchos proyectos de software liberan una versi on mayor que contiene nuevas caracter sticas substanciales. En stas son id paralelo, pueden liberar versiones menores. Usualmente e enticas a las versiones mayores en las cuales est an basadas, pero con arreglos para algunos fallos. En este cap tulo, comenzaremos hablando de c omo mantener registro de etapas del proyecto como las liberaciones de una versi on. Continuaremos hablando del ujo de trabajo entre las diferentes fases de un proyecto, y c omo puede ayudar Mercurial a aislar y administrar tal trabajo.

8.1.

Dar un nombre persistente a una revisi on

Cuando usted decide otorgar a una revisi on el nombre particular de una versi on, es buena idea grabar la identidad de tal revisi on. Esto le permitir a reproducir dicha versi on en una fecha posterior, para cualquiera que sea el prop osito 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 on usando la orden hg tag. Sin causa de sorpresa, esos nombres se llaman tags (etiquetas).

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

Nueva l nea (ASCII 10, \n) Puede usar la orden hg tags para ver las etiquetas presentes en su repositorio. Al desplegarse, cada revisi on nico de la marcada se identica primero con su nombre, despu es con el n umero de revisi on y nalmente con un hash u revisi on.
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 on m as reciente en el repositorio. Al desplegar la orden hg tags, las etiquetas se listan en orden inverso, por n umero de revisi on. Lo que signica usualmente que las etiquetas m as recientes se listan antes que las m as antiguas. Tambi en signica que la etiqueta tip siempre aparecer a como primera etiqueta listada al desplegar la orden hg tags. Cuando usted ejecuta hg log, si se muestra una revisi on que tenga etiquetas asociadas a ella, se imprimir an 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 on a una orden de Mercurial, aceptar a un nombre de etiqueta en su lugar. Internamente, Mercurial traducir a su nombre de etiqueta en el ID de revisi on correspondiente, y lo usar 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 l mites en la cantidad de etiquetas por repositorio, o la cantidad de etiquetas que una misma revisi on pueda tener. Siendo pr acticos, no es muy buena idea tener demasiadas (la cantidad variar a de un proyecto a otro), debido a que la intenci on es ayudarle a encontrar revisiones. Si tiene demasiadas etiquetas, la facilidad de usarlas para identicar revisiones disminuir a r apidamente. Por ejemplo, si su proyecto tiene etapas (milestones) frecuentes, de pocos d as, es perfectamente razonable asignarle una etiqueta a cada una de ellas. Pero si tiene un sistema de construcci on autom atica de binarios que asegura 82

que cada revisi on puede generarse limpiamente, estar a introduciendo mucho ruido si se usara una etiqueta para cada generaci on exitosa. M as bien, podr a usar tags para generaciones fallidas (en caso de que estas sean raras!), o simplemente evitar las etiquetas para llevar cuenta de la posibilidad de generaci on de binarios. 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 en puede modicar una etiqueta en cualquier momento, para que identique una revisi on distinta, simplemente usando una nueva orden hg tag. Deber a usar la opci on -f para indicarle a Mercurial que realmente desea actualizar 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 a un registro permanente de la antigua identidad de la etiqueta, pero Mercurial no la usar a. nico que debe hacer es mover la Por lo tanto no hay problema al marcar con una etiqueta una revisi on incorrecta; lo u etiqueta hacia la revisi on correcta tan pronto como localice el error. Mercurial almacena las etiquetas en un chero controlado por revisiones en su repositorio. Si ha creado etiquetas, las encontrar a en un chero llamado .hgtags. Cuando invoca la orden hg tag, Mercurial modica este chero, y hace la consignaci on del cambio al mismo autom aticamente. Esto signica que cada vez que ejecuta hg tag, ver a un conjunto de cambios correspondiente en la salida de hg log.

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 on

Usualmente no tendr a que preocuparse por el chero .hgtags, pero a veces hace su aparici on durante una fusi on. El formato del chero es sencillo: Consiste de una serie de l neas. Cada l nea comienza con un hash de conjunto de cambios, seguido por un espacio, seguido por el nombre de una etiqueta. Si est a resolviendo un conicto en el chero .hgtags durante una fusi on, hay un detalle para tener en cuenta al 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 on consignada m as reciente del chero. Una consecuencia desafortunada de este dise no es que usted no puede vericar que su chero .hgtags fusionado sea correcto hasta despu es de haber consignado un cambio. As que si se encuentra resolviendo un conicto en .hgtags durante una fusi on, aseg urese de ejecutar la orden hg tags despu es de consignar. Si encuentra un error en el chero .hgtags, la orden reportar a el lugar del error, que podr a arreglar y despu es consignar. Posteriormente 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 on -r que le permite clonar una copia exacta del repositorio hasta un conjunto de cambios espec co. El nuevo clon no tendr a historial posterior a la revisi on que usted haya especicado. Esto tiene una interacci on con etiquetas que puede sorprender a los desprevenidos. Recuerde que una etiqueta se almacena como una revisi on al chero .hgtags, as que cuando usted crea una eti sta se almacena necesariamente se reere a un conjunto de cambios anterior. queta, el conjunto de cambios en el cual e Cuando ejecuta hg clone -r foo para clonar un repositorio hasta la etiqueta foo, el nuevo clon no contendr a el historial que creo la etiqueta que us o para clonar el repositorio. El resultado es que tendr a exactamente el subconjunto correcto del historial del proyecto en el nuevo repositorio, pero, no la etiqueta que podr a haber esperado.

8.1.3.

Cuando las etiquetas permanentes son demasiado

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

8.2.

El ujo de cambiosEl gran cuadro vs. el pequeno

Retomando lo mencionado en el comienzo de un cap tulo, pensemos en el hecho de que un proyecto tiene muchas piezas concurrentes de trabajo en desarrollo al mismo tiempo. ltima versi Puede haber prisa por una nueva versi on principal; una nueva versi on con un arreglo de fallo a la u on; y una versi on de mantenimiento correctivo a una versi on antigua que ha entrado en modo de mantenimiento. 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 ericamente, pero que en esencia comparten un nombre. El gran cuadro Las ramas representan un barrido de la evoluci on del proyecto; la gente les da nombres y hablan acerca de ellas en sus conversaciones. El cuadro peque no Las ramas son artefactos de las actividades diarias de desarrollar y fusionar cambios. Exponen la narrativa de c omo se desarroll o el c odigo.

8.3.

Administrar ramas en repositorios estilo gran cuadro

En Mercurial la forma m as sencilla de aislar una rama del gran cuadro es a trav es de un repositorio dedicado. Si cuenta con un repositorio compartido existente llam emoslo myprojectque alcanz o la etapa 1.0, puede comenzar a prepararse para versiones de mantenimiento futuras a partir de la versi on 1.0 marcando con una etiqueta la revisi on con la cual prepar o la versi on 1.0.
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 on de un fallo deber a dirigirse a la liberaci on de versi on 1.0.1 que viene en camino, ellos clonar an el repositorio myproject-1.0.1, har an sus cambios y los empujar an 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 on mayor puede continuar aislado e inc olume, en el repositorio 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 on entre ramas

En muchos casos, cuando tiene un fallo para arreglar en una rama de mantenimiento, es muy probable que el fallo tambi en est e en la rama principal (y posiblemente en otras ramas de mantenimiento tambi en). Solamente un desarrollador extra no desear a corregir el mismo fallo muchas veces, por tanto, veremos varias alternativas con las que Mercurial puede ayudarle a administrar tales arreglos de fallo sin duplicar su trabajo. En el caso m as sencillo, basta con jalar los cambios de la rama de mantenimiento a la rama objetivo en su clon 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 on deber a mezclar las cabezas de las dos ramas, y empujar de nuevo a la rama principal.

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 on correcta en casi todas las oportunidades es aislar las ramas en los repositorios. Es f acil de entender gracias a su simplicidad; y es dif cil cometer errores. Hay una relaci on uno a uno entre las ramas y los directorios con los que est a trabajando en su sistema. Esto le permite usar emplear herramientas usuales (que no son conscientes de Mercurial) para trabajar con los cheros dentro de una rama/repositorio. Si se encuentra m as en la categor a usuario diestro (y sus colaboradores tambi en), puede considerar otra alternativa para administrar las ramas. He mencionado con anterioridad la distinci on a nivel humano entre las ramas estilo cuadro peque no y gran cuadro. Mientras que Mercurial trabaja con muchas ramas del estilo cuadro peque no en el repositorio todo el tiempo (por ejemplo cuando usted jala cambios, pero antes de fusionarlos), tambi en puede 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 on, busque la l nea que contiene el texto HG: branch default al nal. Le est a indicando que su consignaci on ocurrir a en la rama llamada default. Use la orden hg branches para empezar a trabajar con ramas nombradas. Esta orden mostrar a las ramas presentes en su repositorio, indic andole qu e conjunto de cambios es la punta de cada una.
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

nica que ver Dado que todav a no ha creado ramas nombradas, la u a ser a default. Para hallar cu al es la rama actual, invoque la orden hg branch, sin argumento alguno. Le informar a en qu e rama 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 es de crear la rama, usted podr a desear ver el efecto que tuvo la orden hg branch. Qu e reportan las 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 nadido nada al historial. Esto sugiere que al ejecutar la orden hg branch no hay un efecto permanente; solamente le indica a que nombre de rama usar a la pr oxima vez que consigne un conjunto de cambios. Cuando consigna un cambio, Mercurial almacena el nombre de la rama en la cual consign o. Una vez que haya cambiado de la rama default y haya consignado, ver a que el nombre de la nueva rama se mostrar a cuando use la rdenes que desplieguen la misma clase de informaci orden hg log, hg tip, y otras o on.
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

rdenes del tipo hg log imprimir Las o an el nombre de la rama de cualquier conjunto de cambios que no est e en la rama default. Como resultado, si nunca usa ramas nombradas, nunca ver a esta informaci on. Una vez que haya nombrado una rama y consignado un cambio con ese nombre, todas las consignaciones subsecuentes que desciendan de ese cambio heredar an el mismo nombre de rama. Puede cambiar el nombre de una rama en 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 a muy seguido en la pr actica, debido que los nombres de las ramas tienden a tener vidas largas. (Esto no es una regla, solamente una observaci on.)

8.6.

Tratamiento de varias ramas nombradas en un repositorio

Si tiene m as de una rama nombrada en un repositorio, Mercurial recordar a la rama en la cual est a su directorio de trabajo cuando invoque una orden como hg update o hg pull -u. Se actualizar a su directorio de trabajo actual a la punta de esta rama, sin importar cu al sea la punta a lo largo del repositorio. Para actualizar a una revisi on que est a en una rama con distinto nombre, puede necesitar la opci on -C de hg update. Este comportamiento puede ser sutil, as que ve amoslo en acci on. Primero, recordemos en qu e rama estamos trabajando, y qu e ramas est an en nuestro repositorio.
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 as antigua llamada hg foo. Podemos hacer hg update entre los tipos de las ramas foo y bar sin necesidad de usar la opci on -C, puesto que esto solamente implica ir linealmente hacia adelante y atr as en nuestro historial de cambios.

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 a en foo, sin movernos a la punta de 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 a una nueva cabeza.

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 etricas. Supongamos que su repositorio tiene dos 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 on, y 23 como el segundo. Mientras que si hago hg update a 23 y despu es aplico hg merge con 17, grabar a a 23 como el primer padre, y 17 como el segundo. Esto afecta el c omo elige Mercurial el nombre de la rama cuando usted hace la fusi on. Despu es de una fusi on, Mercurial mantendr a el nombre de la rama del primer padre cuando consigne el resultado de la fusi on. Si el primer nombre de su padre es foo, y fusiona con bar, el nombre de la rama continuar a siendo foo despu es de fusionar. 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 en. Consignamos cambios distintos; yo jalo sus cambios; Ahora tengo nica cabeza en la rama foo dos cabezas, cada una armando estar en la rama foo. El resultado de una fusi on ser a una u como usted esperar a. Pero si estoy trabajando en la rama bar, y fusiono el trabajo de la rama foo, el resultado permanecer a en la rama 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 as concreto, si yo estoy trabajando en la rama bleeding-edge, y deseo traer los arreglos m as recientes de la rama estable, Mercurial elegir a el nombre de rama correcto (bleeding-edge) cuando yo jale una fusi on desde estable.

8.8.

nombrar ramas Normalmente es util

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

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

90

Cap tulo 9

Encontrar y arreglar sus equivocaciones


Errar es humano, pero tratar adecuadamente las consecuencias requiere un sistema de control de revisiones de primera categor a. En este cap tulo, discutiremos algunas t ecnicas que puede usar cuando encuentra que hay un problema enraizado en su proyecto. Mercurial tiene unas caracter sticas poderosas que le ayudar an a isolar las fuentes de los problemas, y a dar cuenta de ellas apropiadamente.

9.1.
9.1.1.

Borrar el historial local


La consignaci on accidental

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

9.1.2.

Hacer rollback una transacci on

En la secci on 4.2.2, mencion e que Mercurial trata modicaci on a un repositorio como una transacci on. Cada vez 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 on 9.1.4 una anotaci on importante acerca del uso de esta orden.) A continuaci on una equivocaci on que me sucede frecuentemente: consignar un cambio en el cual he creado un 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 es de la consignaci on conrma inmediatamente este error.


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 on captur o los cambios en el chero a, pero no el nuevo chero b. Si yo publicara este conjunto de cambios a un repositorio compartido con un colega, es bastante probable que algo en a se reriera a b, el cual podr a no estar presente cuando jalen mis cambios del repositorio. Me convertir a el sujeto de cierta indignaci on. Como sea, la suerte me acompa naEncontr e mi error antes de publicar el conjunto de cambios. Uso la orden hg ltimo conjunto de cambios. rollback, y Mercurial hace desaparecer el u
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 a en el historial del repositorio, y el directorio de trabajo cree que el chero a ha sido modicado. La consignaci on y el roll back dejaron el directorio de trabajo exactamente como estaba antes de la consignaci on; el conjunto de cambios ha sido eliminado totlamente. Ahora puedo hacer hg add al chero b, y hacer de nuevo la consignaci on.

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 actica com un con Mercurial. Su equipo de desarrollo puede tener un repositorio compartido para la versi on 0.9 y otra con cambios distintos para la versi on 1.0. 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 on 1.0 en este. En el peor de los casos, por falta de atenci on, es rbol compartido 0.9, confundiendo a todo su equipo de trabajo (pero no posible que publique tales cambios en el a se preocupe, volveremos a este terror co escenario posteriormente). En todo caso, es muy probable que usted se de cuenta inmediatamente, dado que Mercurial mostrar a el URL de donde est a jalando, o que vea jalando una sospechosa gran cantidad de cambios en el repositorio. La orden hg rollback excluir a ecientemente los conjuntos de cambios que haya acabado de jalar. Mercurial nica transacci agrupa todos los cambios de un hg pull a una u on y bastar a con un hg rollback para deshacer esta equivocaci on.

9.1.4.

Despu es de publicar, un roll back es futil

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 on de un cambio se propague entre repositorios. 92

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

9.1.5.

Solamente hay un roll back

Mercurial almacena exactamente una transacci on en su bit acora de transacciones; tal transacci on es la m as reciente de las que haya ocurrido en el repositorio. Esto signica que solamente puede hacer roll back a una transacci on. Si espera poder hacer roll back a una transacci on despu es al antecesor, observar a que no es el comportamiento que 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 on a un repositorio, no podr a volver a hacer rollback hasta que haga una consignaci on o haya jalado.

9.2.

Revertir un cambio equivocado

Si modica un chero y se da cuenta que no quer a realmente cambiar tal chero, y todav a 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 ua la orden hg revert con un ejemplo peque no. Comenzaremos modicando un chero al cual Mercurial ya est a siguiendo.
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 on .orig.
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 as detalle en la secci on siguiente. Si usted modica un chero, lo restaurar a a su estado sin modicaci on previo. Si usted hace hg add a un chero, revertir a el estado de adicionado del chero, pero no lo tocar a Si borra un chero sin decirle a Mercurial, restaurar a el chero con sus contenidos sin modicaci on. Si usa la orden hg remove para eliminar un chero, deshar a el estado removido del chero, y lo restaurar a con sus contenidos sin modicaci on.

9.2.1.

Errores al administrar cheros

til para m La orden hg revert es u as que cheros modicados. Le permite reversar los resultados de todas las rdenes de administraci o on de cheros que provee Mercurialhg add, hg remove, y las dem as. Si usted hace hg add a un chero, y no deseaba que Mercurial le diera seguimiento, use hg revert para deshacer la adici on. No se preocupe; Mercurial no modicar a de forma alguna el chero. Solamente lo desmarcar 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 ten a la revisi on padre del directorio de trabajo.
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 terminolog a 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 o permanece en su directorio de trabajo, pero sin 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 as como agregado, pero el chero con el nombre-inicial se elimna! Esto es contra-intuitivo (por lo menos para m ), pero por lo menos es f acil arreglarlo.
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 osito, si elimina un chero, y modica el chero con el nuevo nombre, al revertir ambos componentes del renombramiento, cuando Mercurial restaure el chero que fue eliminado como parte del renombramiento, no ser a modicado. Si necesita que las modicaciones en el chero destino del renombramiento se muestren, no olvide 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 aticamente, y construir bloques que le permitan revertir parte de un conjunto de cambios a mano. Antes de leer esta secci on, hay algo para tener en cuenta: la orden hg backout deshace cambios adicionando al historial, sin modicar o borrar. Es la herramienta correcta si est a arreglando fallos, pero no si est a tratando de deshacer alg un cambio que tiene consecuencias catastr ocas. Para tratar con esos, vea la secci on 9.4.

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 on de la orden hg backout es un poco intrincada, y lo ilustraremos con algunos ejemplos. Primero 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 a un editor de texto para escribir el mensaje de la consignaci on, para dejar un registro de por qu e est a retrocediendo. En este ejemplo, colocamos un mensaje en la consignaci on usando la opci on -m.

9.3.2.

Retroceder el conjunto de cambios punta

ltimo conjunto de cambios que consignamos. Comenzamos retrocediendo el u


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 l nea de myfile ya no est a presente. La salida de hg log nos da una idea de lo que la 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 as sencillo de ver en la gura 9.1, que presenta una vista gr aca del historial de cambios. Como puede ver, el historial es bonito y lineal.

9.3.3.

Retroceso de un cambio que no es la punta

ltimo que ha consignado, use la opci Si desea retrocede un cambio distinto al u on --merge a la orden hg backout.
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 olo tiro, una operaci on que resulta normalmente r apida y sencilla.

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 es de nalizar el retroceso, ver a que el primer y el tercer cambio est an presentes, pero no el segundo.

1 2 3

$ cat myfile first change third change Como lo muestra el historial gr aco en la gura 9.2, Mercurial realmente consigna dos cambios en estas situaciones (los nodos encerrados en una caja son aquellos que Mercurial consigna automaticamente). Antes de que Mercurial comience el proceso de retroceso, primero recuerda cu al es el padre del directorio de trabajo. Posteriormente hace un 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 on.

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 quer a evitar. Use siempre la opci on --merge De hecho, dado que la opci on --merge siempre hara lo correcto est e o no retrocediendo el conjunto de cambios punta (p.e. no tratar a de fusionar si est a retrocediendo la punta, dado que no es necesario), usted deber a usar siempre esta opci on cuando ejecuta la orden hg backout.

9.3.4.

M as control sobre el proceso de retroceso

A pesar de que recomiendo usar siempre la opci on --merge cuando est a retrocediendo un cambio, la orden hg backout le permite decidir c omo mezclar un retroceso de un conjunto de cambios. Es muy extra no que usted necestite til entender lo que la orden hg backout tomar control del proceso de retroceso de forma manual, pero puede ser u est a haciendo autom aticamente para usted. Para ilustrarlo, clonemos nuestro primer repositorio, pero omitamos el 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 es haremos retroceso de su padre, y veremos qu e pasa.

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 expl cita dici endolo.

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 as sencillo lo que pas o viendo una gr aca del historial de revisiones, en la gura 9.3. Esto nos aclara que cuando usamos hg backout para retroceder un cambio a algo que no sea la punta, Mercurial a nade una nueva cabeza al repositorio (el cambio que consign o est a encerrado en una caja). Despu es de que la orden hg backout ha terminado, deja un nuevo conjunto de cambios de retroceso como el 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 deber a estar presente, porque nunca le hicimos retroceso. El segundo cambio debi o desaparecer, puesto que es el que retrocedimos. Dado que la gr aca del historial muestra que el tercer camlio es una cabeza separada, no esperamos ver el tercer cambio presente en myfile.
1 2 3 4

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

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 es de eso, el historial gr aca de nuestro repositorio luce como la gura 9.4. 100

primer cambio

segundo cambio

tercer cambio

reversar segundo cambio

fusin manual
Figura 9.4: Fusi on manual de un retroceso

9.3.5.

Por qu e hg backout hace lo que hace

Esta es una descripci on corta de c omo trabaja la orden hg backout. 1. Se asegura de que el directorio de trabajo es limpio, esto es, que la salida de hg status deber a ser vac a. 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 a el equivalente a hg revert -r parent sobre ese chero, para restaurarlo a los contenidos que ten a 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 l nea de comandos, se fusiona con orig, y se consigna el resultado de la fusi on. Una v a alternativa de implementar la orden hg backout ser a usar hg export sobre el conjunto de cambios a retroceder como un diff y despu es usar laa opci on --reverse de la orden patch para reversar el efecto del cambio sin molestar el directorio de trabajo. Suena mucho m as simple, pero no funcionar a bien ni de cerca. La raz on por la cual hg backout hace una actualizaci on, una consignaci on, una fusi on y otra consignaci on es para dar a la maquinaria de fusi on la mayor oportunidad de hacer un buen trabajo cuando se trata con todos los cambios entre el cambio que est a retrocediendo y la punta actual. 101

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

9.4.

Cambios que nunca debieron ocurrir

En la mayor a 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 o el conjunto de cambios original y cuando se hizo la limpieza. En ocasiones particulares, puede haber consignado un cambio que no deber a estar de ninguna forma en el repositorio. Por ejemplo, ser a muy inusual, y considerado como una equivocaci on, consignar los cheros objeto junto con el c odigo fuente. Los cheros objeto no tienen valor intr nseco y son grandes, por lo tanto aumentan el tama no del repositorio y la cantidad de tiempo que se emplea al clonar o jalar cambios. Antes de discutir las opciones que tiene si consign o cambio del tipo bolsa de papel deschable (el tipo que es tan malo que le gustar a colocarse una bolsa de papel desechable en su cabeza), perm tame 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 nica excepci que le precedenusualmente usted no puede hacer que unos cambios desastrosos desaparezcan. La u on 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 e en la secci on 9.1.2. Despu es de que usted haya publicado un cambio en otro repositorio, usted podr a usar la orden hg rollback para hacer que en su copia local desaparezca el cambio, pero no tendr a las consecuencias que desea. El cambio estar a presente en un repositorio remoto, y reaparecer a en su repositorio local la pr oxima vez que jale Si una situaci on como esta se presenta, y usted sabe en qu e repositorios su mal cambio se ha propagado, puede intentar deshacerse del conjunto de cambios de todos los repositorios en los que se pueda encontrar. Esta por supuesto, no es una soluci on satisfactoria: si usted deja de hacerlo en un solo repositorio, mientras est e elimin andolo, el cambio todav a estar a all afuera, y podr a propagarse m as tarde. Si ha consignado uno o m as cambios despu es del cambio que desea desaparecer, sus opciones son a un m as reducidas. 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 omo protegerse de cambios que han escapado

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 cap tulo 10), puede prevenir la publicaci on autom aticamente de cierta clase de cambios malos. Con tal conguraci on, cierta clase de conjuntos de cambios malos tender an naturalmente amorir debido a que no pueden propagarse al repositorio central. Esto suceder a sin necesidad de intervenci on expl cita. Por ejemplo, un gancho de cambios de entrada que verique que un conjunto de cambios compila, puede prevenir que la gente rompa la compilaci on inadvertidamente.

9.5.

Al encuentro de la fuente de un fallo

Aunque es muy bueno poder retroceder el conjunto de cambios que origin o un fallo, se requiere que usted sepa 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 e pieza de c odigo introdujo el cambio, pero si requiere que sepa c omo probar la existencia de un fallo. La orden hg bisect usa su prueba para dirigir su b usqueda del conjunto de cambios que introdujo el c odigo causante del fallo. A continuaci on un conjunto de escenarios que puede ayudarle a entender c omo puede aplicar esta orden. La versi on m as reciente de su programa tiene un fallo que usted recuerda no estaba hace unas semanas, pero no sabe cu ando fue introducido. En este caso, su prueba binaria busca la presencia de tal fallo. Usted arregl o un fallo en un apurto, y es hora de dar por cerrado el caso en la base de datos de fallos de su 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 e conjunto de cambios arregl o tal fallo. De nuevo la prueba binaria revisa la presencia del fallo. ltima vez que lo midi Su programa funciona correctamente, pero core 15 % m as lento que la u o. Usted desea saber qu e conjunto de cambios introdujo esta disminuci on de desempe no. En este caso su prueba binaria mide el desempe no de su programa, para ver d onde es r apido y d onde es lento. Los tama nos de los componentes del proyecto que usted lleva se expandieron recientemente, y sospecha que algo cambio en la forma en que se construye su proyecto. til no solamente para encontrar la fuente de Para estos ejemplos deber a ser claro que la orden hg bisect es u los fallos. Puede usarla para encontrar cualquier propiedad emergente de un repositorio (Cualquier cosa que usted rbol) para la cual pueda escribir una no pueda encontrar con una b usqueda de texto sencilla sobre los cheros en el a prueba binaria. A continuaci on introduciremos algo terminolog a, para aclarar qu e partes del proceso de b usqueda son su responsabilidad y cu ales de Mercurial. Una prueba es algo que usted ejecuta cuando hg bisect elige un conjunto de cambios. Un sondeo es lo que hg bisect ejecuta para decidir si una revisi on es buena. Finalmente, usaremos la palabra biseccionar, en frases como buscar con la orden hg bisect. Una forma sencilla de automatizar el proceso de b usqueda ser a probar cada conjunto de cambios. Lo cual escala muy poco. Si le tom o diez minutos hacer pruebas sobre un conjunto de cambios y tiene 10.000 conjuntos de cambios en su repositorio, esta aproximaci on exhaustiva tomar a en promedio 35 d as para encontrar el conjunto de cambios ltimos 500 conjuntos de cambios y que introdujo el fallo. Incluso si supiera que el fallo se introdujo en un de los u limitara la b usqueda a ellos, estar a tomabdi m as de 40 horas para encontrar al conjunto de cambios culpable. La orden hg bisect usa su conocimiento de la forma del historial de revisiones de su proyecto para hacer una b usqueda proporcional al logaritmo del n umero de conjunto de cambios a revisar (el tipo de b usqueda que realiza se llama b usqueda binaria). Con esta aproximaci on, el buscar entre 10.000 conjuntos de cambios tomar a menos de 3 horas, incluso a diez minutos por prueba (La b usqueda requerir a cerca de 14 pruebas). Al limitar la b usqueda a la ltima centena de conjuntos de cambios, tomar u a a lo sumo una hora (Apenas unas 7 pruebas). 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 ultiples en un repositorio. Puede evitar ramas enteras de historial con un solo sondeo.

9.5.1.

Uso de la orden hg bisect

A continuaci on un ejemplo de hg bisect en acci on. Nota: En las versiones 0.9.5 y anteriores de Mercurial, hg bisect no era una orden inclu da en la distribuci on principal: se ofrec a como una extensi on de Mercurial. Esta secci on describe la orden embebida y no la extensi on anterior. 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 nico chero al un cambio espec co sea el fallo. Este ciclo crea 35 conjuntos de cambios, cada uno a nade un u 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 on observaremos c omo usar la orden hg bisect. Podemos usar el mecanismo de ayuda embebida 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 a hg bisect ejecutando la orden hg bisect good. Si falla, ejecutar a la orden hg bisect --bad. 2. La orden usa su informaci on para decidir qu e conjuntos de cambios deben probarse a continuaci on. 3. Actualiza el directorio de trabajo a tal conjunto de cambios y el proceso se lleva a cabo de nuevo.

104

nico conjunto de cambios que marca el punto donde se enconEl proceso termina cuando hg bisect identica un u tr o la transici on de exitoso a fallido. Para comenzar la b usqueda, es indispensable ejecutar la orden hg bisect --reset.
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 o el fallo. Por convenci on, un conjunto de cambios que tiene la propiedad que estamos buscando es malo, mientras que el otro que no la tiene es bueno. En la mayor a de casos, la revisi on del directorio actual (usualmente la punta) exhibe el problema introducido por el cambio con el fallo, por lo tanto la marcaremos como mala.

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

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 o algo. Nos dijo cu antos conjuntos de cambios debe considerar antes de que pueda identica aquel que introdujo el fallo, y cu antas pruebas se requerir an. Actualiz o el directorio de trabajo al siguiente conjunto de cambios, y nos dijo qu e conjunto de cambios est a evaluando. Ahora ejecutamos nuestra prueba en el directorio de trabajo. Usamos la orden grep para ver si nuestro chero malo est a presente en el directorio de trabajo. Si lo est a, esta revisi on es mala; si no esta revisi on es buena.

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 on de interfaz 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 as de nuestra prueba, y hemos terminado.

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 ten amos unos 40 conjuntos de cambios en los cuales buscar, la orden hg bisect nos permiti o encontrar el conjunto de cambios que introdujo el fallo con s olo cinco pruebas. Porque el n umero de pruebas que la orden hg bisect ejecuta crece logar tmicamente con la cantidad de conjuntos de cambios a buscar, la ventaja que esto tiene frente a la b usqueda porfuerza bruta crece con cada conjunto de cambios que usted adicione.

9.5.2.

Limpieza despu es de la busqueda

Cuando haya terminado de usar la orden hg bisect en un repositorio, puede usar la orden hg bisect reset para deshacerse de la informaci on que se estaba usando para lograr la b usqueda. Lar orden no usa mucho espacio, as que no hay problema si olvida ejecutar la orden. En todo caso, hg bisect no le permitir a comenzar una nueva b usqueda sobre el repositorio hasta que no aplique hg bisect reset.
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, podr a detectar la inconsistencia. Si puede identicar una inconsistencia en sus reportes, le dir a que un conjunto de cambios particular es a la vez bueno y malo. Aunque puede no hacerlo; estar a 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 e a usar la orden hg bisect, intent e ejecutar algunas veces las pruebas a mano desde la l nea de comandos. Es una aproximaci on a la cual no esta acostumbrado. Despu es de algunos intentos, me di cuenta que estaba cometiendo tantas equivocaciones que ten a que comenzar de nuevo con mis b usquedas varias veces antes de llegar a los resultados deseados. Mi problema inicial al dirigir a la orden hg bisect manualmente ocurrieron incluso con b usquedas en repositorios peque nos; si el problema que est a buscando es m as sutil, o el n umero de pruebas que hg bisect debe aplicar, la posibilidad de errar es mucho m as alta. Una vez que comenc e a automatizar mis pruebas, obtuve mejores resultados. La clave para las pruebas automatizadas se puede resumir en: pruebe siempre buscando el mismo s ntoma y ofrezca siempre datos consistentes a la orden hg bisect. En mi tutorial de ejemplo anterior, la orden grep busca el s ntoma, y la construcci on if toma el resultado de esta prueba y verica que siempre alimentamos con los mismos datos a la orden hg bisect. La funci on mytest los une 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 usqueda de hg bisect es tan buena como los datos ofrecidos por usted, no conf e en 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 o como la primera versi on erronea. Su prueba deber a dar un reporte de fallo. El conjunto de cambios padre (cada padre, si es una fusi on). Su prueba deber a reportar este(os) conjunto(s) de cambios como bueno(s). Un hijo del conjunto de cambios. Su prueba deber a reportar al conjunto de cambios hijo como malo.

9.6.4.

Tener en cuenta la interferencia entre fallos

Es posible que su b usqueda de un fallo pueda viciarse por la presencia de otro. Por ejemplo, digamos que su programa se revienta en la revisi on 100, y que funcion o correctamente en la revisi on 50. Sin su conocimiento, alguien introdujo un fallo con consecuencias grandes en la revisi on 60, y lo arregl o en la revisi on 80. Sus resultados estar an distorcionados de una o muchas formas. Es posible que este fallo enmascare completamente al suyo, y que podr a 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 e presente en un conjunto particular de cambios, la orden hg bisect no podr a ayudarle directamente. En cambio, puede marcar este conjunto de cambios como al ejecutar hg bisect --skip. 107

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

9.6.5.

Acotar la busqueda perezosamente

Elegir los primeros buenos y malos conjuntos de cambios que marcar an los l mites de su b usqueda en general es sencillo, pero vale la pena discutirlo. Desde la perspectiva de hg bisect, el conjunto de cambios m as nuevo por convenci on es el malo, y el otro conjunto de cambios es el bueno. Si no recuerda cu al podr a ser el cambio bueno, para informar a hg bisect, podr a hacer pruebas aleatorias en el peor de los casos. Pero recuerde eliminar aquellos conjuntos de cambios que podr an no exhibir el fallo (tal vez porque la caracter stica donde se presenta el fallo todav a no est a presente) y aquellos en los cuales otro fallo puede enmascararlo (como se discuti o anteriormente). Incluso si termina muy atr as por miles de conjuntos de cambios o meses de historial, solamente esta ra adicionando unas pruebas contadas para hg bisect, gracias al comportamiento logar tmico.

108

Cap tulo 10

Manejo de eventos en repositorios mediante ganchos


Mercurial ofrece un poderoso mecanismo para permitirle a usted automatizar la ejecuci on de acciones en respuesta 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 ermino gancho para identicar estas acciones. Los ganchos son conocidos como disparadores 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 on se encuentra una breve lista de los ganchos que Mercurial soporta. Volveremos a cada uno de estos ganchos con m as detalle despu es, en la secci on 10.8.
changegroup Es ejecutado luego de que un grupo de conjuntos de cambios ha sido tra do al repositorio desde alg un otro sitio. commit Es ejecutado despu es de la creaci on de un conjunto de cambios en el repositorio local. incoming Es ejecutado una vez por cada conjunto de cambios tra do al repositorio desde otra ubicaci on. Note la diferencia

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 on de un grupo de conjuntos de cambios en el repositorio. precommit De control. Es ejecutado antes de iniciar una consignaci on. preoutgoing De control. Es ejecutado antes de iniciar la transmisi on de un grupo de conjuntos de cambios desde el repositorio. pretag De control. Es ejecutado antes de crear una etiqueta. pretxnchangegroup De control. Es ejecutado despu es de haber recibido un grupo de conjuntos de cambios en el repositorio local,

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

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

109

update Es ejecutado despu es de que termina una actualizaci on o una fusi on.

Cada uno de los ganchos cuya descripci on empieza con la frase de control tiene la facultad de determinar si una xito, la actividad puede continuar; si falla, o bien la actividad actividad puede continuar. Si el gancho se ejecuta con e 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 on de un gancho, dicho gancho se ejecuta en su sistema, en su cuenta de usuario, con sus privilegios. Ya que los ganchos son elementos arbitrarios de c odigo ejecutable, usted deber a tratarlos con un nivel adecuado de desconanza. No instale un gancho a menos en que conf e en quien lo cre o y en lo que el gancho hace. En algunos casos, usted puede estar expuesto a ganchos que usted no instal o. Si usted usa Mercurial en un sistema extra no, tenga en cuenta que Mercurial ejecutar a los ganchos denidos en el chero hgrc. Si est a trabajando con un repositorio propiedad de otro usuario, Mercurial podr a ejecutar los ganchos denidos en el repositorio de dicho usuario, pero los ejecutar a como usted. Por ejemplo, si usted jala (hg pull) desde ese 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 olo aplica si usted est a jalando desde un repositorio en un sistema de cheros local o de red. Si est a jalando a trav es de http o ssh, cualquier gancho saliente (outgoing) se ejecutar a bajo la cuenta que est a ejecutando el proceso servidor, en el servidor. XXX Para ver qu e ganchos han sido denidos en un repositorio, use el comando hg config hooks. Si usted est a trabajando en un repositorio, pero comunic andose con otro que no le pertenece (por ejemplo, usando hg pull 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 odigo ejecutable arbitrario. Se ejecuta bajo su identidad, con su nivel de privilegios, en su m aquina. Ser a extremadamente descuidado de parte de cualquier sistema distribuido de control de revisiones el implementar control de revisiones para ganchos, ya que esto ofrecer a maneras f acilmente aprovechables de subvertir las cuentas de los usuarios del sistema de control de revisiones. Ya que Mercurial no propaga los ganchos, si usted est a colaborando con otras personas en un proyecto com un, no deber a asumir que ellos est an usando los mismos ganchos para Mercurial que usted usa, o que los de ellos est an congurado correctamente. Usted deber a documentar los ganchos que usted espera que la gente use. En una intranet corporativa, esto es algo m as f acil de manejar, ya que usted puede, por ejemplo, proveer una instalaci on est andar de Mercurial en un sistema de cheros NFS, y usar un chero hgrc global para denir los ganchos que ver an todos los usuarios. Sin embargo, este enfoque tiene sus l mites; vea m as abajo.

10.2.3.

Es posible hacer caso omiso de los ganchos

Mercurial le permite hacer caso omiso de la decini on de un gancho, a trav es de la redenici on del mismo. Usted puede deshabilitar el gancho jando su valor como una cadena vac a, 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 cr ticos sean ejecutados

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

10.3.

Precauciones con ganchos pretxn en un repositorio de acceso compartido

Si usted desea usar ganchos para llevar a cabo autom aticamente alg un trabajo en un repositorio al que varias personas tienen acceso compartido, debe tener cuidado con la forma de hacerlo. Mercurial s olo bloquea un repositorio cuando est a escribiendo al mismo, y s olo las partes de Mercurial que escriben al repositorio le prestan atenci on a los bloqueos. Los bloqueos de escritura son necesarios para evitar que m ultiples escritores simult aneos intereran entre s , corrompiendo el repositorio. 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 on a los bloqueos. Este esquema de lectura libre de bloqueos incremententa en gran medida el desempe no y la concurrencia. Sin embargo, para tener un gran desempe no es necesario hacer sacricios, uno de los cuales tiene el potencial de l. Describirlo requiere algo de detalle respecto a c causarle problemas a menos de que usted est e consciente de e omo Mercurial a nade conjuntos de cambios al repositorio y c omo lee esos cambios de vuelta. 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 acora de cambios (que contienen punteros a los nuevos datos del maniesto). Antes de la primera escritura a cada chero, se guarda un registro de d onde estaba el nal de chero en su registro de transacciones. Si la transacci on debe ser deshecha, Mercurial simplemente trunca cada chero de vuelta al tama no que ten a antes de que empezara la transacci on. Cuando Mercurial lee metadatos, lee la bit acora de cambios primero, y luego todo lo dem as. Como un lector s olo l puede ver en la bit acceder a a las partes del maniesto o de los metadatos de chero que e acora de cambios, nunca puede ver datos parcialmente escritos. Algunos ganchos de control (pretxncommit y pretxnchangegroup) se ejecutan cuando una transacci on est a casi completa. Todos los metadatos han sido escritos, pero Mercurial a un puede deshacer la transacci on y hacer que los datos reci en escritos desaparezcan. Si alguno de estos ganchos permanece en ejecuci on por mucho tiempo, abre una ventana de tiempo en la que un lector puede ver los metadatos de conjuntos de cambios que a un no son permanentes y que no deber a considerarse que est en realmante ah . Entre m as tiempo tome la ejecuci on del gancho, m as tiempo estar a abierta esta ventana.

111

10.3.1.

Ilustraci on del problema

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

10.4.

Tutorial corto de uso de ganchos

Escribir un gancho para Mercurial es f acil. Empecemos con un gancho que se ejecute cuando usted termine un hg commit, y simplemente muestre el hash del conjunto de cambios que usted acaba de crear. El gancho se llamar a commit.
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 on de un conjunto de cambios Todos los ganchos siguen el patr on del ejemplo 10.1. Usted puede a nadir una entrada a la secci on [hooks] de su chero hgrc. A la izquierda est a el nombre del evento respecto al cual dispararse; a la derecha est a la acci on a llevar a cabo. Como puede ver, es posible ejecutar cualquier orden de la l nea de comandos en un gancho. Mercurial le pasa informaci on extra al gancho usando variables de entorno (busque HG NODE en el ejemplo).

10.4.1.

Llevar a cabo varias acciones por evento

A menudo, usted querr a denir m as de un gancho para un tipo de evento particular, como se muestra en el ejemplo 10.2. Mercurial le permite hacer esto a nadiendo una extensi on al nal del nombre de un gancho. Usted extiende 112

el nombre del gancho poniendo el nombre del gancho, seguido por una parada completa (el caracter .), seguido de algo m as de texto de su elecci on. Por ejemplo, Mercurial ejecutar a tanto commit.foo como commit.bar cuando 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 on de un segundo gancho commit Para dar un orden bien denido de ejecuci on cuando hay m ultiples ganchos denidos para un evento, Mercurial ordena los ganchos de acuerdo a su extensi on, y los ejecuta en dicho orden. En el ejemplo de arribam commit.bar se ejecutar a antes que commit.foo, y commit se ejecutar a antes de ambos. Es una buena idea usar una extensi on descriptiva cuando usted dene un gancho. Esto le ayudar a a recordar para qu e se usa el gancho. Si el gancho falla, usted recibir a un mensaje de error que contiene el nombre y la extensi on del gancho, as que usar una extensi on descriptiva le dar a una pista inmediata de porqu e el gancho fall o (vea un ejemplo en la secci on 10.4.2).

10.4.2.

Controlar cu ando puede llevarse a cabo una actividad

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

10.5.

Escribir sus propios ganchos

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

10.5.1.

Escoger c omo debe ejecutarse su gancho

Usted puede escribir un gancho que funcione como un programa normal t picamente un gui on de l nea de comandoso como una funci on de Python que se ejecuta dentro del proceso Mercurial. Escribir un gancho como un programa externo tiene la ventaja de que no requiere ning un conocimiento del funcionamiento interno de Mercurial. Usted puede ejecutar comandos Mercurial normales para obtener la informci on 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 as lentos que los ganchos internos 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 as r apido que un gancho externo. Adicionalmente es m as f acil obtener la mayor a de la informaci on que un gancho requiere a trav es de llamadas directas a la API de Mercurial que hacerlo ejecutando comandos Mercurial. Si se siente a gusto con Python, o requiere un alto desempe no, escribir sus ganchos en Python puede ser una buena elecci on. Sin embargo, cuando usted tiene un gancho bastante directo por escribir y no le importa el desempe no (el caso de la mayor a de los ganchos), es perfectamente admisible un gui on de l nea de comandos.

10.5.2.

Par ametros para ganchos

Mercurial llama cada gancho con un conjunto de pa rametros bien denidos. En Python, un par ametro se pasa como argumento de palabra clave a su funci on de gancho. Para un programa externo, los par ametros son pasados como variables de entornos. Sin importar si su gancho est a escrito en Python o como gui on de l nea de comandos, los nombres y valores de los par ametros espec cos de los ganchos ser an los mismos. Un par ametro booleano ser a representado como un valor booleano en Python, pero como el n umero 1 (para verdadero) o 0 (para falso) en una variable de entorno para un gancho externo. Si un par ametro se llama foo, el argumento de palabra clave para un gancho en Python tambi en se llamar a foo, mientras que la variable de entorno para un gancho externo se llamar a HG FOO.

10.5.3.

Valores de retorno de ganchos y control de actividades

Un gancho que se ejecuta exitosamente debe terminar con un c odigo de salida de cero, si es externo, o retornar el valor booleano falso, si es interno. Un fallo se indica con un c odigo de salida diferente de cero desde un gancho externo, o un valor de retorno booleano verdadero. Si un gancho interno genera una excepci on, se considera que el 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 on quiere decir no permitir.

10.5.4.

Escribir un gancho externo

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

normales del int erprete en el cuerpo del gancho. Un gancho ejecutable siempre es ejecutado con su directorio actual jado al directorio ra z del repositorio. Cada par ametro para el gancho es pasado como una variable de entorno; el nombre est a en may usculas, y tiene como prejo la cadena HG . Con la excepci on de los par ametros para los ganchos, Mercurial no dene o modica ninguna variable de entorno til recordar esto al escribir un gancho global que podr al ejecutar un gancho. Es u a ser ejecutado por varios usuarios con distintas variables de entorno jadas. En situaciones con m ultiples usuarios, usted no deber a asumir la existencia de ninguna variable de entorno, ni que sus valores sean los mismos que ten an cuando usted prob o el gancho en su 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 a como el valor del gancho. El m odulo en que vive un gancho es importado autom aticamente cuando se ejecuta un gancho. Siempre que usted tenga el nombre del m odulo y la variable de entorno PYTHONPATH ajustada adecuadamente, todo deber a funcionar sin 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 as sencillo no hace nada, pero ilustra la estructura b asica de la API1 para ganchos:
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 es de estos dos argumentos est an los argumentos de palabra clave. Los argumentos que se pasen depender an del tipo de gancho que se est e llamando, pero un gancho siempre puede ignorar los argumentos que no le interesen, releg andolos a un diccionario de argumentos por palabras clave, como se hizo arriba con **kwargs.

10.6.
10.6.1.

Ejemplos de ganchos
Escribir mensajes de consignaci on signicativos

til y al mismo tiempo muy corto. El simple gancho pretxncommit Es dif cil de imaginar un mensaje de consignaci on u de la gura 10.4 evitar a que usted consigne un conjunto de cambios con un mensaje de menos de 10 bytes de longitud.
1 N.

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

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 proh be mensajes de consignaci on demasiado cortos

10.6.2.

Comprobar espacios en blanco nales

Un uso interesante para ganchos relacionados con consignaciones es ayudarle a escribir c odigo m as limpio. Un ejemplo simple de c odigo m as limpio es la regla de que un cambio no debe a nadir l neas de texto que contengan espacios en blanco nales. El espacio en blanco nal es una serie de caracteres de espacio y tabulaci on que se encuentran al nal de una l nea de texto. En la mayor a de los casos, el espacio en blanco nal es innecesario, ruido l. invisible, pero ocasionalmente es problem atico, y la gente en general preere deshacerse de e 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 a qu e cheros se est an consignando, por lo que se tendr a que revisar cada chero modicado en el repositorio para ver si tiene espacios en blanco nales. Si usted s olo quiere consignar un cambio al chero foo, y el chero bar contiene espacios en blanco nales, hacer la revisi on en el gancho precommit evitar a que usted haga la consignaci on de foo debido al problem en bar. Este no parece el enfoque adeucado. Si usted escogiera el gancho pretxncommit, la revisi on no ocurrir a sino hasta justo antes de que la transacci on para la consignaci on se complete. Esto le permitir a comprobar por posibles problemas s olo en los cheros que ser an consignados. Sin embargo, si usted ingres o el mensaje de consignaci on de manera interactiva y el gancho falla, la transacci on ser a deshecha; usted tendr a que reingresar el mensaje de consignaci on luego de que corrija el problema 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 odigo de salida de error si un cambio a nade una l nea con espacio en blanco nal a cualquier chero, pero no muestra ninguna informaci on que pueda ser 116

til para identicar el chero o la l u nea de texto origen del problema. Tambi en tiene la agradable propiedad de no prestar atenci on a las l neas que no sufrieron modicaciones; s olo las l neas que introducen nuevos espacios en blanco 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 til. El gancho procesa un diff unicado El ejemplo de la gura 10.6 es mucho m as complejo, pero tambi en m as u para revisar si alguna l nea a nade espacios en blanco nales, e imprime el nombre del chero y el n umero de l nea de cada ocurrencia. A un mejor, si el cambio a nade espacios en blanco nales, este gancho guarda el mensaje de consignaci on e imprime el nombre del chero en el que el mensaje fue guardado, antes de terminar e indicarle a Mercurial que deshaga la transacci on, para que uste pueda usar hg commit -l nombre fichero para reutilizar el mensaje de consignaci on guardado anteriormente, una vez usted haya corregido el problema. Como anotaci on nal, note en la gura 10.6 el uso de la caracter stica de edici on in-situ de perl para eliminar los 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

rbol de Mercurial se instala con varios ganchos adicionales. Usted puede encontrarlos en el directorio hgext del a cheros fuente de Mercurial. Si usted est a usando un paquete binario de Mercurial, los ganchos estar an ubicados en el 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 on acl le permite controlar a qu e usuarios remotos les est a permitido empujar conjuntos de cambios a un servidor en red. Usted puede proteger cualquier porci on de un repositorio (incluyendo el repositorio completo), de tal manera que un usuario remoto espec co pueda empujar cambios que no afecten la porci on protegida. Esta extensi on implementa control de acceso basado en la identidad del usuario que empuja los conjuntos de cambios, no en la identidad de quien hizo la consignaci on de los mismos. Usar este gancho tiene sentido s olo si se tiene un servidor adecuadamente asegurado que autentique a los usuarios remotos, y si usted desea segurarse de que s olo se le permita a ciertos usuarios empujar cambios a dicho servidor. 117

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

[hooks] pretxnchangegroup.acl = python:hgext.acl.hook La extensi on acl es congurada mediante tres secciones. La secci on [acl] s olo tiene una entrada, sources2 , que lista las fuentes de los conjuntos de cambios entrantes a las que el gancho debe prestar atenci on. Usualmente usted no necesita congurar esta secci on. serve Controlar conjuntos de cambios entrantes que est an llegando desde un repositorio a trav es de http o ssh. Este es nico valor de conguraci el valor por defecto de sources, y usualmente es el u on que necesitar a para este tem. pull Controlar conjuntos de cambios entrantes que lleguen v a un pull (jalado) desde un repositorio local. push Controlar conjuntos de cambios entrantes que lleguen v a un push (empuje) desde un repositorio local. bundle Controlar conjuntos de cambios entrantes que lleguen desde otro repositorio a trav es de un paquete. La secci on [acl.allow] controla los usuarios a los que les est a permitido a nadir conjuntos de cambios al repositorio. Si esta secci on no est a presente, se le permite acceso a todos los usuarios excepto a los que se les haya negado expl citamente el acceso. Si esta secci on no est a presente, se niega el acceso a todos los usuarios excepto a todos a los que se les haya permitido de manera expl cita (as que una secci on vac a implica que se niega el acceso a todos los usuarios). La secci on [acl.deny] determina a qu e usuarios no se les permite a nadir conjuntos de cambios al repositorio. Si esta secci on no est a presente o est a vac a, no se niega el acceso a ning un usuario. La sintaxis para los cheros [acl.allow] y [acl.deny] es id entica. A la izquierda de cada entrada se encuentra un patr on glob que asocia cheros o directorios, respecto a la ra z del repositorio; a la derecha, un nombre usuario. En el siguiente ejemplo, el usuario escritordoc s olo puede empujar cambios al directorio docs del repositorio, 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 on de problemas Si usted desea probar el gancho acl, ejec utelo habilitando la opci on de salida de depuraci on habilitada. Ya que usted probablemente lo estar a ejecutando en un servidor donde no es conveniente (o incluso posible) pasar la opci on --debug, no olvide que usted puede habilitar la salida de depuraci on en su hgrc:
1 2

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

del T. Fuentes.

118

10.7.2.

bugzillaintegraci on con Bugzilla

La extensi on bugzilla a nade un comentario a un fallo Bugzilla siempre que encuentre una referencia al ID de dicho fallo en un mensaje de consignaci on. Usted puede instalar este gancho en un servidor compartido, para que cada vez que un usuario remoto empuje cambios al servidor, el gancho sea ejecutado. Se a nade un comentario al fallo que se ve as (usted puede congurar los contenidos del comentariovea m as 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 l. Si usted congura este gancho adecuadamente, har se reera a e a f acil para la gente navegar directamente desde un fallo Bugzilla a un conjunto de cambios que se reere a ese fallo. Usted puede usar el c odigo de este gancho como un punto de partida para otras recetas de integraci on con Bugzilla a un m as ex oticas. Ac a hay algunas posibilidades: Requerir que cada conjunto de cambios tenga un ID de fallo en su mensaje de consignaci on. En este caso, usted querr a congurar el gancho como uno de tipo pretxncommit. Esto le permitir a al gancho rechazar cambios que no contiene IDs de fallos. Permitir a los conjuntos de cambios entrantes modicar autom aticamente el estado de un fallo, as como simplemente a nadir un comentario. Por ejemplo, el gancho podr a reconocer la cadena corregido fallo 31337 como la se nal de que deber a actualizar el estado del fallo 31337 a requiere pruebas. Conguraci on del gancho bugzilla Usted deber a 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 on 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 a disponible como paquete binario para su sistema, usted puede descargar el paquete desde [Dus]. La informaci on para congurar este gancho se ubica en la secci on [bugzilla] de su hgrc.

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

del T. Entrante.

119

user El nombre de usuario que se usar a para conectarse al servidor MySQL. La base de datos debe ser congurada para permitir a dicho usuario conectarse desde cualquiera de las m aquinas en las que se ejecute el gancho 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 andar del usuario para Bugzilla en una base de datos MySQL. es almacenada como texto plano, as password La contrase na MySQL para el usuario congurado anteriormente. Esta que usted deber a asegurarse de que los usuarios no autorizados no puedan leer el chero hgrc en donde usted guarda esta informaci on. 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 andar de la base de datos MySQL en donde Bugzilla almacena sus datos. notify Si usted desea que Bugzilla env e un correo de noticaci on a los suscriptores despu es de que el gancho haya a nadido un comentario a un fallo, necesitar a que este gancho ejecute un comando siempre que actualice la base de datos. El comando que se ejecute depende de en d onde haya sido instalado Bugzilla, pero t picamente se ver a as , si usted ha instalado Bugzilla en /var/www/html/bugzilla:
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 on de correo. Tambi en espera poder escribir a ciertos cheros en el directorio en que se ste gancho no est ejecuta. Si Bugzilla y e an instalados en la misma m aquina, usted deber a encontrar una manera de ejecutar processmail en el servidor donde est a instalado Bugzilla.

Asociar nombres de consignadores a nombres de usuario Bugzilla Por defecto, el gancho bugzilla trata de usar la direcci on de correo electr onico de la persona que hizo la consignaci on del conjunto de cambios como el nombre de usuario Bugzilla con el cual debe actualizar el fallo. Si esto no se ajusta a sus necesidades, es posible asociar direcciones de correo a nombres de usuario Bugzilla usando una secci on [usermap]. Cada tem en la secci on [usermap] contiene una direcci on de correo electr onico a la izquierda, y un nombre de 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 on desde un chero usermap externo. En este caso, usted puede almacenar los datos de usermap en (por ejemplo) un repositorio modicable por los usuarios. Esto hace posible para sus usuarios mantener sus propias entradas usermap. El chero hgrc principal se ver a 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 ver a 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 nade como comentario; usted los especica como una plantilla Mercurial. Varias entradas hgrc (a un en la secci on [bugzilla]) controlan este comportamiento. 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 a en una ruta parcial de app/tests. El gancho har a disponible esta ruta parcial cuando expanda una plantilla, como webroot. template El texto de la plantilla a usar. En adici on a las variables usuales relacionadas con conjuntos de cambios, esta plantilla puede usar hgweb (el valor del tem de conguraci on hgweb de arriba) y webroot (la ruta construida usando strip arriba). Adicionalmente, usted puede a nadir un tem baseurl a la secci on [web] de su hgrc. El gancho bugzilla publicar a esto cuando expanda una plantilla, como la cadena base a usar cuando se construya una URL que le permita 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 on se presenta un ejemplo completo de conguraci on para el gancho bugzilla.

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 on de problemas Los problemas m as comunes que aparecen en la conguraci on del gancho bugzilla suelen estar relacionados con la ejecuci on del gui on de Bugzilla processmail y la asociaci on de nombres de consignadores a nombres de usuario. Recuerde que en la secci on 10.7.2 arriba el usuario que ejecuta el proceso Mercurial en el servidor es tambi en el usuario que ejecutar a el gui on processmail. El gui on processmail algunas veces hace que Bugzilla escriba en cheros en su directorio de conguraci on, y los cheros de conguraci on de Bugzilla usualmente son propiedad del 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 on se presenta una entrada de ejemplo para un chero sudoers.

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 on a trav es de un gui on envoltorio es necesaria, porque processmail espera que al ser ejecutado su directorio actual sea aquel en el cual se instal o Bugzilla; usted no puede especicar ese tipo de condici on en un chero sudoers. Los contenidos del giu on envoltorio son simples: 121

1 2

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

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

10.7.3.

notifyenviar noticaciones de correo electr onico

Aunque el servidor web embebido de Mercurial provee noticaciones de cambios en cada repositorio, muchas personas preeren recibir las noticaciones de cambios v a correo electr onico. El gancho notify4 le permite a usted enviar noticaciones a un conjunto de direcciones de correo cuando lleguen conjuntos de cambios en los que los subscriptores est en interesados. De la misma forma que con el gancho bugzilla, el gancho notify est a orientado a plantillas, as que usted puede personalizar los contenidos del mensaje de noticaci on que se env a. Por defecto, el gancho notify incluye un diff de cada conjunto de cambios que se env a; usted puede limitar el til para permitir a los subscriptores revisar los tama no del diff, o desactivar completamente esta caracter stica. Es u cambios inmediatamente, en vez de tener que hacer clic para visitar una URL. Conguraci on del gancho notify Usted puede congurar el gancho notify para enviar un mensaje de correo por conjunto de cambios entrante, o nico empuje o jalado). uno por grupo entrante de conjuntos de cambios (todos los que llegaron en un u
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 on para congurar este gancho se ubica en la secci on [notify] de un chero hgrc. test Por defecto, este gancho no env a correos en absoluto; en vez de eso, imprime el mensaje que se enviar a. Fije este tem en false para permitir el env o de correos. El motivo por el que el env o de correos est a desactivado es que hacen falta varios intentos para congurar esta extensi on exactamente como usted desea, y ser a maleducado enviar a los subscriptores una cantidad de noticaciones rotas mientras usted depura su conguraci on. config La ruta a un chero de conguraci on que contiene informaci on de subscripci on. Esto se mantiene separado 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 on de ruta a remover de la ruta del repositorio, al decidir si un repositorio tiene subscriptores. Por ejemplo, si los repositorios en su servidor est an en /home/hg/repos, y notify est a trabajando con un repositorio llamado /home/hg/repos/shared/test, jar strip a 4 har a que notify elimine las partes iniciales de la ruta hasta shared/test, y asociar a los subscriptores frente a dicha ruta.
4 N.

del T. Noticaci on.

122

template El texto de plantilla a usar cuando se env en mensajes. Especica los contenidos de la cabecera del mensaje y el cuerpo del mismo. maxdiff El n umero m aximo de l neas de datos de diff a a nadir al nal de un mensaje. Si la longitud de un diff es mayor a eso, se trunca. Por defecto, est a jado en 300. Fije esto a 0 para omitir los diffs en los correos de noticaci on. sources Una lista de fuentes de conjuntos de cambios a considerar. Esto le permite a usted indicar a notify para que s olo env e correos acerca de cambios que usuarios remotos hayan empujado al repositorio v a un servidor, por ejemplo. Vea la secci on 10.8.3 para las fuentes que usted puede especicar aqu . Si usted ja el tem baseurl en la secci on [web], usted lo puede usar en una plantilla; estar a disponible como webroot. A continuaci on se presenta un ejemplo completo de conguraci on para el gancho notify.
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 est an en el repositorio notify config = /home/hg/repos/notify/notify.conf # repos est an en /home/hg/repos on server, as que elimine 4 # 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 a un mensaje que se ver a como el siguiente:

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 on de problemas No olvide que por defecto, la extensi on notify no enviar a ning un correo electr onico hasta que usted la congure expl citamente para hacerlo, jando el valor de test a false. Hasta que usted haga eso, simplemente se imprimir a el mensaje que se enviar a.

10.8.
10.8.1.

Informaci on para escritores de ganchos


Ejecuci on de ganchos internos

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


1 2

def myhook(ui, repo, **kwargs): pass El par ametro ui es un objeto mercurial.ui.ui. El par ametro repo es un objeto mercurial.localrepo.localrepository. Los nombres y valores de los par ametros en **kwargs dependen del gancho que se invoque, con las siguientes caracter sticas en com un: Si hay un par ametro llamado node o parentN , contendr a un ID hexadecimal de un conjunto de cambios. La cadena vac a es usada para representar un ID de conjunto de cambios nulo en vez de una cadena de ceros. Si hay un par ametro llamado url, contendr a la URL de un repositorio remoto, si puede ser determinada. Los par ametros booleanos son representados como objetos bool de Python. Un gancho interno es ejecutado sin cambiar el directorio de trabajo del proceso (a diferencia de los ganchos externos, que son ejecutados desde la ra z del repositorio). El gancho no debe cambiar el directorio de trabajo del proceso, porque esto har a que falle cualquier llamada que se haga a la API de Mercurial. ste tuvo e xito. Si retorna true6 o genera una Si un gancho retorna el valor booleano false5 , se considera que e til de pensar en esta convenci excepci on, se considera que ha fallado. Una manera u on de llamado es d game si usted 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 on mercurial.node.bin.

10.8.2.

Ejecuci on de ganchos externos

Un gancho externo es pasado al int erprete de comandos del usuario bajo el cual se ejecuta Mercurial. Las caracter sticas del int erprete, como sustituci on de variables y redirecci on de comandos, est an disponibles. El gancho es ejecutado desde el directorio ra z del repositorio (a diferencia de los ganchos internos, que se ejecutan desde el mismo directorio en que Mercurial fue ejecutado). Los par ametros para el gancho se pasan como variables de entorno. El nombre de cada variable de entorno se pasa a may usculas y se le a nade el prejo HG . Por ejemplo, si el nombre de un par ametro es node, el nombre de la variable de entorno que almacena el par ametro se llamar a HG NODE. Un par ametro booleano se representa con la cadena 1 para true, 0 para false. Si una variable se llama HG NODE, HG PARENT1 o HG PARENT2, contendr a un ID de conjunto de cambios representado como una cadena hexadecimal. La cadena vac a 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 a la URL de un repositorio remoto, si puede ser determinada. xito. Si termina con un c Si un gancho termina con un c odigo de salida de cero, se considera que tuvo e odigo de 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 onde vienen los conjuntos de cambios

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

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 nadido al repositorio, por ejemplo v a un hg pull o hg unbundle. Este gancho es ejecutado una vez por cada operaci on que a nade uno o m as conjuntos de cambios. Este gancho se diferencia del gancho incoming, que es ejecutado una vez por 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 nadidos, actualizar una base de datos de fallos, o noticar a subscriptores de que el repositorio contiene nuevos cambios. Par ametros para este gancho: node Un ID de conjunto de cambios. El ID del primer conjunto de cambios que fue a nadido en el grupo. Todos los ste y la punta (tip), inclusive, fueron a nico jalado (hg pull), conjuntos de cambios entre e nadidos por un u empuje (hg push) o hg unbundle. source Una cadena. La fuente de estos cambios. Vea la secci on 10.8.3 para m as detalles. url Una URL. La ubicaci on del repositorio remoto, si es conocida. Vea la secci on 10.8.3 para m as informaci on. Veta tambi en: incoming (secci on 10.9.3), prechangegroup (secci on 10.9.5), pretxnchangegroup (secci on 10.9.9)
7 N.

del T. Fuente.

125

10.9.2.

commitluego de la creaci on de un nuevo conjunto de cambios

Este gancho es ejecutado luego de la creaci on de un nuevo conjunto de cambios. Par ametros para este gancho: node Un ID de conjunto de cambios. El ID de conjunto de cambios del conjunto de cambios que acab o de ser 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 en: precommit (secci on 10.9.6), pretxncommit (secci on 10.9.10)

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 nadido al repositorio, por ejemplo, v a un hg push. Si un grupo de conjuntos de cambios fue a nadido en una sola operaci on, este gancho es ejecutado una vez por cada conjunto de cambios a nadido. Usted puede usar este gancho para los mismos nes que el gancho changegroup (secci on 10.9.1); simplemente algunas veces es m as conveniente ejecutar un gancho una vez por cada grupo de conjuntos de cambios, mientras que til correrlo por cada conjunto de cambios. otras es m as u Par ametros para este gancho: node Un ID de conjunto de cambios. El ID del conjunto de cambios reci en a nadido. source Una cadena. La fuente de estos cambios. Vea la secci on 10.8.3 para m as detalles. url Una URL. La ubicaci on del repositorio remoto, si es conocida. Vea la secci on 10.8.3 para m as informaci on. Vea tambi en: changegroup (secci on 10.9.1) prechangegroup (secci on 10.9.5), pretxnchangegroup (secci on 10.9.9)

10.9.4.

outgoingluego de la propagaci on de los conjuntos de cambios

ste reposiEste gancho es ejecutado luego de que un grupo de conjuntos de cambios ha sido propagado fuera de e torio, 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 ametros para este gancho: 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 on (vea la secci on 10.8.3). Si un cliente remoto jal o cambios de este repositorio, source ser a serve. Si el cliente que obtuvo los cambios desde este repositorio era local, source ser a bundle, pull, o push, dependiendo de la operaci on que llev o a cabo el cliente. url Una URL. La ubicaci on del repositorio remoto, si es conocida. Vea la secci on 10.8.3 para m as informaci on. Vea tambi en: preoutgoing (secci on 10.9.7)

126

10.9.5.

prechangegroupantes de empezar la adici on de conjuntos de cambios remotos

Este gancho de control es ejecutado antes de que Mercurial empiece a a nadir un grupo de conjuntos de cambios de otro repositorio. Este gancho no tiene ninguna informaci on acerca de los conjuntos de cambios que van a ser a nadidos, porque es ejecutado antes de que se permita que empiece la transmisi on de dichos conjuntos de cambios. Si este gancho falla, los conjuntos de cambios no ser an transmitidos. Un uso para este gancho es prevenir que se a nadan cambios externos a un repositorio. Por ejemplo, usted podr a 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 ametros para este gancho: source Una cadena. La fuente de estos cambios. Vea la secci on 10.8.3 para m as detalles. url Una URL. La ubicaci on del repositorio remoto, si es conocida. Vea la secci on 10.8.3 para m as informaci on. Vea tambi en: changegroup (secci on 10.9.1), incoming (secci on 10.9.3), , pretxnchangegroup (secci on 10.9.9)

10.9.6.

precommitantes de iniciar la consignaci on de un conjunto de cambios

Este gancho es ejecutado antes de que Mercurial inicie la consignaci on de un nuevo conjunto de cambios. Es ejecutado antes de que Mercurial tenga cualquier de los metadatos para la consignaci on, como los cheros a ser consignados, el mensaje de consignaci on, o la fecha de consignaci on. 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 on o prueba, y permitir la xito. consignaci on s olo si el ensamble/compilaci on o prueba tiene e Par ametros para este gancho: 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 on contin ua, los padres del directorio de trabajo se convertir an en los padres del nuevo conjunto de cambios. Vea tambi en: commit (secci on 10.9.2), pretxncommit (secci on 10.9.10)

10.9.7.

preoutgoingantes de empezar la propagaci on de conjuntos de cambios

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 ametros para este gancho: ste repositorio (vea la secsource Una cadena. La fuente la operaci on que est a tratando de obtener cambios de e ci on 10.8.3). Revise la documentaci on para el par ametro source del gancho outgoing, en la secci on 10.9.4, para ver los posibles valores de este par ametro. url Una URL. La ubicaci on del repositorio remoto, si es conocida. Vea la secci on 10.8.3 para m as informaci on. Vea tambi en: outgoing (secci on 10.9.4)

127

10.9.8.

pretagantes de etiquetar un conjunto de cambios

Este gancho de control es ejecutado antes de la creaci on de una etiqueta. Si el gancho termina exitosamente, la creaci on de la etiqueta contin ua. Si el gancho falla, no se crea la etiqueta. Par ametros para este gancho: sta instancia del repositorio (p.e. almacenado en .hg/localtags) local Un booleano. Indica si la etiqueta es local a e 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 en ser an ejecutados. Vea tambi en: tag (secci on 10.9.12)

10.9.9.

pretxnchangegroupantes de completar la adici on de conjuntos de cambios remotos

Este gancho de control es ejecutado antes de una transacci onla que maneja la adici on de un grupo de conjuntos xito, la transacci de cambios nuevos desde fuera del repositoriose complete. Si el gancho tiene e on se completa, y todos los conjuntos de cambios se vuelven permanentes dentro de este repositorio. Si el gancho falla, la transacci on es 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 nadidos, pero no debe hacer nada permanente con estos datos. Tampoco debe modicar el directorio de trabajo. Mientras este gancho est a corriendo, si otro proceso Mercurial accesa el repositorio, podr a ver los conjuntos de cambios casi a nadidos como si fueran permanentes. Esto puede llevar a condiciones de carrera si usted no toma precauciones para evitarlas. Este gancho puede ser usado para examinar autom aticamente un grupo de conjuntos de cambios. Si el gancho falla, todos los conjuntos de cambios son rechazados cuando la transacci on se deshace. Par ametros para este gancho: node Un ID de conjunto de cambios. El ID del primer conjunto de cambios que fue a nadido en el grupo. Todos los ste y el tip, inclusive, fueron a nico hg pull, hg push o hg conjuntos de cambios entre e nadidos por un u unbundle. source Una cadena. La fuente de estos cambios. Vea la secci on 10.8.3 para m as detalles. url Una URL. La ubicaci on del repositorio remoto, si es conocida. Vea la secci on 10.8.3 para m as informaci on. Vea tambi en: changegroup (secci on 10.9.1), incoming (secci on 10.9.3), prechangegroup (secci on 10.9.5)

10.9.10.

pretxncommitantes de completar la consignaci on de un nuevo conjunto de cambios

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

node Un ID de conjunto de cambios. El ID del conjunto de cambios reci en 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 en: precommit (secci on 10.9.6)

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 olo si las revisiones usuales de Mercurial antes de las actualizaciones determinan que la actualizaci on o fusi on pueden proceder. Si el gancho termina exitosamente, la actualizaci on o fusi on pueden proceder.; si falla, la actualizaci on o fusi on no empiezan. Par ametros para este gancho: parent1 Un ID de conjunto de cambios. El ID del padre al que el directorio de trabajo ser a actualizado. Si se est a fusionando el directorio de trabajo, no cambiar a este padre. parent2 Un ID de conjunto de cambios. S olo est a denido si se est a fusionando el directorio de trabajo. El ID de la revisi on con la cual est a siendo fusionado el directorio de trabajo. Vea tambi en: update (secci on 10.9.13)

10.9.12.

tagluego de etiquetar un conjunto de cambios

Este gancho es ejecutado luego de la creaci on de una etiqueta. Par ametros para este gancho: sta instancia del repositorio (p.e. almacenado en .hg/localtags) local Un booleano. Indica si la etiqueta es local a e 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 a bajo control de revisiones, el gancho commit (secci on 10.9.2) es ejecutado antes de este gancho. Vea tambi en: pretag (secci on 10.9.8)

10.9.13.

updateluego de actualizar o fusionar el directorio de trabajo

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

Cap tulo 11

Personalizar los mensajes de Mercurial


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

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 o e instal o en un sitio en el cual Mercurial puede encontrarla. 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 l neas de salida por cada conjunto de cambios. El estilo compact lo reduce a tres l neas, 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 bit acora de cambios vislumbra el poder expresivo del sistema de plantillas de Mercurial. Este estilo busca seguir los est andares de bit acora de cambios del proyecto GNU[RS]. 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 on que Mercurial usar a para toda orden v a el chero hgrc indicando el 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 (t picamente el subdirectorio templates de su directorio de instalaci on de Mercurial).

11.2.

Ordenes que soportan estilos y plantillas

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

11.3.

Cuestiones b asicas de plantillas

Una plantilla de Mercurial es sencillamente una pieza de texto. Cierta porci on nunca cambia, otras partes se 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 as sencilla posible; es solamente una porci on est atica de c odigo que se imprime una vez por cada conjunto de cambios. La opci on --template de la orden hg log indica a Mercurial usar 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 l nea al nal de cada objeto de la plantilla. Si omite esta nueva l nea, Mercurial colocar a cada pieza de salida seguida. Si desea m as detalles acerca de secuencias de control, vea la secci on 11.5. til; intentemos algo un poco m Una plantilla que imprime una cadena ja de texto siempre no es muy u as complejo.

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 on de cada conjunto de cambios. Cada vez que Mercurial encuentra texto encerrado entre corchetes ({ y }), intentar a reemplazar los corchetes y el texto con la expansi on de lo que sea est a adentro. Para imprimir un corchete de forma literal, debe escaparlo, como se describe en la secci on 11.5.

11.4.

Palabras claves m as comunes en las plantillas

Puede empezar a escribir plantillas sencillas r apidamente con las palabras claves descritas a continuaci on: author Cadena. El autor NO modicado del conjunto de cambios. branches Cadena. El nombre de la rama en la cual se consign o el conjunto de cambios. Ser a vac a si el nombre de la rama es default. date Informaci on de fecha. La fecha en la cual se consign o el conjunto de cambios. No es legible por un humano, debe pasarla por un rltro que la desplegar a apropiadamente. En la secci on 11.6 hay m as detalles acerca de ltros. La fecha se expresa como un par de n umeros. El primer n umero corresponde a una marca de tiempo UNIX UTC (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 on, en segundos. desc Cadena. La descripci on en texto del conjunto de cambios. 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 on de este conjunto de cambios como una cadena hexadecimal de 40 caracteres. parents Lista de cadenas. Los ancestros del conjunto de cambios. rev Entero. El n umero de revisi on del repositorio local. tags Lista de cadenas. Todas las etiquetas asociadas al conjunto de cambios. Unos experimentos sencillos nos mostrar an qu e esperar cuando usamos estas palabras claves; puede ver los resultados 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 as en la secci on 11.6.
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 as comunmente usadas dentro de las cadenas. Cuando ve un backslash (\), ve el caracter siguiente y sustituye los dos caracteres con un reemplazo sencillo, como se describe a continuaci on: 133

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

11.6.

Uso de ltros con palabras claves

Algunos de los resultados de la expansi on de la plantilla no son f aciles de usar de inmediato. Mercurial le permite especicar una cadena de ltros opcionales para modicar el resultado de expandir una palabra clave. Ya ha visto el ltro usual isodate en acci on con anterioridad para hacer legible la fecha. A continuaci on hay una lista de los ltros de Mercurial m as comunmente usados. Ciertos ltros pueden aplicarse nicamente en circunstancias espec a cualquier texto, otros pueden usarse u cas. El nombre de cada ltro est a seguido de la indicaci on de d onde puede ser usado y una descripci on de su efecto. addbreaks Cualquier texto. A nade una etiqueta XHTML <br/> antes del nal de cada l nea excepto en la nal. Por 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 inclu da. 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 on de correo electr onico, y extrae solamente el componente del dominio. Por ejemplo, de 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 on de correo. Por ejemplo, de Bryan OSullivan <bos@serpentine.com> extrae bos@serpentine.com. escape Cualquier texto. Reemplaza los caracteres especiales de XML/XHTML: &, < y > con las entidades XML. til emplearlo antes de pasar el texto fill68 Cualquier texto. Lograr que el texto ocupe las primeras 68 columnas. Es u por el ltro tabindent, y queremos que a un quepa en una ventana de fuente ja y 80 columnas. fill76 Cualquier texto. Lograr que el texto quepa en 76 columnas. firstline Cualquier texto. Mostrar la primera l nea de texto sin saltos de l nea. hgdate date palabra clave. Mostrar la fecha como un par de n umeros legibles. Muestra una cadena como 1157407993 25200. 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 upidos de adquisici on de correo. til sobre todo para la palabra clave author. Muestra el texto que hay antes de la direcci person Cualquier texto, u on de correo electr onico. Por ejemplo, Bryan OSullivan <bos@serpentine.com> mostrar a Bryan OSullivan. rfc822date date palabra clave. Muestra una fecha con el mismo formato que se usa en los encabezados de correo. Mostrar a 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 no, mes y d a de una fecha. Muestrauna cadena como 2006-09-04. 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 l neas 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. til sobre todo para la palabra clave author. Retorna el usuario de una direcci user Cualquier texto, u on de correo. Por ejemplo, Bryan OSullivan <bos@serpentine.com> se convierte en bos. Nota: Si trata de aplicar un ltro a una porci on de datos que no puede procesarse, Mercurial fallar a e imprimir a una excepci on de Python. Por ejemplo, el tratar de til. usar la salida de la palabra clave desc con el ltro isodate no resultar a algo u

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 on, despu es aseguran que cabe limpiamente en 68 columnas, y las indenta con 8 caracteres (por lo menos en sistemas tipo Unix, en los que el tab por convenci on se extiende en 8 caracteres).
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 l nea se indente; esto es necesario para lograr que la primera l nea luzca indentada; es necesario debido a que tabindent indenta todas las l neas 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 on del primer ltro y as sucesivamente. Por ejemplo, usar fill68|tabindent es muy distinto al resultado de usar tabindent|fill68.

11.7.

De plantillas a estilos

Una plantilla provee una forma r apida y sencilla para dar formato a una salida. Las plantillas pueden volvers ver til poder darle un nombre a una plantilla. Un chero de estilo es una plantilla con un nombre, almacenado bosas, y es u en un chero. M as a un, al usar un chero de estilo se dispara el poder del motor de plantillas en un nivel imposible de alcanzar rdenes. usando las opci on --template desde la l nea de 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 136 (at least i hope that some m $ 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 as sencillos

Nuestro chero sencillo de estilo contiene una sola l nea:


1 2 3

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

11.7.2.

Sintaxis de cheros de estilo

Las reglas de sintaxis para un chero de estilo son sencillas: El chero se procesa l nea por l nea. Se ignoran el espacio en blanco circundante. Se omiten las l neas en blanco. Si una l nea comienza con los caracteres # o ;, la l nea completa se trata como un comentario, y se omite como si fuera vac a. Una l nea comienza con una palabra clave. Esta debe comenzar con una caracter alfab etico o una raya al piso, y puede contener subsecuentemente cualquier caracter alfanum erico o una raya al piso. (En notaci on de expresiones regulares debe coincidir con [A-Za-z_][A-Za-z0-9_]*.) El pr oximo elemento debe ser un caracter =, que puede estar precedido o seguido por una cantidad arbitraria de espacio. Si el resto de la l nea 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 l nea no comienza con una comilla, se trata como el nombre de un chero; los contenidos de este chero se leer an y se usar an como cuerpo de la plantilla.

11.8.

Ejemplos de cheros de estilos

Para ilustrar la creaci on de un chero de estilo, construiremos algunos ejemplos. En lugar de ofrecer un chero 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 as completos.

11.8.1.

Identicar equivocaciones en cheros de estilo

Si Mercurial encuentra un problema en un chero de estilo en el cual usted est a trabajando, imprime un mensaje til. de error suscinto, cuando usted identique lo que signica, resulta muy u
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 dif cil de seguir: El primer componente es la forma como Mercurial dice me rindo.
1

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

abort: broken.style:1: parse error Siguendo el nombre del chero viene el n umero de l nea en la que se encontr o el error.

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

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

11.8.2.

Identicar de forma unica un repositorio

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

$ hg log -r0 --template {node} 92cb4692d38c537be0935f906eeff2a47033600c till en ciertos casos: many cases. No es garant a de unicidad, pero no es u No funcionar a en un repositorio completamente vac o, porque un repositorio as no tiene una revisi on zero. Tampoco funcionar a en caso (muy raro) cuando el repositorio sea una fusi on de dos repositorios independientes y tiene los dos directorios por ah . Hay ciertos casos en los cuales podr a 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 on}. Almacene esta informaci on de forma independiente cuando 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 acil copiar y pegar una porci on de su salida en un chero, y reemplazar el texto producido previamente por Subversion con valores base que quisi eramos ver expandidos.

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 entesis. El motor de plantillas de Mercurial no ofrece una forma sencilla de desplegar una fecha en este formato sin imprimir tambi en la hora y la zona horaria. Emulamos las l neas de separaci on de subversion con caracteres - en una l nea. Usamos la palabra clave header del motor de plantillas para imprimir una l nea de separaci on como la primera l nea de salida (ver m as abajo), para lograr una salida similara a la de Subversion. La salida de subversion incluye un conteo en el encabezado del n umero de l neas en el mensaje de consinaci on. 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 o m as de un minuto o dos de trabajo para reemplazar texto literal de un ejemplo de salida de la salida 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 Podr amos haber inclu do el texto del chero plantilla directamente en el chero de estilo encerrando entre comillas y reemplazando las nuevas l neas con secuencias \n, pero har a muy dif cil de leer el chero de estilos. La facilidad para leer es importante cuando est a decidiendo si un texto pertenece a un chero de estilo o a un chero de plantilla inclu do en el estilo. Si el chero de estilo luce muy grande o complicado, si inserta una pieza de texto literal, mejor col oquelo en una plantilla.

139

Cap tulo 12

Administraci on de cambios con Colas de Mercurial


12.1. El problema de la administraci on de parches

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 es necesita actualizar a una nueva versi on del paquete. Si la nueva versi on del paquete todav a tiene el rbol de fuentes anteriores y aplicarlo a la nueva versi fallo, debe extraer su arreglo del a on. Una tarea tediosa en la cual es f acil equivocarse. rbol de fuentes del mantenedor Este es un caso simple del problema del manejo de parches. Usted tiene un a rbol principal; y desear principal que no puede cambiar: necesita hacer algunos cambios locales sobre el a a poder rbol principal. mantener tales cambios separados, de forma tal que pueda aplicarlos a versiones m as nuevas del a El problema de administraci on de parches surge en muchas situaciones. Probablemente la m as visible es cuando un usuario de un proyecto de software de fuentes abiertas contribuye con un arreglo de un fallo o una nueva caracter stica a los mantenedores del proyecto en la forma de un parche. Aquellos que distribuyen sistemas operativos que incluyen programas abiertos usualmente requieren hacer cambios en los paquetes que distribuyen de tal forma que se armen apropiadamente en sus ambientes. Cuando hay pocos cambios por mantener, es muy sencillo administrar un solo parche con los programas est andar diff y patch (ver la secci on 12.4 para ver c omo emplear tales herramientas). Cuando la cantidad de cambios comienza a crecer, tiene sentido mantener parches como porciones de trabajo individual, de forma que cada cambio contiene solamente un arreglo de un fallo (el parche puede modicar varios cheros, pero est a haciendo una sola cosa), y puede tener cierta cantidad de tales parches para diferentes fallos y cambios locales. En esta situaci on, si env a un parche que arregla un fallo a los mantenedores principales de un paquete y ellos incluyen su arreglo en una publicaci on posterior, puede deshacerse de tal parche cuando se actualice a la nueva versi on. rbol principal es algo tedioso y es f Mantener un solo parche frente a un a acil equivocarse, pero no es dif cil. Aunque, la complejidad del problema crece r apidamente a medida que la cantidad de parches que tiene que mantener crece. Con m as que una peque na cantidad de cambios, entender cu ales ha aplicado se convierte de algo desordenado a algo avasallante. Afortunadamente Mercurial provee una extensi on poderos: Colas de Mercurial (o simplemente MQ), que simplica en gran medida el problema de administraci on de parches.

12.2.

La prehistoria de las Colas de Mercurial

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

Los tama nos de las series de parches crecieron r apidamente. En el 2002, Andrew Morton public o algunos guiones rdenes que estuvo usando para automatizar la tarea de administrar su cola de parches. Andrew us de l nea de o o exit osamente tales guiones para administrar centenas (a veces millares) de parches en el n ucleo de Linux.

12.2.1.

Trabajar parches con quilt

A comienzos del 2003, Andreas Gruenbacher y Martin Quinson tomaron la aproximaci on de los guiones de Andrew 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 on de parches, fue adoptado en gran medida por desarrolladores de programas abiertos. rbol de directorios. Para comenzar, usted le indica a quilt que administre Quilt maneja una pila de parches sobre un a rbol de directorios, le indica qu un a e cheros manejar; Este almacena los nombres y los contenidos de estos cheros. Para arreglar un fallo, usted crea un nuevo parche (con una sola orden), edita los cheros que est a arreglando y refresca el parche. rbol de directorios; actualiza el parche con todos los cambios que usted El paso de refresco hace que quilt revise el a haya hecho. Puede crear otro parche sobre el primero, que har a seguimiento de los cambios requeridos para modicar rbol desde el a rbol con un parch aplicado a un el a arbol con dos parches aplicados. rbol. Si pop1 un parche, los cambios hechos por tal parchve Usted puede elegir qu e cambios desea aplicar al a rbol de directorios. Quilt recuerda qu desaparece ran del a e parches ha sacado, para que pueda introducirlos2 posteri rbol de directorios se restaurar ormente, as el a a con las modicaciones que vienen del parche. Lo m as importante es ltimo parche ser que puede ejecutar la orden refresh en cualquier momento, y el u a actualizado. Esto signica que puede, en cualquier momento, cambiar qu e parches ser an aplicados y qu e modicaciones hacen ellos. Quilt no tiene nada que ver con herramientas de control de versiones, y puede trabajar bien sobre un conjunto de fuentes que viene de un 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 o las caracter sticas de quilt y escribi o una extensi on que llam o Colas de Mercurial3 , que proporcion o un comportamiento a Mercurial al estilo quilt. La diferencia clave entre quilt y MQ es que quilt no sabe nada acerca del sistema de control de revisiones, mientras que MQ est a integrado con Mercurial. Cada parche que usted introduce se representa como un conjunto de cambios en Mercurial. Si sustrae un parche, el conjunto de cambios desaparece.4 Dado que quilt no se preocupa por las herramientas de control de revisiones, contin ua siendo una porci on de til para aquellas situaciones en las cuales no puede usar Mercurial y MQ. software tremendamente u

12.3.

La gran ventaja de MQ

No puedo sobreestimar el valor que MQ ofrece en la unicaci on de parches y el control de revisiones. La principal raz on por la cual los parches han persistido en el mundo del software libre y de fuentes abiertasa 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 en es bastante sutil. Si requiere realizar un experimento ((((wild-eyed)))), debe ser cuidadoso en c omo lo hace, o puede dejar trazas innecesariaso peor a un, desconcertantes o desestabilizantes de los pasos y errores en el registro de revisiones de forma permanente. En contraste, con la cohesi on de MQ con el control de revisiones distribuidos y los parches, resulta m as sencillo 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 es cuando encontremos que facilita la comprensi on
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 on de parches con el control de revisiones hace que el entender los parches y revisar sus efectosy sus interacciones con el c odigo en el cu al est an enlazados sea mucho m as sencillo. Dado que todo parche que se aplique tiene un conjunto de cambios asociado, puede usar hg log filename para ver qu e conjuntos de cambios y parches afectaron un chero. Puede usar la orden bisect para hacer una b usqueda binaria sobre todos los conjuntos de cambios y parches aplicados para ver d onde se introdujo un fallo o d onde fue arreglado. Puede usar la orden hg annotate para ver qu e conjuntos de cambios o parches modicaron una l nea particular de un chero fuente. Y mucho m as.

12.4.

Entender los parches

til para entender de qu Dado que MQ no esconde su naturaleza parche-c entrica, es muy u e se tratan los parches, y 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 l neas. La orden patch entiende esas diferencias como modicaciones para construir un chero. Vea en la gura 12.1 un ejemplo rdenes en acci sencillo de tales o on.
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

rdenes diff y patch Figura 12.1: Uso sencillo de las o 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 ermino parche, dado que es el que m as comunmente se usa.) Un parche puede comenzar con un texto arbitrario; la orden patch ignora este texto, pero MQ lo usa como el mensaje de consignaci on cuando se crean conjuntos de cambios. Para encontrar el inicio del contenido de un parche, la orden patch busca la primera l nea 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 a modicando; contiene el nombre del chero a modicar. Cuando patch ve un nuevo encabezado de chero, busca un chero con ese nombre para modicarlo. Despu es del encabezaado vienen varios trozos. Cada trozo comienza con un encabezado; que identica el rango de l neas del chero que el trozo debe modicar. Despu es del encabezado, un trozo comienza y termina con unas pocas l neas (usualmente tres) de texto del chero que no han sido modicadas; las cuales llamamos el contexto del trozo. Si solamente hay una peque na cantidad de contexto entre trozos sucesivos, diff no imprime un nuevo encabezado para el trozo, continua integrando los trozos, con unas l neas de contexto entre las modicaciones. Cada l nea de contexto comienza con un caracter de espacio. En el trozo, si una l nea comienza con - signica elimine esta l nea, si la l nea comienza con un + signica inserte esta l nea. Por ejemplo, una l nea que se 142

modica se representa con una l nea eliminada y una l nea insertada. Retomaremos aspectos m as sutiles acerca de parches posteriormente (en la secci on 12.6), pero en el momento usted ya deber a tener suciente informaci on para usar MQ.

12.5.

Comenzar a usar Colas de Mercurial

Dado que MQ est a implementado como una extensi on, debe habilitarla expl citamente antes de comenzar a usarla. (No necesita descargar nada; MQ viene con la distribuci on est andar de Mercurial.) Para habilitar MQ, edite su chero /.hgrc, y a nada las l neas de la gura 12.5.
1 2

[extensions] hgext.mq =

Figura 12.2: L neas a a nadir en /.hgrc para habilitar la extensi on MQ Cuando la extensi on est e habilitada, aparecer an varios comandos. Para vericar que la extensi on est a trabajando, puede usar hg help para ver si la orden hg qinit est a disponible; vea un ejemplo en la gura 12.3.
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 omo vericar que MQ est a habilitado Puede usar MQ en cualquier repositorio de Mercurial, y sus comandos solamente operar an con tal repositorio. Para comenzar, basta con preparar el repositorio con la orden hg qinit (ver la gura 12.4). Esta orden crea un directorio vac o llamado .hg/patches, donde MQ mantendr a sus metadatos. Como otras ordenes de Mercurial, la 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 a como el nombre del chero en el directorio .hg/patches, como puede apreciarlo en 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 en hay otros dos nuevos cheros en el directorio .hg/patches: series y status. El chero series lista todos los parches de los cuales MQ tiene noticia para este repositorio, con un parche por l nea. 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 a editar el chero series a mano; por ejemplo, cambiar el orden en que se aplican ciertos parches. A pesar de esto, es una mala idea editar manualmente el chero status, dado que es f acil desorientar a MQ acerca de lo que est a pasando. Una vez que haya creado un nuevo parche, puede editar los cheros en el directorio de trabajo, como lo har a rdenes que de a Mercurial, tales como hg diff y hg annotate, trabajar usualmente. Toda las o an de la misma 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 a trabajando. Esta orden almacena los cambios que haya hecho al directorio actual de 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 a este parche sobre su parche anterior. Para un ejemplo, ver la gura 12.8. Note que el parche contiene los cambios en nuestro parche anterior como parte de su contexto (lo ver a m as claramente en la salida de hg annotate). nicamente Hasta ahora, con excepci on de hg qnew y hg qrefresh, hemos sido cuidadosos para aplicar u rdenes usuaales de Mercurial. De todas maneras, MQ ofrece muchos comandos que son m o as sencillos de usar cuando est e pensando acerca de parches, como se puede ver en la gura 12.9: La orden hg qseries lista cada parche del cual MQ tiene noticia en este repositorio, desde el m as antiguo ltimo creado). hasta el m as nuevo (El u La orden hg qapplied lista cada parche que MQ haya aplicado en este repositorio, de nuevo, desde el m as antiguo hasta el m as nuevo (El aplicado m as recientemente).

12.5.4.

Manipular la pila de parches

La discusi on previa indic o que debe haber una diferencia entre los parches conocidos y aplicados, y efectivamente la hay. MQ puede manejar un parche sin que este haya sido aplicado al repositorio. 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 on de un parche con la orden hg qpop. MQ sabe acerca de, o maneja un parche sustra do, pero el parche ya no tendr a un conjunto de cambios correspondientes en el repositorio, y el directorio de trabajo no contendr a los cambios hechos por el parche. La gura 12.10 ilustra la diferencia entre parches aplicados y seguidos. Puede reaplicar un parche no aplicado o sustra do con la orden hg qpush. Esto crea un nuevo conjunto de cambios correspondiente al parche, y los cambios del parche estar an presentes de nuevo en el directorio de trabajo. Vea ejemplos de hg qpop y hg qpush en acci on en la gura 12.11. Vea que hemos sustra do uno o dos parches, la salida dehg qseries contin ua igual, mientras que hg qapplied ha cambiado.

12.5.5.

Introducir y sustraer muchos parches

nico parche cada vez, puede introducir y sustraer varios Mientras que hg qpush y hg qpop operan sobre un u parches de una vez. La opci on -a de hg qpush introduce todos los cambios que no hayan sido aplicados, mientras que la opci on -a de hg qpop sustrae todos los cambios aplicados. (Vea la secci on 12.7 m as adelante en la cual se explican otras formas de de introducir y sustraer varios cambios.)

12.5.6.

Medidas de seguridad y c omo saltarlas

rdenes MQ revisan el directorio de trabajo antes de hacer cualquier cosa, y fallan si encuentran alguna Muchas o modicaci on. Lo hacen para garantizar que usted no pierda cambio alguno de los que haya hecho, pero que no hayan sido incorporados en alg un parche. La gura 12.13 ilusta esto; la orden hg qnew no crear a un nuevo parche si hay cambios notorios, causados en este caso por aplicado la orden hg add a file3. rdenes que revisan el directorio actual cuentan con una opci Las o on Se lo que estoy haciendo, que siempre est a nombrada como -f. El signicado exacto de -f depende de la orden. Por ejemplo, hg qnew -f incorporar an cualquier cambio notorio en el nuevo parche que crea pero hg qpop -f revertir a las modicaciones a cualquier chero que haya sido afectado por el parche que est a siendo sustra do. Aseg urese de leer la documentaci on de la opci on -f de cada comando antes de usarla!

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 es del primero

12.5.7.

Trabajar con varios parches a la vez

La orden hg qrefresh siempre refresca el u ltimo parche aplicado. Esto signica que usted puede suspender su ltimo y trabajar en trabajo en un parche (refresc andolo), sustraerlo o introducirlo para lograr que otro parche est e de u ese parche por un rato. A continuaci on un ejemplo que ilustra c omo puede usar esta habilidad. Digamos que est a desarrollando una nueva caracter stica 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 odigo que ha a nadido a la parte fundamental. Si ve que hay un fallo en la parte fundamental mientras est a trabajando en el parche de UI5 , es f acil arreglar la parte fundamental. 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 hab a quedado.
5 N.

del T. Interfaz de Usuario, User Interface en ingl es

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 as acerca de parches

til conocer ciertos detalles de c MQ usa la orden GNU patch para aplicar los parches, por lo tanto es u omo trabaja patch, y tambi en acerca de los parches.

12.6.1.

La cantidad de franjas

Si ve el encabezado de un parche, notar a que la ruta al chero tiene un componente adicional al principio, que no est a presente en la ruta. Esta es una traza de c omo generaba anteriormente los parches la gente (algunos a un lo hacen, pero es raro con las herramientas de control de revisiones del actuales). Alicia desempaquetar a un comprimido, editar a sus cheros, y querr a crear un parche. Por lo tanto ella renombrar a su directorio de trabajo, desempacar a el comprimido de nuevo (para lo cual necesit o el renombramiento), y usar a las opciones -r y -N de diff para generar recursivamente un parche entre el directorio original y el modicado. El resultado ser a que el nombre del directorio original estar a al principio de toda ruta en cada encabezado de chero, y el nombre del directorio modicado estar a al frente de la porci on derecha de la ruta del chero. Como alguien que reciba un parche de Alicia en la red podr a obtener dos directorios, uno original y el otro modicado con exactamente los mismos nombres, la orden patch tiene la opci on -p que indica la cantidad de componentes de la ruta a eliminar cuando se vaya a aplicar el parche. Este n umero se llama la cantidad de eliminaciones. La opci on con -p1 signica elimine uno. Si patch ve un nombre de chero foo/bar/baz en el encabezado del chero, eliminar a foo y tratar a de parchar un chero llamado bar/baz. (Hablando estrictamente, la cantidad de 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 a foo/bar en bar, pero /foo/bar (note la barra extra) en foo/bar.) La cantidad a eliminarest andar para parches es uno; casi todos los parches contienen un componente inicial de 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 on que no sea uno, no podr a aplicar hg qimport en primera medida, porque hg qimport no tiene todav a una opci on -p option (ver Fallo de Mercurial No. 311). Lo mejor que puede hacer es aplicar hg qnew por su cuenta, y despu es usar patch -pN para aplicar tal parche, seguido de hg addremove para tener en 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 as informaci on.

12.6.2.

Estrategias para aplicar parches

Cuando patch aplica un trozo, intenta varias estrategias sucesivas que decrecen en precisi on para intentar aplicarlo. Esta t ecnica de pruebas y error aveces permite que un parche que fue generado contra una versi on anterior de un chero, sea aplicada sobre una versi on m as nueva del mismo. Primero patch intenta una correspondencia perfecta donde los n umeros de l nea, el contexto y el texto a modicar deben coincidir perfectamente. Si no lo logra, intenta encontrar una correspondencia exacta del contexto, sin tener en cuenta el n umero de l nea. Si es exitoso, imprime una l nea indicando que el trozo fue aplicado, pero a un corrimiento del n umero de l nea original. ltima l Si falla la correspondencia por contexto, patch elimina la primera y la u nea del contexto, e intenta una correspondencia reducida del contexto. Si el trozo con contexto reducido es exitoso, imprime un mensaje indicando que aplic o el trozo con un factor difuso (el n umero despu es del factor difuso indica cu antas l neas de contexto patch 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 ecnicas funciona, patch imprime un mensaje indicando que el trozo en cuesti on se desech o. Almacena los trozos desechados (tambi en llamados descartados) en un chero con el mismo nombre, y la extensi on .rej a nadida. Tambi en almacena una copia igual al chero original con la extensi on .orig; la copia del chero sin extensi on contendr a cualquier cambio hecho por los trozos que s se aplicaron sin problema. Si usted tiene un parche que modica foo con seis trozos, y uno de ellos falla al aplicarse, tendr a : un chero original foo.orig, un 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 on de parches

tiles por saber acerca de c Hay ciertas cosas u omo trabaja patch con los cheros: Deber a 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 vac o. Y por lo tanto su idea de Borr e este chero deber a pensarse como toda l nea de este chero fue eliminada en un parche. Trata la adici on de un chero como un diff entre un chero vac o y el chero a ser adicionado. Por lo tanto en un parche su idea de A nad este chero se ver a como toda l nea de este chero fue a nadida. Trata el renombramiento de un chero como la eliminaci on del nombre anterior y la adici on del nuevo nombre. 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 vac os, por lo tanto no puede usar un parche para representar la noci on rbol. A nad este chero vac o al a

12.6.4.

Cuidado con los difusos

Cuando aplique un trozo con un corrimiento, o con un factor difuso, aveces ser a taotalmente exitoso, tales t ecnicas inexactas dejan claramente la posibilidad de corromper el chero parchado. Los casos m as t picos involucran aplicar 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, deber a asegurarse que los cheros modicados est en correctos despu es del suceso. Casi siempre es buena idea refrescar un parche que fue aplicado con un corrimiento o un factor difuso; refrescar el parche genera nueva informaci on de contexto que permitir a aplicarlo limpiamente. Digo casi siempre, no siempre, puesto que en ciertas ocasiones refrescar un parche lo har a fallar frente a una revisi on diferente del chero. En algunos casos, como por ejemplo, cuando usted est a manteniendo un parche que debe estar encima de m ultiples revisiones de rbol de fuentes, es aceptable tener un parche aplicado algo difuso, siempre que haya vericado los resultados del un a proceso de parchar.

150

12.6.5.

Manejo de descartes

Si hg qpush falla al aplicar un parche, mostrar a un texto de error y saldr a. Si ha dejado cheros .rej, es mejor arreglar los trozos descartados antes de introducir parches adicionales o hacer cualquier otra cosa. Si su parche sol a aplicarse limpiamente, y ya no lo hace porque ha cambiado c odigo subyacente en el cual se basa su parche, las Colas de Mercurial pueden ayudar; consulte la secci on 12.8. Desafortunadamente, no hay grandes t ecnicas para tratar los trozos descartados. Casi siempre deber a consultar el chero .rej y editar el chero objetivo, aplicando los trozos descartados a mano. Si es aventurero, Neil Brown, un hacker del n ucleo Linux, escribi o una herramienta llamada wiggle [Bro], que es m as vigorosa que patch en su intento de hacer que se aplique un parche. Otro hacker del nucleo Linux, Chris Mason (el autor de las Colas de Mercurial), escribi o una herramienta similar llamada mpatch [Mas], que sigue una aproximaci on sencilla para automatizar la aplicaci on de trozos descartados por 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 podr a aplicarse mejorpor completo o una partesi estaba cortado en trozos m as peque nos. Un trozo remueve l neas con contenido ligeramente diferente que aquellas que est an presentes en el chero. Si usted usa wiggle o mpatch, deber a ser doblemente cuidadoso al revisar sus resultados cuando haya terminado. De hecho, mpatch refuerza este m etodo de revisar por partida doble su salida, dej andolo a usted en un programa de fusi on cuando la herramienta haya terminado su trabajo, de tal forma que usted pueda vericar lo que ha hecho y pueda terminar de aplicar cualquier fusi on faltante.

12.7.

maximizar el rendimiento de MQ

MQ es muy eciente al tratar con una gran cantidad de parches. Corr unos experimentos de desempe no a mediados del 2006 para una charla que d en la conferencia EuroPython 2006 [OS06]. Emple e la serie de parches para el n ucleo Linux 2.6.17-mm1, que contaba con 1.738 parches. Los apliqu e sobre un repositorio del n ucleo de Linux con todas las 27.472 revisiones entre 2.6.12-rc2 y 2.6.17. En mi port atil antiguo y lento, logr e aplicar hg qpush -a a los 1.738 parches en 3.5 minutos, y hg qpop -a en 30 segundos. (En un port atil m as nuevo, el tiempo para introducir todos los parches, se logr o en menos de dos minutos.) Apliqu e hg qrefresh sobre uno de los parches m as grandes (que hizo 22.779 l neas de cambios en 287 cheros) en 6,6 segundos. rboles grandes, y adem Claramente, MQ funciona adecuadamente en a as hay unos trucos que pueden emplearse para obtener el m aximo desempe no. En primer lugar, trate de hacer en lote las operaciones. Cada vez que ejecute hg qpush o hg qpop, tales rdenes revisan el directorio de trabajo para asegurarse de que usted no ha hecho cambios y ha olvidado ejecutar hg o rbol peque rbol mediano (con decenas qrefresh. En un a no, el tiempo de esta revisi on puede ser m nimo, Pero en un a de miles de cheros), puede tomar un segundo o m as. rdenes hg qpush y hg qpop le permiten introducir o sustraer varios parches en una operaci Las o on. Puede identicar el parche destino que desee. Cuando aplique hg qpush con un destino, introducir a tantos parches como sea necesario hasta que el especicado est e en el tope de la pila. Cuando emplee hg qpop con un destino, MQ sustraer a parches hasta que el parche destino est e en el tope. Puede identicar un parche destino con el nombre del parche o con el n umero. Si se reere al n umero, los parches se contar an desde cero; esto signica que el primer parche es cero, el segundo es uno y as sucesivamente.

151

12.8.

Actualiar los parches cuando el c odigo cambia

Es com un contar con una pila de parches sobre un repositorio que usted no modica directamente. Si est a trabajando en cambios de c odigo de otros, o en una caracter stica que tarda bastante en desarrollarse comparada con la tasa de cambio del c odigo sobre la cual se est a trabajando, necesitar a sincronizarse con el c odigo, y ajustar cualquier trozo en sus parches que ya no est en al d a. A esto se le llama hacer rebase a su serie de parches. La v a m as sencilla de hacerlo es con hg qpop -a sobre sus parches, despu es hacer hg pull de los cambios en el repositorio, y nalmente hacer hg qpush -a con sus parches de nuevo. MQ dejar a de de introducir parches siempre que llegue a un parche que no se pueda aplicar debido a un conicto, permiti endole a usted arreglarlo, aplicar hg qrefresh al parche afectado y continuar introduciendo hasta que haya arreglado la pila completa. Esta aproximaci on es sencilla y funciona bien si no espera cambios en el c odigo original que afecte en gran medida los parches que usted est e aplicando. Si su pila de parches toca c odigo que es modicado frecuentemente o de forma invasiva sobre el c odigo subyacente, arreglar trozos manualmente se vuelve desgastante. 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 on para ayudarle a a resolver conictos entre sus parches y una revisi on distinta. 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 a los parches en un directorio llamado .hg/patches.N , donde N es un entero peque no. Tambi en consigna un conjunto de cambios de seguridad sobre sus parches aplicados; esto es para mantener el hist orico, y guarda los estados de los cheros series y status. 3. Use hg pull para traer los nuevos cambios en el repositorio subyacente. (No ejecute hg pull -u; vea m as adelante por qu e.) 4. Actualice a la nueva revisi on punta con hg update -C para sobreescribir los parches que haya introducido. 5. Fusione todos los parches con hg qpush -m -a. La opci on -m de hg qpush le indica a MQ que haga una fusi on que involucra tres fuentes si el parche falla al aplicarse. 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 o con hg qsave, y aplica una fusi on de tres con el correspondiente conjunto de cambios. Esta fusi on usa la maquinaria de Mercurial, por lo tanto puede mostrar una herramienta de fusi on GUI para ayudarle a resolver los problemas. Cuando termine de resolver los efectos de un parche, MQ refrescar a su parche basado en el resultado de la fusi on. Al nal de este proceso, su repositorio tendr a una cabeza extra de la antigua cola de parches, y una copia de la cola de parches anterio estar a en .hg/patches.N . Puede eliminar la cabeza extra con hg qpop -a -n patches.N o hg strip. Puede eliminar .hg/patches.N una vez que est e seguro de que no lo necesita m as como copia de seguridad.

12.9.

Identicar parches

rdenes de MQ le permiten trabajar reri Las o endose al nombre del parche o al n umero. Es obvio hacerlo por el nombre; por ejemplo se pasa el nombre foo.patch a hg qpush, que introducir a los parches hasta que foo.patch se aplique. Para hacerlo m as corto, puede referirse a un parche con un nombre y un corrimiento de n umero; por ejemplo, foo.patch-2 signica dos parches antes de foo.patch, mientras que bar.patch+4 signica cuatro parches despu es de bar.patch.

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. rdenes normales de Mercurial. Cada comando que acepte IdentiMQ facilita el trabajo cuando est a usando o cadores de conjuntos de cambios tambi en aceptar a el nombre de un parche aplicado. MQ aumenta las etiquetas normalmente en el repositorio con un distintivo para cada parche aplicado. Adicionalmente, las etiquetas especiales qbase ltimo, respectivamente. y qtip identican los parches primero y u Junto con las capacidades de Mercurial para etiquetar, estas adiciones hacen que trabajar con parches sea muy sencillo. ltimos cambios que ha hecho? Desea enviar una bomba de parches a una lista de correo con los u
1

hg email qbase:qtip (No sabe qu e es una bomba de parches? Consulte la secci on 14.4.) rbol? Desea ver todos los parches desde que se aplic o foo.patch sobre los cheros de un subdirectorio en su a

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 a el nombre del parche como una etiqueta, usualmente con la salida normal. Esto facilita distinguir 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 on util

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 es de introducir/sustraer tendr a una identidad distinta que aquella que representaba el conjunto de cambios anteriormente. Consulte la seccti on B.1.13 para obtener informaci on del por qu e de esto. 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 on de parches de ese conjunto de cambios y los conjuntos de cambios que se encuentran por debajo en la pila de parches. Si intenta hacerlo, parecer a que ha sido exitoso, pero MQ se 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 on o presencia de parches. Esto presenta la interesante posibilidad de administrar los contenidos del directorio de parches como un repositorio til de trabajar. Por ejemplo, puede trabajar en un parche por un rato, de Mercurial por su cuenta. Puede ser una forma u hacerle hg qrefresh y despu es hacer hg commit al estado actual del parche. Esto le permite devolverse a esa versi on del parche posteriormente. Puede tambi en compartir diferentes versiones de la misma pila de parches entre varios repositorios subyacentes. Uso esto cuando estoy desarrollando una caracter stica del n ucleo Linux. Tengo una copia original de las fuentes del 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 caracter sticas de etiquetamiento al trabajar con MQ n ucleo para varias arquitecturas, y clon e un rpositorio en cada una que contiene los parches en los cuales estoy trabajando. Cuando quiero probar un cambio en una arquitectura diferente, introduzco mis parches actuales al repositorio rbol del kernel, sustraigo e introduzco todos mis parches, armo y pruebo el n de parches asociado con el a ucleo. 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 on -c para que se cree el directorio .hg/patches como un repositorio de Mercurial.

154

Nota: Si olvida usar la opci on -c option, puede ir al directorio .hg/patches en cualquier momento y ejecutar hg init. No olvide a nadir una entrada en el chero status del chero .hgignore, a pesar de que (hg qinit -c hace estodo de forma autom atica para usted); usted seguro no quiere administrar el chero status. MQ nota convenientemente que el directorio .hg/patches es un repositorio, har a hg add autom aticamente 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 erprete bash, puede incluir el siguiente recorte de c odigo6 en su chero /.bashrc.
1

alias mq=hg -R $(hg root)/.hg/patches rdenes de la forma mq pull al repositorio principal. Puede aplicar las o

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 aticamente los cambios que haga al directorio de parches. Si aplica hg pull, edita manualmente, o hace hg update a los parches o el chero series, tendr a que aplicar hg qpop -a y despu es hg qpush -a en el repositorio subyacente para que los cambios se reejen all . Si olvida hacerlo, puede confundir a MQ en cuanto a qu e parches se han aplicado.

12.12.

Otras herramientas para trabajar con parches

Cuando haya trabajado por cierto tiempo con parches, desear a herramientas que le ayuden a entender y manipular los parches con los que est e tratando. 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 e cheros afecta, y cu antos cambios introduce a cada chero y en total. (Me ha parecido interesante usar la opci on -p de diffstat, puesto que de otra forma intentar a hacer cosas inteligentes con prejos de cheros que terminan confundi endome.) El paquete patchutils [Wau] es invaluable. Provee un conjunto de peque nas utilidades que siguen la losof a Unix; cada una hace una cosa muy bien hecha a un parche. La orden patchutils que m as uso es filterdiff, que extrae subconjuntos de un chero de parche. Por ejemplo, dado un parche que modica centenas de cheros en nica invocaci docenas de directorios, una u on de filterdiff puede generear un parche m as peque no que solamente toca aquellos cheros con un patr on. Puede ver otro ejemplo en la secci on 13.9.2.

12.13.

Buenas pr acticas de trabajo con parches

En caso de que est e trabajando en una serie de parches para enviar a un proyecto de software libre o de fuentes abiertas, o en una serie que desea tratar como un conjunto de cambios regular, cuando haya terminado, puede usar t ecnicas sencillas para mantener su trabajo bien organizado. De nombres descriptivos a sus parches. Un buen nombre para un parche podr a ser rework-device-alloc.patch, porque da de forma inmediata una pista del prop osito del parche. Los nombres largos no deben ser un problema; no rdenes como hg qapplied y hg qtop. los estar a tecleando repetidamente, pero estar a ejecutando regularmente o Los nombres adecuados son especialmente importantes cuando tiene bastantes parches con los cuales trabajar, o si est a trabajando en diferentes tareas y sus parches toman solamente una porci on de su atenci on.
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);

rdenes diffstat, filterdiff, y lsdiff Figura 12.15: Las o Tenga en cuenta en qu e parche est a trabajando. Use la orden hg qtop para dar un vistazo al texto de sus parches frecuentementepor ejemplo, use hg tip -p)para asegurarse en d onde est a ubicado. En distintas oportunidades me sucedi o que apliqu e hg qrefresh a un parche distinto al que deseaba hacerlo, y usualmente es complejo migrar los cambios al parche correcto despu es de haberlo hecho mal. Por este motivo, vale la pena invertir ese poco tiempo para aprender c omo usar otras herramientas que describ en la secci on 12.12, particularmente diffstat y filterdiff. La primera le dar a una idea de qu e cambios est a haciendo 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 on. Primero se traen sus 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 on que comienza con hg locate mostrada m as arriba, borra todos los cheros en el directorio de trabajo, 157

as que la opci on --addremove de hg commit puede indicar qu e cheros se han eliminado en la nueva versi on del rbol de fuentes. a rbol de fuentes Finalmente, puede aplicar sus parches encima del nuevo a
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 ltimo parche aplicado, y concatena sus descripciones al nal de su ed nombre, en el orden que especique, en el u descripci on. Deber a sustraer los cambios para poder integrarlos. ltimamente aplicado es foo, e integra hg qfold El orden en el que integre los parches importa. Si el parche u l, terminar bar y quux en e a con un parche que tiene el mismo efecto que si hubiera aplicado primero foo, y despu es bar, seguido de quux.

12.14.3.

Fusionar una porci on de un parche dentro de otro

Fusionar partes de un parche dentro de otro es m as complejo que combinar completamente dos parches. 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 a modicar el parche del cu al ha fusionado los cambios. En cambio, MQ reportar a que hay unos trozos 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 as enredado, pero puede automatizarlo parcialmente. Use lsdiff -nvv para imprimir algunos 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 umeros: (en la primera columna) un n umero de chero para identicar cada chero modicado en el parche; (En la siguiente l nea, indentado) el n umero de l nea dentro de un chero modicado donde comienza el trozo; y (en la misma l nea) un n umero de trozo que identica el trozo. Tendr a que hacer una inspecci on visual, y leer el parche para identicar los n umeros de chero y trozo que desea, 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 on 12.14.2.

12.15.

Diferencias entre quilt y MQ

rdenes. Hay algunas diferencias en c Si le es familiar quilt, MQ provee un conjunto similar de o omo funcionan. Debe haber notado que la mayor a de comandos de quilt tienen su contraparte en MQ, que simplemente comienzan rdenes add y remove de quilt, que realmente son las o rdenes hg add y hg con q. Las excepciones son las o remove de Mercurial. No hay un equivalente en MQ para la orden edit de quilt.

159

Cap tulo 13

Usos avanzados de las Colas de Mercurial


Auunque es f acil aprender los usos m as directos de las Colas de Mercurial, tener algo de disciplina junto con algunas de las capacidadees menos usadas de MQ hace posible trabajar en entornos de desarrollo complejos. En este cap tulo, usar e como ejemplo una t ecnica que he usado para administrar el desarrollo de un controlador de dispositivo Inniband para el kernel de Linux. El controlador en cuesti on es grande (al menos en lo que se reere a controladores), con 25,000 l neas de c odigo esparcidas en 35 cheros fuente. Es mantenido por un equipo peque no de desarrolladores. Aunque mucho del material en este cap tulo es espec co de Linux, los mismos principios aplican a cualquier base de c odigo de la que usted no sea el propietario principal, y sobre la que usted necesita hacer un mont on de desarrollo.

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 asticos entre versiones frecuentemente. Esto signica que una versi on del controlador que funciona bien con una versi on particular del kernel ni siquiera compilar a correctamente contra, t picamente, cualquier otra versi on. Para mantener un controlador, debemos tener en cuenta una buena cantidad de versiones de Linux en mente. rbol de desarrollo principal del kernel de Linux. En este caso el mantenimiento del c Un objetivo es el a odigo es compartido parcialmente por otros desarrolladores en la comunidad del kernel, quienes hacen modicaciones de-af an al controlador a medida que desarrollan y renan subsistemas en el kernel. Tambi en mantenemos algunos backports para versiones antiguas del kernel de Linux, para dar soporte a las necesidades de los clientes que est an corriendo versiones antiguas de Linux que no incorporan nuestros controladores. (Hacer el backport de un pedazo de c odigo es modicarlo para que trabaje en una versi on de su entorno objetivo anterior a aquella para la cual fue escrito.) Finalmente, nosotros liberamos nuestro software de acuerdo a un cronograma que no necesariamente est a alineado con el que usan los distribuidores de Linux y los desarrolladores del kernel, as que podemos entregar nuevas caracter sticas a los clientes sin forzarlos a actualizar kernels completos o distribuciones.

13.1.1.

Aproximaciones tentadoras que no funcionan adecuadamente

Hay dos maneras est andar de mantener una porci on de software que debe funcionar en muchos entornos diferentes. nico entorno. El problema de esta aproximaci La primera es mantener varias ramas, cada una pensada para un u on es que usted debe tener una disciplina f errea con el ujo de cambios entre repositorios. Una nueva caracter stica o un arreglo de fallo deben empezar su vida en un repositorio pr stino, y luego propagarse a cada repositorio de backport. Los cambios para backports est an m as limitados respecto a las ramas a las que deber an propagarse; un cambio para backport que es aplicado a una rama en la que no corresponde probablemente har a que el controlador no compile. 160

nico a rbol de c La segunda es mantener un u odigo fuente lleno de declaraciones que activen o desactiven secciones rbol del kernel de Linux, de c odigo dependiendo del entorno objetivo. Ya que estos ifdefs no est an permitidos en el a rbol limpio. Una base de c debe seguirse alg un proceso manual o autom atico para eliminarlos y producir un a odigo mantenida de esta manera se convierte r apidamente en un nido de ratas de bloques condicionales que son dif ciles de entender y mantener. Ninguno de estos enfoques es adecuado para situaciones en las que usted no es due no de la copia can onica rbol de fuentes. En el caso de un controlador de Linux que es distribuido con el kernel est rbol de de un a andar, el a Linux contiene la copia del c odigo que ser a considerada por el mundo como la can onica. La versi on ocial de mi controlador puede ser modicada por gente que no conozco, sin que yo siquiera me entere de ello hasta despu es de rbol de Linus. que los cambios aparecen en el a Estos enfoques tienen la debilidad adicional de dicultar la generaci on de parches bien formados para enviarlos a la versi on ocial. 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 caracter sticas adicionales que hacen el trabajo m as agradable.

13.2.

Aplicar parches condicionalmente mediante guardias

Tal vez la mejor manera de conservar la cordura con tantos entornos objetivo es poder escoger parches espec cos para aplicar para cada situaci on. MQ provee una caracter stica llamada guardias (que se origina del comando guards sto. Para empezar, creemos un repositorio sencillo para experimentar. de Quilt) que hace precisamente e
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 no repositorio que contiene dos parches que no tienen ninguna dependencia respecto al otro, porque tocan cheros diferentes. La idea detr as de la aplicaci on condicional es que usted puede etiquetar un parche con un guardia, que simplemente es una cadena de texto de su elecci on, y luego decirle a MQ que seleccione guardias espec cos para usar cuando aplique parches. MQ entonces aplicar a, u omitir a, un parche vigilado, dependiendo de los guardias que usted 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 e guardias deben aplicarse a un parche, o mostrar los guardias que est an en efecto. Sin ning un argumento, el comando muestra los guardias del parche actual de la parte m as alta de 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 nico guardia sobre el parche despu hg qguard +c en el mismo parche, el u es del comando ser a +c. Mercurial almacena los guardias en el chero series; la forma en que son almacenados es f acil tanto de entender como de editar a mano. (En otras palabras, usted no tiene que usar el comando hg qguard si no lo desea; est a bien 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 e guardias est an activos en cualquier momento. El efecto de esto es determinar qu e parches aplicar a MQ la pr oxima vez que usted ejecute hg qpush. No tiene ning un otro efecto; en 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 l nea 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 a interesado, los guardias seleccionados actualmente est an almacenados en el chero guards.

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 alido, MQ se 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 un guardia negativo que corresponda con cualquiera de los guardias seleccionados, se salta el parche. Si el parche tiene alg un guardia positivo que corresponda con cualquiera de los guardias seleccionados, se aplica 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

rbol En el trabajo del controlador de dispositivo que mencion e anteriormente, yo no aplico los parches a un a normal del kernel de Linux. En cambio, uso un repositorio que s olo contiene una instant anea de los cheros fuente y de cabecera que son relevantes para el desarrollo de Inniband. Este repositorio tiene un 1 % del tama no del repositorio l. del kernel, por lo que es m as f acil trabajar con e rbol del kernel Luego escojo una versi on base sobre la cual son aplicados los parches. Es una instant anea del a de Linux en una revisi on de mi elecci on. Cuando tomo la instant anea, almaceno el ID de conjunto de cambios en el rbol mensaje de consignaci on. Ya que la instant anea preserva la forma y el contenido de las partes relevantes del a rbol normal del kernel. del kernel, puedo aplicar mis parches sobre mi peque no repositorio o sobre un a 163

rbol base sobre el que se aplican los parches deber rbol de desarrollo Normalmente, el a a ser una instant anea de un a rbol ocial con pocas o ninguna muy reciente. Esto facilita mucho el desarrollo de parches que puedan ser enviados al a modicaci on.

13.7.

Dividir el chero series

Yo categorizo los parches en el chero series en una serie de grupos l ogicos. Cada secci on de parches similares empieza con un bloque de comentarios que describen el prop osito de los parches que le siguen. La secuencia de grupos de parches que mantengo se muestra a continuaci on. El orden de los grupos es importante; explicar e porqu e luego de que presente los grupos. El grupo aceptado. Son parches que el equipo de desarrollo ha enviado al mantenedor del subsistema Inni l ha aceptado, pero que no est band, y que e an presentes en la instant anea en la cual est a basada el repositorio nicamente para transformar el a rbol en un estado peque no. Estos son parches de s olo lectura, presentes u 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 an terminados. Estos parches ser an de s olo lectura por un buen tiempo. Si el mantenedor ocial los acepta cuando los env e, los l solicita que modicaciones en alguno de ellos, los mover mover e al nal del grupo aceptado. Si e e al principio del grupo revisar. El grupo en proceso. Parches que est an siendo activamente desarrollados, y no deber an ser enviados a ninguna parte a un. rbol de fuentes a versiones antiguas del a rbol del kernel. El grupo backport. Parches que adaptan el a El grupo no enviar. Parches que por alguna raz on nunca deben ser enviados al mantenedor ocial del kernel. Por ejemplo, alguno de esos parches podr a cambiar las cadenas de identicaci on embebidas del controlador para hacer m as f acil la distinci on, en pruebas de campo, entre una versi on del controlador de salida-del- arbol y una versi on entregada por un vendedor de alguna distribuci on. Ahora volvemos a las razones para ordenar los grupos de parches en esta manera. Quisi eramos que los parches del fondo de la pila sean tan estables como sea posible, para no tener que revisar parches m as arriba debido a cambios de contexto. Poner los parches que nunca cambiar an en el primer lugar del chero series sirve a este prop osito. rbol de fuentes Tambi en desear amos que los parches que sabemos que debemos modicar sean aplicados sobre un a 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 e parches deben ser aplicados. Los parches aceptados son vigilados con accepted. Yo habilito este guardia la mayor a de las veces. Cuando rbol donde los parches ya est aplico los parches sobre un a an presentes, puedo desactivar este parche, y los parches que lo siguen se aplicar an sin problemas. Los parches que est an terminados, pero no han sido enviados, no tienen guardias. Si estoy aplicando la pila rbol ocial, no necesito habilitar ning rbol de fuentes de parches a una copia del a un guardia para obtener un a razonablemente seguro. 164

Los parches que necesitan revisi on antes de ser reenviados tienen el guardia rework. Para aquellos parches que a un est an bajo desarrollo, uso devel. Un parche de backport puede tener varios guardias, uno para cada versi on del kernel a la que aplica. Por ejemplo, un parche que hace backport de un segmento de c odigo a 2.6.9 tendr a un guardia 2.6.9. rbol de fuentes acabar La variedad de guardias me brinda una exibilidad considerable para determinar qu e tipo de a e por obtener. En la mayor a de las situaciones, la selecci on de guardias apropiados es automatizada durante el proceso de compilaci on, pero puedo ajustar manualmente los guardias a usar para circunstancias poco comunes.

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 on de c odigo que usa una caracter stica del kernel que no est a presente en la versi on anterior del kernel, para que el controlador siga funcionando correctamente en esa versi on anterior. til al escribir un buen parche de backport es hacer parecer que el c Una meta u odigo hubiera sido escrito para la versi on vieja del kernel que usted tiene como objetivo. Entre menos intrusivo el parche, m as f acil ser a entenderlo y mantenerlo. Si usted est a escribiendo una colecci on de parches de backport para evitar el efecto de nido de ratas de tener muchos #ifdefs (secciones de c odigo fuente que s olo son usados condicionalmente) en su c odigo, no introduzca #ifdefs dependientes de versiones espec cas en los parches. En vez de eso, escriba varios parches, cada uno de ellos haciendo cambios incondicionales, y controle su aplicaci on usando guardias. 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 as dif cil usar herramientas como la extensi on patchbomb para automatizar el proceso de enviar los parches a un mantenedor ocial. La segunda es que un 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 a trabajando en un proyecto grande con MQ, no es dif cil acumular un gran n umero de parches. Por ejemplo, tengo un repositorio de parches que contiene m as de 250 parches. Si usted puede agrupar estos parches en categor as l ogicas separadas, usted puede almacenarlos en diferentes 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 a desarrollando un conjunto de parches en un per odo de tiempo grande, es una buena idea mantenerlos en un repositorio, como se discuti o en la secci on 12.11. Si lo hace, notar a r apidamente que usar el comando hg diff para mirar el historial del repositorio no es viable. Esto es debido en parte a que usted est a mirando la segunda derivada del c odigo real (el diff de un diff), pero tambi en porque MQ a nade ruido al proceso al modicar las marcas de tiempo y los nombres de directorio cuando actualiza un parche. Sin embargo, usted puede usar la extensi on extdiff, que es provisto junto con Mercurial, para convertir un diff de dos versiones de un parche en algo legible. Para hacer esto, usted necesitar a un paquete de un tercero llamado paquete provee un comando llamado interdiff, que muestra las diferencias entre dos diffs patchutils [Wau]. Este 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 on. Usted puede habilitar la extensi on extdiff de la manera usual, a nadiendo una l nea a la secci on [extensions] de su hgrc.

165

1 2

[extensions] extdiff = El comando interdiff espera recibir los nombres de dos cheros, pero la extensi on extdiff le pasa un par de directorios al programa que ejecuta, cada uno de los cuales puede contener una cantidad arbitraria de cheros. Por esto necesitamos un programa peque no que ejecute interdiff en cada par de cheros de estos dos directorios. Este programa est a disponible como hg-interdiff en el directorio examples del repositorio de c odigo fuente que acompa na a este libro.

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 usqueda de su int erprete de comandos, puede ejecutarlo como 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 a usar este comando tan largo a menudo, puede hacer que hgext lo haga disponible 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 on un comando interdiff, con lo que usted puede abreviar la invocaci on anterior de hg extdiff a algo un poco m as manejable.

hg interdiff -r A:B my-change.patch Nota: El comando interdiff trabaja bien s olo si los cheros contra los cuales 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 til. podr a no producir ning un resultado u til para m La extensi on extdiff es u as que solamente mejorar la presentaci on de los parches MQ. Para leer m as acerca de esto, vaya a la secci on 14.2.

167

Cap tulo 14

Anadir funcionalidad con extensiones


A pesar de que el coraz on de Mercurial es muy completo desde el punto de vista de funcionalidad, carece de caracter sticas rimbombantes deliberadamente. Esta aproximaci on de preservar la simplicidad mantiene el programa sencillo tanto para mantenedores como para usuarios. rdenes: usted puede a Si embargo Mercurial no le cierra las posibilidades a un conjunto inexible de o nadir caracter sticas como extensiones (aveces llamadas a nadidos1 ). Ya hemos discutido algunas de estas extensiones en cap tulos anteriores: La secci on 3.3 cubre la extensi on fetch; que combina jalar cambios y fusionarlos con los cambios locales en una sola orden: hg fetch. tiles en funcionalidades relacionadas con ganchos: En el cap tulo 10, cubrimos muchas extensiones que son u Los acl a naden listas de control de acceso; bugzilla a nade integraci on con el sistema de seguimiento de fallos Bugzilla; y notify env a noticaciones por correo de nuevos cambios. La extensi on de administraci on de parches MQ es tan invaluable que amerita dos cap tulos y un ap endice por s misma. El cap tulo 12 cubre lo b asico; el cap tulo 13 discute temas avanzados; y el ap endice B muestra en detalle cada orden. En este cap tulo cubriremos algunas extensiones adicionales disponibles para Mercurial, y daremos un vistazo a la maquinaria que necesita conocer en caso de que desee escribir una extensi on. En la secci on 14.1, discutiremos la posibilidad de mejorar el desempe no en gran medida con la extensi on inotify.

14.1.

con la extensi Mejorar el desempeno on inotify

Desea lograr que las operaciones m as comunmente usadas de Mercurial se ejecuten centenas de veces m as r apido? A leer! Mercurial tiene gran desempe no bajo circunstancias normales. Por ejemplo, cuando ejecuta la orden hg status, Mercurial tiene que revisar casi todos los cheros y directorios en su repositorio de forma que pueda desplegar el estado rdenes tienen que hacer tal trabajo tras bambalinas; por ejemplo la orden hg diff de los cheros. Muchas otras o usa la maquinaria de estado para evitar hacer operaciones de comparaci on costosas en cheros que obviamente no han cambiado. Dado que obtener el estado de los cheros es crucial para obtener buen desempe no, los autores de Mercurial han optimizado este c odigo en la medida de lo posible. Sin embargo, no puede obviarse el hecho de que cuando ejecuta hg status, Mercurial tendr a que hacer por lo menos una costosa llamada al sistema por cada chero administrado
1 N.

del T. plugins

168

ltima vez que se consign para determinar si ha cambiado desde la u o. Para un repositorio sucientemente grande, puede tardar bastante tiempo. Para mostrar en n umeros la magnitud de este efect, cre e un repositorio que conten a 150.000 cheros administrador. Tard o diez segundos para ejecutar hg status, a pesar de que ninguno de los cheros hab a sido modicado. Muchos sistemas operativos modernos contienen una facilidad de noticaci on de cheros. Si un programa se registra con un servicio apropiado, el sistema operativo le noticar a siempre que un chero de inter es haya sido creado, modicado o borrado. En sistemas Linux, el componente del n ucleo que lo hace se llama inotify. rdenes de hg status. La extensi on inotify habla con el componente inotify del n ucleo para optimizar las o La extensi on tiene dos componentes. Un daemonio est a en el fondo recibiendo noticaciones del subsistema inotify. Tambi en escucha conexiones de una orden regular de Mercurial. La extensi on modica el comportamiento de Mercurial de tal forma que, en lugar de revisar el sistema de cheros, le pregunta al daemonio. Dado que el daemonio tiene informaci on perfecta acerca del estado del repositorio, puede responder instant aneamente con el resultado, evitando la 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 on inotify habilitada, el tiempo se disip o a 0.1 seconds, un factor cien veces m as r apido. Antes de continuar, tenga en cuenta algunos detalles: La extensi on inotify es espec ca de Linux. Porque se enlaza directamente con el subsistema inotify del n ucleo Linux, no funciona en otros sistemas operativos. Deber a funcionar en cualquier distribuci on Linux a partir de comienzos del 2005. Las distribuciones m as antiguas deben tener un kernel sin inotify, o una versi on de glibc que no tiene necesariamente el soporte para la interfaz. No todos los sistemas de cheros pueden usarse con la extensi on inotify. Los sistemas de cheros tales como NFS no lo soportan, por ejemplo, si est a corriendo Mercurial en vaios sistemas, montados todos sobre el mismo sistema de cheros en red. El sistema inotify del kernel no tiene forma de saber acerca de los cambios hechos en otro sistema. La mayor a de sistemas de cheros locales (p.e. ext3, XFS, ReiserFS) deber an funcionar bien. Hacia mayo de 2007 la extensi on inotify no ven a de forma predeterminada en Mercurial2 , y es un poco m as compleja de activar que otras extensiones. Pero la mejora en el desempe no bien vale la pena! La extensi on ven a en dos partes: un conjunto de parches al c odigo fuente de Mercurial, y una librer a de interfaces Nota: Hay dos librer as 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 actica.

Nota: Si sigue las instrucciones a continuaci on, estar a reempl on previa de Mercurial que pudiera Para comenzar, es mejor tener una copia de Mercurial funcional instalada: biendo cualquier instalaci de Mercurial m as reciente y peligrosa. No diga que no se le 1. Clone el repositorio de interfaz entre Python e inotify. Armelo e inst alelo:
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 a activada de forma predeterminada

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 urese de instalar la extensi on Colas de Mercurial mq y que est en habilitadas. Si nunca ha usado MQ, lea la secci on 12.5 para poder comenzar r apidamente. 4. Vaya al repositorio de inotify y aplique todos los parches de inotify con la opci on -a de la orden hg qpush.
1 2

cd inotify hg qpush -a Si obtiene un mensaje de error de hg qpush, no deber a continuar. Mejor pida ayuda.

5. Arme e instale la versi on parchada de Mercurial.


1 2

python setup.py build --force sudo python setup.py install --skip-build

Una vez que haya armado una versi on funcional parchada de Mercurial, todo lo que necesita es habilitar la extensi on inotify colocando una entrada en su hgrc.
1 2

[extensions] inotify = Cuando la extensi on inotify est e habilitada, Mercurial iniciar a transparente y autom aticamente el daemonio de estado 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 on despu es de habilitar la extensi on inotify y ejecuta unos pocos comandos en diferentes repositorios, ver a que hay 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 on inotify habilitada, correr a casi con el mismo desempe no que una orden usual de Mercurial. Esto es debido a que el estado del daemonio necesita aplicar una b usqueda normal sobre el estado para poder tener una l nea de partida frente a la cual aplicar posteriormente actualizaciones del n ucleo. De todas formas, todo comando posterior que haga cualquier clase de revisi on del estado deber a ser notablemente m as r apido en repositorios con incluso un tama no modesto. A un mejor, a medida que su repositorio sea m as grande, mejor desempe no ver a. El daemonio inotify hace operaciones de estado de forma casi instant anea en repositorios de todos los tama nos! Si lo desea, puede iniciar manualmente un daemonio de estado con la orden hg inserve. Esto le da un control un poco m as no acerca de c omo deber a ejecutarse el daemonio. Esta orden solamente estar a disponible cuando haya habilitado la extensi on inotify. Cuando est e usando la extensi on inotify, no deber a ver diferencia en el comportamiento de Mercurial, con nica excepci la u on de que los comandos relacionados con el estado deber an ejectuarse mucho m as r apido que co rdenes no deber mo sol an hacerlo. Deber a esperar espec camente que las o an 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 on extdiff

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 a usar la extensi on extdiff. Esta le permitir a usar por ejemplo una herramienta gr aca de diff. La extensi on extdiff viene con Mercurial, y es f acil congurar. En la secci on [extensions] de su hgrc, basta con a nadir una entrada de una l nea para habilitar la extensi on.

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 a exactamente el mismo que con la orden interna hg diff, puesto que la salida de diff var a de un sistema a otro, incluso pasando las mismas opciones. Como lo indican las l neasmaking snapshot, la orden hg extdiff funciona creando dos instant aneas de rbol de fuentes. La primera instant su a anea es la revisi on fuente; la segunda es la revisi on objetivo del directorio de trabajo. La orden hg extdiff genera estas instant aneas en un directorio temporal, pasa el nombre de cada directorio a un visor de diffs temporal y borra los directorios temporales. Por cuestiones de eciencia solamente genera instant aneas de los directorios y cheros que han cambiado entre dos revisiones. Los nombres de los directorios de instant aneas tienen los mismos nombres base de su repositorio. Si su repositorio tiene por ruta /quux/bar/foo, foo ser a el nombre de cada instant anea de directorio. Cada instant anea de directorio tiene sus identicadores de conjuntos de cambios al nal del nombre en caso de que sea apropiado. Si una instant anea viene de la revisi on a631aca1083f, el directorio se llamar a foo.a631aca1083f. Una instant anea del directorio de trabajo no tendr a el identicador del conjunto de cambios, y por lo tanto ser a solamente foo en este ejemplo. Para ver c omo luce en la pr actica, veamos de nuevo el ejemplo hg extdiff antes mencionado. Tenga en cuenta que los diffs tienen los nombres de las instant aneas de directorio dentro de su encabezado. La orden hg extdiff acepta dos opciones importantes. La opci on -p le permite elegir un programa para ver las diferencias, en lugar de diff. Con la opci on -o puede cambiar las opciones que hg extdiff pasa a tal programa nicamente si est (de forma predeterminada las opciones son-Npru, que tienen sentido u a usando diff). En otros aspectos, la orden hg extdiff act ua de forma similar a como lo hace la orden hg diff de Mercurial: usted usa 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 on -c) en lugar de diferencias unicadas, y cinco l neas de contexto en lugar de las tres predeterminadas (pasando 5 como argumento a la opci on -C).
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 on mq junto con la orden interdiff est a en la secci on 13.9.2.

14.2.1.

Denici on de alias de comandos

rdenes hg extdiff y el visor de diferencias de su preferencia puede Acordarse de todas las opciones de las o rdenes que invocar ser dispendioso, y por lo tanto la extensi on extdiff le permite denir nuevas o an su visor de diferencias con las opciones exactas. Basta con editar su chero hgrc, y a nadir una secci on llamada [extdiff]. Dentro de esta secci on puede denir rdenes. Mostraremos como a varias o nadir la orden kdiff3. Despu es de denido, puede teclear hg kdiff3 y la extensi on a extdiff ejecutar a la orden kdiff3.
1 2

[extdiff] cmd.kdiff3 = Si deja vac a la porci on derecha de la denici on, como en el ejemplo, la extensi on extdiff usa el nombre de la orden se denir a como el nombre del programa externo a ejecutar. Pero tales nombres no tienen por qu e ser iguales. Denimos ahora la orden llamada hg wibble, que ejecuta kdiff3.

1 2

[extdiff] cmd.wibble = kdiff3 Tambi en puede especicar las opciones predeterminadas con las cuales desea invocar el visor de diferencias. Se 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 on DirDiff del editor vim.

1 2 3

[extdiff] cmd.vimdiff = vim opts.vimdiff = -f +next +execute "DirDiff" argv(0) argv(1)

14.3.

Uso de la extensi on transplant para seleccionar

Need to have a long chat with Brendan about this.

14.4.

Enviar cambios v a correo electr onico con la extensi on patchbomb

Varios proyectos tienen la cultura de revisi on de cambios, en la cual la gente env a sus modicaciones a una lista de correo para que otros las lean y comenten antes de consignar la versi on nal a un repositorio compartido. Algunos proyectos tienen personas que act uan como cancerberos; ellos aplican los cambios de otras personas a un repositorio para aquellos que no tienen acceso. 172

Mercurial facilita enviar cambios por correo para revisi on o aplicaci on gracias a su extensi on patchbomb. La extensi on es tan popular porque los cambios se formatean como parches y es usual que se env a un conjunto de cambios por cada correo. Enviar una gran cantidad de cambios por correos se llama por tanto bombardear el buz on de entrada del destinatario, de ah su nombre bombardeo de parches. Como es usual, la conguraci on b asica de la extensi on patchbomb consta de una o dos l neas en su hgrc.
1 2

[extensions] patchbomb = Cuando haya habilitado la extensi on, dispondr a de una nueva orden, llamada hg email. La forma mejor y m as segura para invocar la orden hg email es ejecutarla siempre con la opci on -n; que le mostrar a lo que la orden enviar a, sin enviar nada. Una vez que haya dado un vistazo a los cambios y vericado que est a enviando los correctos, puede volver a ejecutar la misma orden, sin la opci on -n. La orden hg email acepta la misma clase de sintaxis de revisiones como cualquier otra orden de Mercurial. Por ejemplo, enviar a todas las revisiones entre la 7 y la punta, inclusive.

hg email -n 7:tip Tambi en puede especicar un repositorio para comparar. Si indica un repositoro sin revisiones, la orden hg email enviar a todas las revisiones en el repositorio local que no est an presentes en el repositorio remoto. Si especica ltima con la opci revisiones adicionalmente o el nombre de una rama (la u on -b), respetar a las revisiones enviadas. 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 a tales valores de forma interactiva. (Si est a usando Linux o un sistema tipo Unix, til.) tendr a capacidades estiloreadline aumentadas cuando ingrese tales encabezados, lo cual es sumamente u Cuando env e una sola revisi on, la orden hg email de forma predeterminada usar a la primera l nea de descrip nico mensaje que se enviar ci on del conjunto de cambios como el tema del u a. Si env a varias revisiones, la orden hg email enviar a normalmente un mensaje por conjunto de cambios. Colocar a como prefacio un mensaje introductorio en el cual usted deber a describir el prop osito de la serie de cambios que est a enviando.

14.4.1.

Cambiar el comportamiento de las bombas de parches

Cada proyecto tiene sus propias convenciones para enviar cambios en un correo electr onico; la extensi on patchbomb rdenes: intenta acomodarse a diferentes variaciones gracias a las opciones de la l nea de o rdenes con la opci Puede escribir un tema para el mensaje introductorio en la l nea de o n -s. Toma un argumento: el tema del mensaje a usar. Para cambiar el correo electr onico del campo del cual se origina, use la opci on -f. Toma un argumento, el correo electr onico a usar. El comportamiento predeterminado es enviar diferencias unicadas (consulte la secci on 12.4 si desea una descripci on del formato), una por mensaje. Puede enviar un conjunto binario3 con la opci on -b. Las diferencias unicadas est an precedidas por un encabezado de metadatos. Puede omitirlo, y enviar diferencias sin adornos con la opci on --plain. Las diferencias usualmente se env an en l nea, como parte del cuerpo del mensaje con la descripci on del 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 an la primera parte MIME del cuerpo de un mensaje. Si preere enviar la descripci on y el diff en partes separadas del cuerpo, use la opci on -a.
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 on -m. La opci on recibe un argumento, el nombre del chero en el cual escribir. Si desea a nadir un resumen con formato-diffstat en cada parche, y uno como mensaje introductorio, use la opci on -d. La orden diffstat despliega una tabla que contiene el nombre de cada chero parchado, el n umero de l neas afectadas, y un historgrama mostrando cu anto ha sido modicado cada chero. Lo cual ofrece a los lectores una mirada cuantitativa de cuan complejo es el parche.

174

Ap endice A

Referencia de Ordenes
A.1. hg addAnade cheros en la pr oxima consignaci on

--include, tambi en -I --exclude, tambi en -X --dry-run, tambi en -n

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 on del formato unicado diff, ver la secci on 12.4. De forma predeterminada, esta orden no imprime las diferencias para los cheros binarios que Mercurial est e siguiendo. Para controlar este comportamiento, vea las opciones -a y --git.

A.2.1.

Options

opci on --nodates Omite la fecha y hora cuando se muestran los encabezados de las diferencias. --ignore-blank-lines, tambi en -B No imprime los cambios que solamente insertan o eliminan l neas en blanco. Una l nea que contiene espacios en blanco no se considera como una l nea en blanco. --include, tambi en -I Incluye cheros y directorios cuyos nombres coinciden con los patrones elegidos. --exclude, tambi en -X Excluye los cheros y directorios cuyos nombres coinciden con los patrones elegidos. --text, tambi en -a Si no especica esta opci on, hg diff no mostrar a las diferencias de los cheros que detecte como binarios. Al especicar -a se forza a hg diff a tratar los cheros como texto, y generar diferencias para todos.

175

til para los cherso que son texto en mayor medida pero que tienen caracteres NUL. Si lo usa Esta opci on es u en cheros que contienen muchos datos binarios, la salida ser a incomprensible. --ignore-space-change, tambi en -b nico cambio que en la l No imprime si el u nea es la cantidad de espacio en blanco. --git, tambi en -g Mostrar diferencias compatibles con git. XXX reference a format description. --show-function, tambi en -p Mostrar el nombre de la funci on que contiene el c odigo en una porci on del encabzado usando una heur stica simple. Esta funcionalidad se habilita de forma predeterminada, as que la opci on -p no tiene efectos a menos que cambie el valor de showfunc en la conguraci on, como en el ejemplo siguiente.
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 en -r

>> $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 as revisiones para comparar. La orden hg diff acepta hasta dos opciones -r para especicar las revisiones a comparar. 1. Despliega las diferencias entre la revisi on padre y del directorio de trabajo. 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 on de rango. Por ejemplo, las dos especicaciones de revisiones a continuaci on son equivalentes: 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 a un diff que transformar a los cheros desde los contenidos en la revisi on 10 a los contenidos de la revisi on 20, mientras que hg diff -r20:10 signica lo opuesto: el diff que transformar a los contenidos de los cheros de la revisi on 20 a los contenidos de la revisi on 10. No puede invertir el orden de esta forma si est a haciendo un diff frente al directorio de trabajo. --ignore-all-space, tambi en -w

A.3.

hg versionimprime la informaci on de versi on y derechos de reproducci on

Esta orden despliega la versi on de Mercurial que est a usando, y su nota de derechos de reproducci on. Hay cuatro clases de cadenas de versi on posibles: La cadena unknown. Esta versi on de Mercurial no fue construida en un repositorio de Mercurial, y no puede determinar su propia versi on. Una cadena num erica corta, tal como 1.1. Esta es una construcci on de una versi on de Mercurial que se identica con una etiqueta espec ca en el repositorio en el cual fue armada (Esto no signica necesariamente que est a ejecutando una versi on ocial; alguien pudo haber a nadido tal etiqueta a cualquier versi on del repositorio en el cual armaron Mercurial). Una cadena hexadecimal, tal como 875489e31abe. Esta es una construcci on de una revisi on dada de Mercurial. Una cadena hexadecimal seguida por una fecha, tal como 875489e31abe+20070205. Esta construcci on de la revisi on de Mercurial fue la construcci on de un repositorio que tuvo cambios locales que no han sido consignados.

A.3.1.

Consejos y trucos

Por qu e dieren los resultados de hg diff y hg status? Cuando ejecuta la orden hg status, ver a una lista de cheros para los cuales Mercurial almacenar a cambios la pr oxima vez que consigne. Si ejecuta la orden hg diff, ver a que imprime diferencias solamente para un subconjunto 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 as notable es que las diferencias tradicionales no pueden representar un cambio acerca de la ejecutabilidad de un chero, pero Mercurial s almacena esta informaci on. Si usa la opci on --git de hg diff, mostrar a diferencias compatibles con git que pueden desplegar esta informaci on adicional. La segunda raz on posible para que hg diff est e imprimiendo diferencias para un subconjunto de cheros de 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 un los resultados de la fusi on, su directorio de trabajo tiene dos padres (use hg parents para verlos). Mientras que hg status imprime modicaciones relativas a ambos padres despu es de una fusi on que no se ha consignado, hg diff opera a un relativo solamente al primer padre. Puede lograr que imprima las diferencias relativas al segundo padre especicando tal padre con la opci on -r. No hay forma de hacer que imprima las diferencias relativas a los dos padres. 177

Generar diferencias seguras en binarios Si usa la opci on -a para forzar que Mercurial imprima las diferencias de los cheros que so o bien casi completamente 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 on hg diffgit cuando genere el parche. La orden patch del sistema no puede tratar con parches binarios.

178

Ap endice B

Referencia de las Colas de Mercurial


B.1. rdenes MQ Referencia de o

rdenes que ofrece MQ, use la orden hg help mq. Si desea dar un vistazo a las o

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 ltimo parche de la lista es el que antig uedad, primero los m as antiguos y despu es los m as recientes, por lo tanto el u est a en el tope.

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 o el directorio con hg qinit -c o ejecut o hg init en el directorio despu es de correr hg qinit. 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 on -f para 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 as recientemente aplicado. Es equivalente a hg diff -r-2:-1.

B.1.5.

hg qfoldfusionar (integrar) varios parches en uno solo

ltimo parche aplicado, de tal forma que el u ltimo parche La orden hg qfold fusiona muchos parches en el u aplicado es la uni on de todos los cambios de los parches en cuesti on. Los parches a fusionar no deben haber sido aplicados; hg qfold saldr a indicando un error si alguno ha sido aplicado. El orden en el cual los parches se pliegan es signicativo; hg qfold a b signica aplique el parche m as 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 on -e para editar el mensaje de consignaci on para el conjunto de cambios/parches despu es de completarse el pliegue. Opciones: -e Edita el mensaje de consignaci on y la descripci on del parche del parche que se ha integrado. -l Usa los contenidos del chero dado como el nuevo mensaje de consignaci on y descripci on del parche para el parche a integrar. -m Usa el texto dado como el mensaje de consignaci on y descripci on del parche para el parche integrado.

B.1.6.

hg qheaderdesplegar el encabezado/descripci on de un parche

La orden hg qheader imprime el encabezado o descripci on de un parche. De forma predeterminada, imprime ltimo parche aplicado. Si se da un argumento, imprime el encabezado del parche referenciado. el encabezado del u

B.1.7.

hg qimportimportar el parche de un tercero en la cola

La orden hg qimport a nade una entrada de un parche externo al chero series y copia el parche en el directorio ltimo parche aplicado, pero no introduce el parche. .hg/patches. A nade la entrada inmediatamente despu es del u Si el directorio .hg/patches es un repositorio, hg qimport autom aticamente hace un hg add del parche 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 en crea un chero .hgignore que ignorar a el chero status. rdenes hg qimport y hg qnew hacen hg add Cuando el directorio .hg/patches es un repositorio, las o autom aticamente a los parches nuevos.

B.1.9.

hg qnewcrear un parche nuevo

La orden hg qnew crea un parche nuevo. Exige un argumento, el nombre que se usar a para tal parche. El parche ltimo parche aplicado, y se introduce reci en creado est a vac o inicialmente. Se a nade al chero series despu es del u en el tope de ese parche. Si hg qnew encuentra cheros modicados en el directorio de trabajo, rehusar a crear un parche nuevo a meos ltimo parche que se emplee -f la opci on (ver m as adelante). Este comportamiento le permite hacer hg qrefresh al u 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 on signicativa se a nade al parche recientemente creado, de tal forma que al nalizar la orden, el directorio de trabajo no lucir a modicado. -m Usa el texto dado como el mensaje de consignaci on. Este texto se almacenar a al principio del chero del parche, antes de los datos del parche.

B.1.10.

hg qnextimprimir el nombre del pr oximo parche

ltimo La orden hg qnext imprime el nombre del siguiente parche en el chero series a continuaci on del u parche aplicado. Este parche ser a el pr oximo parche a aplicar si se ejecutara la orden hg qpush. 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 sustra dos 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 ltimo parche aplicado. Si se da un n el nombre, sustraer a los parches hasta que el parche nombrado sea el u umero, hg qpop lo trata como un ndice dentro del chero series, contando desde cero (no cuenta las l neas vac as o aquellas nicamente comentarios). Sustrae los parches hasta que el parche identicado por el ltimo que sean u ndice sea el u 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. ltimos casos, use el nombre del parche tal como lo hizo cuando lo aplic En los dos u o. De forma predeterminada, la orden hg qpop no sustraer a parche alguno si el directorio de trabajo ha sido modicado. Puede modicar este comportamiento con la opci on -f, que revierte todas las modicaciones del directorio de trabajo. Opciones: -a Sustrae todos los parches aplicados. Restaura el repositorio al estado antes de haber aplicado parche alguno. -f Revertir forzadamente cualquier modicaci on del directorio de trabajo cuando se hace sustracciones. -n Sustraer un parche de la cola dado un nombre. La orden hg qpop elimina una l nea del nal del chero status por cada parche que se sustrae.

B.1.12.

hg qprevimprimir el nombre del parche anterior

ltimo parche aplicado. La orden hg qprev imprime el nombre del parche en el chero series que est a antes del u ltimo parche aplicado si ejecuta hg qpop. Este se volver a el u

B.1.13.

hg qpushintroducir parches a la pila

La orden hg qpush a nade parches a la pila. De forma predeterminada a nade solamente un parche. 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 on y zona horaria corresponden a la hora actual de la zona. Dado que tales datos se 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 a una identidad distinta a la del conjunto de cambios que sustrajo. El autor es el mismo que el predeterminado usado por la orden hg commit. El mensaje de consignaci on es cualquier texto del chero del parche que viene antes del primer encabezado del 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 on en el encabezado del 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 as para introducir. 181

-l A nade el nombre del parche al nal del mensaje de consignaci on -m Si un parche no se aplica limpiamente, usa la entrada para un parche en otra cola almacenada para computar los par ametros en una fusi on de tres, y aplica una fusi on de tres fuentes usando la maquinaria usual de Mercurial. Usa la resoluci on de la fusi on como el contenido del parche nuevo. -n Usa la cola mencionada si se est a fusionando en la introducci on. La orden hg qpush lee, pero no modica el chero series. A nade al nal del chero hg status una l nea por cada parche que se introduce.

B.1.14.

hg qrefreshactualiza el ultimo parche aplicado

ltimo parche aplicado. Modica el parche, elimina el u ltimo conjunto de La orden hg qrefresh actualiza el u cambios que represent o el parche, y crea un nuevo conjunto de cambios para representar el parche modicado. La orden hg qrefresh busca las siguientes modicaciones: Los cambios al mensaje de consignaci on, p.e. el texto antes del primer encabezado de diff en el chero del 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 nade al parche. Los cambios a los cheros a los que se les da seguimiento con hg add, hg copy, hg remove, o hg rename. Se a naden al parche los cheros a nadidos, copiados y renombrados, mientras que los cheros eliminados 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 o al parche. Opciones: -e Modicar la descripci on de la consignaci on y el parche con el editor de texto preferido. -m Modicar el mensaje de consignaci on y la descripci on del parche con el texto dado. -l Modicar el mensaje de consignaci on y la descripci on del parche con el texto del chero dado.

B.1.15.

hg qrenamerenombrar un parche

La orden hg qrename renombra un parche y cambia la entrada del parche en el chero series. ltimo parche aplicado. Con dos argumentos, renombra el Con un argumento sencillo, hg qrename renombra el u 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 ltimo, el u ltimo aplicado. de los parches sin las l neas en blanco o comentarios. Imprime primero el primero y de u 182

B.1.19.

hg qtopimprime el nombre del parche actual

ltimo parche aplicado. hg qtop imprime el nombre del u

B.1.20.

no se han aplicado hg qunappliedimprimir los parches que aun

La orden hg qunapplied imprime los nombres de los parches del chero series que todav a no han sido aplicados. Los imprime de acuerdo al orden en el cual ser an introducidos.

B.1.21.

hg stripremover una revisi on y sus descendientes

La orden hg strip remueve una revisi on, y todos sus descendientes del repositorio. Deshace los efectos de las revisiones removidas del repositorio, y actualiza el directorio de trabajo hasta el primer padre de la revisi on removida. 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 on. Opciones: -b Almacenar conjuntos de cambios no relacionados que se han mezclado con los conjuntos de cambios que est an 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 l nea. Se ignora el espacio en blanco al principio y al nal. Las l neas pueden contener comentario. Un comentario comienza con el caracter #, y va hasta el nal de la l nea. Se ignoran las l neas vac as y las que solamente contengan comentarios. En alg un momento podr a editar el chero series a mano, por tal motivo se admiten comentarios y l neas en blanco como se menciono anteriormente. Por ejemplo, puede poner en comentario un parche temporalmente y hg qpush omitir a tal parche cuando los aplique. Tambi en puede cambiar el orden en el cual se aplican los parches, reordenando las entradas en el chero series. Tambi en es posible colocar el chero series bajo control de revisiones; tambi en es favorable colocar todos los parches que reera bajo control de revisiones. Si crea un directorio de parches con la opci on -c de hg qinit, esto se har a autom aticamente.

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 nado para ser editado. No deber a colocar este chero bajo el control de revisiones o modicarlo de forma alguna. MQ lo usa estrictamente para administraci on interna.

183

Ap endice C

Instalar Mercurial desde las fuentes


C.1. En un sistema tipo Unix

Si usa un sistema tipo Unix que tiene una versi on sucientemente reciente de Python (2.3 o superior) disponible, es f acil instalar Mercurial desde las fuentes. 1. Descargue un paquete fuente reciente de http://www.selenic.com/mercurial/download. 2. Descompr malo:
1

gzip -dc mercurial-version.tar.gz | tar xf -

3. Vaya al directorio fuente y ejecute el gui on de instalaci on. Esto armar a Mercurial y lo instalar a en su directorio casa:
1 2

cd mercurial-version python setup.py install --force --home=$HOME

Cuando termine la instalaci on, Mercurial estar a en el subdirectorio bin de su directorio casa. No olvide asegurarse de rdenes. que este directorio est e presente en el camino de b usqueda de su int erprete de o Probablemente necesitar a establecer la variable de ambiente PYTHONPATH de tal forma que los ejecutables de Mercurial puedan encontrar el resto de los paquetes de Mercurial. Por ejemplo, en mi port atil, la establec a a /home/bos/lib/python. La ruta exacta que usted use depender a de como ha sido constru do Python en su sistema, pero deber a ser f acil deducirla. Si no est a seguro, mire lo que haya mostrado el script en el paso anterior, y vea d onde se instalaron los contenidos del directorio mercurial se instalaron.

C.2.

En Windows

Armar e instalar Mercurial en Windows requiere una variedad de herramientas, cierta suciencia t ecnica y paciencia 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 a decidido a construir Mercurial desde las fuentes en Windows, siga el camino dif cil indicado en el wiki de Mercurial en http://www.selenic.com/mercurial/wiki/index.cgi/WindowsInstall, y espere que el proceso sea realmente un trabajo duro.

184

Ap endice D

Licencia de Publicaci on Abierta


Versi on 1.0, 8 Junio de 1999

D.1.

Requerimientos en versiones modicadas y no modicadas

Los trabajos bajo Publicaci on Abierta pueden reproducirse y distribuirse enteros o en porciones, en cualquier medio f sico o electr onico, siempre y cuando se respeten los t erminos de esta licencia, y se incorpore esta licencia o su referencia (con cualquiera de las opciones elegidas por el autor y el editor) en la reproducci on. A continuaci on mostramos la forma correcta de incorporar por referencia: Copyright (c) a no por nombre del autor o designado. Este material puede distribuirse solamente bajo los ltima t erminos y condiciones especicados por la Licencia de Publicaci on Abierta, vx.y o posterior (la u versi on disponible est a en http://www.opencontent.org/openpub/). La referencia debe estar seguida inmediatamente por cualquier opci on elegida por el(os) autor(es) y/o editor(es) del documento (consulte la secci on D.6). Se permite la redistribuci on comercial de los materiales sujetos a la Publicaci on Abierta. Cualquier publicaci on en forma est andar de libro (papel) requerir a citar al editor y autor original. Los nombres del editor y el autor aparecer an en todas las supercies externas del libro. En todas las supercies externas el nombre del editor deber a aparecer en tama no de la misma medida que el t tulo del trabajo y ser a citado como poseedor con respecto al t tulo.

D.2.

Derechos de reproducci on

El derecho de reproducci on de cada Publicaci on Abierta pertenece al(os) autor(es) o designados.

D.3.

Alcance de la licencia

Los t erminos de licencia dsecritos aplican a todos los trabajos bajo licencia de publicaci on abierta a menos que se indique de otra forma en este documento. La simple agregaci on de trabajos de Publicaci on Abierta o una porci on de trabajos de Publicaci on Abierta con otros trabajos o programas en el mismo medio no causar an que esta licencia se aplique a los otros trabajos. Los agregados deber an contener una nota que especique la inclusi on de matrial de Publicaci on Abierta y una nota de derechos de reproducci on acorde. Separabilidad. Si cualquier porci on de esta licencia no es aplicable en alguna jurisdicci on, las porciones restantes se mantienen. 185

Sin garant a. Los trabajos de Publicaci on Abierta se licencian y ofrecen como est an sin garant a de ninguna clase, expresa o impl cita, incluyendo, pero no limitados a las garant as de mercabilidad y adaptabilidad para un prop osito particular o garant a de no infracci on.

D.4.

Requerimientos sobre trabajos modicados

Todas las versiones modicadas de documentos cubiertos por esta licencia, incluyendo traducciones, antolog as, compilaciones y documentos parciales, deben seguir estos requerimientos: 1. La versi on modicada debe estar etiquetada como tal. 2. La persona que hace la modicaci on debe estar identicada y la modicaci on con fecha. 3. El dar cr edito al autor original y al editor si se requiere de acuerdo a las pr acticas acad emicas de citas. 4. Debe identicarse el lugar del documento original sin modicaci on. 5. No puede usarse el(os) nombre(s) del autor (de los autores) para implicar relaci on alguna con el documento resultante sin el permiso expl cito del autor (o de los autores).

D.5.

Recomendaciones de buenas pr acticas

Adicional a los requerimientos de esta licencia, se solicita a los redistribuidores y se recomienda en gran medida que: 1. Si est a distribuyendo trabajaos de Publicaci on Abierta en copia dura o CD-ROM, env e una noticaci on por correo a los autores acerca de su intenci on de redistribuir por lo menos con treinta d as antes de que su manuscrito o el medio se congelen, para permitir a los autores tiempo para proveer documentos actualizados. Esta noticaci on deber a describir las modicaciones, en caso de que haya, al documento. 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 on en copia dura o CD-ROM de un trabajo licenciado con Publicaci on Abierta a el(os) autor(es).

D.6.

Opciones de licencia

El(os) autor(es) y/o editor de un documento licenciado con Publicaci on Abierta pueden elegir ciertas opciones a nadiendo informaci on a la referencia o a la copia de la licencia. Estas opciones se consideran parte de la instancia de la licencia y deben incluirse con la licencia (o su incorporaci on con referencia) en trabajos derivados. A Prohibir la distribuci on de versiones substancialmente modicadas sin el permiso expl cito del(os) autor(es). Se denen modicaciones substanciales como cambios en el contenido sem antico del documento, y se excluyen simples cambios en el formato o correcciones tipogr acas. Para lograr esto, a nada la frase Se prohibe la distribuci on de versiones substancialmente modicadas de este documento sin el permiso expl cito del due no de los derechos de reproducci on. a la referencia de la licencia o a la copia.

186

B Est a prohibido prohibir cualquier publicaci on de este trabajo o derivados como un todo o una parte en libros est andar (de papel) con prop ositos comerciales a menos que se obtenga un permiso previo del due no de los derechos de reproducci on. Para lograrlo, a nada la frase La distribuci on del trabajo o derivados en cualquier libro est andar (papel) se prohibe a menos que se obtenga un permiso previo del due no de los derechos de reproducci on. a la referencia de la licencia o la copia.

187

Bibliograf a
[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 etico


.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 on, 66 PATH, variable de entorno, 68 PYTHONPATH, variable de entorno, 68, 71, 115, 183 acl, extensi on, 117, 118, 168 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 on --dry-run, 174 opci on --exclude, 174 opci on --include, 174 opci on -I, 174 opci on -n, 174 opci on -X, 174 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 on --merge, 96, 98, 101 opci on -m, 96 basename, ltro de plantilla, 134 bash, comando de sistema, 155 bisect, comando, 102108 bisect, extensi on, 2, 142 branches, comando, 86 branches, palabra clave de plantilla, 132 branch, comando, 87, 88 bugzilla, extensi on, 119122, 168 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 on -r, 84 commit, comando, 1921, 30, 41, 49, 52, 86, 112, 116, 117, 153, 155, 158, 178, 180 opci on --addremove, 158 opci on -A, 52 opci on -l, 117 opci on -u, 20 commit, gancho, 109, 112, 113, 126, 127, 129 config, comando, 110 convert, comando (extensi on conver), 10 convert, extensi on, 10 conver, extensi on comando convert, 10 copy, comando, 44, 5256, 95, 181 opci on --after, 55 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 on -p, 155 diffstat, comando de sistema, 155, 156, 173 diff, comando, 19, 21, 144, 148, 165, 168, 170, 171, 174178 opci on --exclude, 174 opci on --git, 174176 opci on --ignore-all-space, 176 opci on --ignore-blank-lines, 174 opci on --ignore-space-change, 175 opci on --include, 174 opci on --nodates, 174 opci on --rev, 175 opci on --show-function, 175 opci on --text, 174 opci on -a, 174, 177 opci on -B, 174 opci on -b, 175 opci on -C, 171 opci on -c, 171 opci on -g, 175 opci on -I, 174 opci on -N, 148 opci on -p, 175 opci on -r, 148, 175, 176 opci on -w, 176 opci on -X, 174 diff, comando de sistema, 140, 142, 148, 171 domain, ltro de plantilla, 134 email, comando (extensi on patchbomb), 173 email, comando (extensi on patchbomb) opci on --plain, 173 opci on -a, 173 opci on -b, 173 opci on -d, 173 opci on -f, 173 opci on -m, 173 opci on -n, 173 opci on -s, 173 email, ltro de plantilla, 134 escape, ltro de plantilla, 134 export, comando, 101 extdiff, comando (extensi on extdiff), 167, 171, 172 extdiff, comando (extensi on extdiff) opci on -o, 171 opci on -p, 171 extdiff, extensi on, 165167, 170172 comando extdiff, 167, 171, 172 extdiff, extensi on comando extdiff opci on-o, 171

opci on-p, 171 fetch, comando, 35 fetch, comando (extensi on fetch), 168 fetch, extensi on, 35, 168 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 on --files, 159 opci on --hunks, 159 opci on -i, 158 opci on -x, 158 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 on, 167 hgmerge, comando de sistema, 31, 33, 129 hgrc, chero secci on acl.allow, 118 secci on acl.deny, 118 secci on acl, 118 entrada bundle, 118 entrada pull, 118 entrada push, 118 entrada serve, 118 entrada sources, 118 secci on bugzilla, 119, 121 entrada db, 120 entrada host, 119 entrada notify, 120 entrada password, 120 entrada usermap, 120 entrada user, 120 entrada version, 119 secci on diff entrada showfunc, 175 secci on extdiff, 172 secci on extensions, 35, 165, 171 secci on hooks, 112 secci on notify, 122

190

entrada config, 122 entrada maxdiff, 123 entrada sources, 123 entrada strip, 122 entrada template, 123 entrada test, 122, 124 secci on ui entrada username, 20 entrada verbose, 113 secci on usermap, 120, 122 secci on web, 73, 74, 121, 123 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 on, 69, 73, 74, 90, 110112, 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 on, 168170 comando inserve, 170 inserve, comando (extensi on inotify), 170 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 on --patch, 17 opci on --rev, 16, 18 opci on --template, 132, 135 opci on -p, 17 opci on -r, 16, 18

lsdiff comando de sistema, 158 lsdiff, comando de sistema, 156 mercurial.localrepo, m odulo clase localrepository, 115, 124 mercurial.node, m odulo funci on bin, 124 mercurial.ui, m odulo 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 on, 170, 172 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 on comando qdel opci on-f, 178 comando qfold opci on-e, 179 opci on-l, 179 opci on-m, 179 comando qinit opci on-c, 154, 155, 178, 179, 182 comando qnew opci on-f, 146, 179 opci on-m, 179 comando qpop opci on-a, 146, 151, 152, 155, 180

191

opci on-f, 146, 180 opci on-n, 152, 180 comando qpush opci on-a, 146, 151, 152, 155, 170, 180 opci on-l, 181 opci on-m, 152, 181 opci on-n, 181 comando qrefresh opci on-e, 181 opci on-l, 181 opci on-m, 181 comando qsave opci on-c, 152 opci on-e, 152 node, palabra clave de plantilla, 133 ltro short, 135 notify, extensi on, 122124, 168 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 on, 165, 172, 173 comando email, 173 patchbomb, extensi on comando email opci on--plain, 173 opci on-a, 173 opci on-b, 173 opci on-d, 173 opci on-f, 173 opci on-m, 173 opci on-n, 173 opci on-s, 173 patchutils, paquete, 155, 165 patch comando de sistema, 149 patch, comando opci on --reverse, 101 opci on -p, 148 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 on -u, 23, 24 push, comando, 25, 80, 125, 126, 128 puttygen, comando de sistema, 67 putty, comando de sistema, 67 qapplied, comando (extensi on mq), 145, 146, 148, 155, 178 qcommit, comando (extensi on mq), 155, 178 qdelete, comando (extensi on mq), 178 qdel, comando (extensi on mq) opci on -f, 178 qdiff, comando (extensi on mq), 178 qfold, comando, 178 qfold, comando (extensi on mq), 158, 178 qfold, comando (extensi on mq) opci on -e, 179 opci on -l, 179 opci on -m, 179 qguard, comando, 162 qguard, comando (extensi on mq), 161, 162 qheader, comando (extensi on mq), 179 qimport, comando (extensi on mq), 149, 179 qinit, comando, 155, 178 qinit, comando (extensi on mq), 143, 154, 178, 179, 182 qinit, comando (extensi on mq) opci on -c, 154, 155, 178, 179, 182 qnew, comando, 146 qnew, comando (extensi on mq), 143, 145, 146, 149, 179 qnew, comando (extensi on mq) opci on -f, 146, 179 opci on -m, 179 qnext, comando (extensi on mq), 179 qpop, comando, 146, 151, 152, 155 qpop, comando (extensi on mq), 146, 147, 151, 153, 180 qpop, comando (extensi on mq) opci on -a, 146, 151, 152, 155, 180 opci on -f, 146, 180 opci on -n, 152, 180 qprev, comando (extensi on mq), 180 qpush, comando, 151, 152, 155 qpush, comando (extensi on mq), 146, 147, 150153, 158, 162, 170, 179182 qpush, comando (extensi on mq) opci on -a, 146, 151, 152, 155, 170, 180 opci on -l, 181 opci on -m, 152, 181 opci on -n, 181

192

qrefresh, comando (extensi on mq), 144, 145, 147, 149, 151153, 156, 158, 179, 181 qrefresh, comando (extensi on mq) opci on -e, 181 opci on -l, 181 opci on -m, 181 qrename, comando (extensi on mq), 181 qrestore, comando (extensi on mq), 181 qsave, comando, 152 qsave, comando (extensi on mq), 152, 181 qsave, comando (extensi on mq) opci on -c, 152 opci on -e, 152 qselect, comando (extensi on mq), 162 qseries, comando (extensi on mq), 145, 146, 148, 153, 181 qtop, comando (extensi on mq), 155, 156, 182 qunapplied, comando (extensi on mq), 182 remove, comando, 44, 51, 52, 56, 76, 94, 159, 181 opci on --after, 52 rename, comando, 44, 55, 56, 80, 95, 181 opci on --after, 56 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 on -p, 65 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 on -C, 69 ssh, comando de sistema, 42, 60, 6669 status, comando, 19, 21, 49, 5153, 55, 76, 87, 91, 95, 101, 168, 169, 176, 181 opci on -C, 53, 55 status, chero, 144, 152, 155, 179, 180, 182 strip, comando, 152, 182 opci on -b, 182 opci on -f, 182 opci on -n, 182 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 on -f, 83 opci on -l, 84 tag, gancho, 109, 128, 129 tar, comando de sistema, 73 tip, comando, 21, 23, 87, 131, 156 opci on -p, 156 transplant, extensi on, 172 unbundle, comando, 125, 128 update, comando, 23, 24, 29, 35, 40, 61, 80, 8890, 101, 152, 155 opci on -C, 88, 152 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 on 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 on --debug, 68, 118 opci on --exclude, 79 opci on --include, 79 opci on --quiet, 18 opci on --verbose, 13, 17, 18 opci on -I, 79 opci on -q, 18, 77 opci on -v, 13, 17, 18, 65, 77, 113 opci on -X, 79 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