hgbook
annotate es/tour-merge.tex @ 890:2887b61fa4fe
Change fields to fieldsets in the Comment admin model. The 'date'
field isn't working properly for an unknown reason, so it has been
removed from the interface temporarily.
field isn't working properly for an unknown reason, so it has been
removed from the interface temporarily.
author | dukebody <dukebody@gmail.com> |
---|---|
date | Sun Oct 11 21:12:46 2009 +0200 (2009-10-11) |
parents | 9da096de3c52 |
children |
rev | line source |
---|---|
jerojasro@381 | 1 \chapter{Una gira de Mercurial: fusionar trabajo} |
jerojasro@336 | 2 \label{chap:tour-merge} |
jerojasro@336 | 3 |
jerojasro@383 | 4 Hasta ahora hemos cubierto cómo clonar un repositorio, hacer cambios, |
jerojasro@383 | 5 y jalar o empujar dichos cambios de un repositorio a otro. Nuestro |
jerojasro@383 | 6 siguiente paso es \emph{fusionar} cambios de repositorios separados. |
jerojasro@383 | 7 |
jerojasro@383 | 8 % TODO cambié streams por líneas. check please |
jerojasro@383 | 9 \section{Fusionar líneas de trabajo} |
jerojasro@383 | 10 |
jerojasro@383 | 11 Fusionar es una parte fundamental de trabajar con una herramienta |
jerojasro@383 | 12 de control distribuido de versiones. |
jerojasro@336 | 13 \begin{itemize} |
jerojasro@383 | 14 \item Alicia y Roberto tienen cada uno una copia personal del |
jerojasro@383 | 15 repositorio de un proyecto en el que están trabajando. Alicia |
jerojasro@383 | 16 arregla un fallo en su repositorio; Roberto añade una nueva |
jerojasro@383 | 17 característica en el suyo. Ambos desean que el repositorio |
jerojasro@383 | 18 compartido contenga el arreglo del fallo y la nueva |
jerojasro@383 | 19 característica. |
jerojasro@383 | 20 \item Frecuentemente trabajo en varias tareas diferentes en un mismo |
jerojasro@383 | 21 proyecto al mismo tiempo, cada una aislada convenientemente de las |
jerojasro@383 | 22 otras en su propio repositorio. Trabajar de esta manera significa |
jerojasro@383 | 23 que a menudo debo fusionar una parte de mi propio trabajo con |
jerojasro@383 | 24 otra. |
jerojasro@336 | 25 \end{itemize} |
jerojasro@336 | 26 |
jerojasro@383 | 27 Como fusionar es una operación tan necesaria y común, Mercurial la |
jerojasro@383 | 28 facilita. Revisemos el proceso. Empezaremos clonando (otro) |
jerojasro@383 | 29 % TODO poner interrogante de apertura |
jerojasro@383 | 30 repositorio (ve lo seguido que aparecen?) y haciendo un cambio en él. |
jerojasro@336 | 31 \interaction{tour.merge.clone} |
jerojasro@383 | 32 Ahora deberíamos tener dos copias de \filename{hello.c} con contenidos |
jerojasro@383 | 33 diferentes. El historial de los dos repositorios diverge ahora, como |
jerojasro@383 | 34 se ilustra en la figura~\ref{fig:tour-merge:sep-repos}. |
jerojasro@336 | 35 \interaction{tour.merge.cat} |
jerojasro@336 | 36 |
jerojasro@336 | 37 \begin{figure}[ht] |
jerojasro@336 | 38 \centering |
jerojasro@336 | 39 \grafix{tour-merge-sep-repos} |
jerojasro@383 | 40 \caption{Historial reciente divergente de los repositorios |
jerojasro@383 | 41 \dirname{my-hello} y \dirname{my-new-hello}} |
jerojasro@336 | 42 \label{fig:tour-merge:sep-repos} |
jerojasro@336 | 43 \end{figure} |
jerojasro@336 | 44 |
jerojasro@383 | 45 Ya sabemos que jalar los cambios desde nuestro repositorio |
jerojasro@383 | 46 \dirname{my-hello} no tendrá efecto en el directorio de trabajo. |
jerojasro@336 | 47 \interaction{tour.merge.pull} |
jerojasro@384 | 48 Sin embargo, el comando \hgcmd{pull} dice algo acerca de |
jerojasro@384 | 49 ``frentes''\ndt{El autor se refiere a \emph{heads} aquí.}. |
jerojasro@384 | 50 |
jerojasro@384 | 51 \subsection{Conjuntos de cambios de frentes} |
jerojasro@384 | 52 |
jerojasro@384 | 53 Un frente es un cambio que no tiene descendientes, o hijos, como |
jerojasro@384 | 54 también se les conoce. La revisión de punta es, por tanto, un frente, |
jerojasro@384 | 55 porque la revisión más reciente en un repositorio no tiene ningún |
jerojasro@384 | 56 % TODO cambio en la redacción de la frase, pero espero que conserve el |
jerojasro@384 | 57 % sentido. Querido human@, apruebe o corrija :D |
jerojasro@384 | 58 hijo. Sin embargo, un repositorio puede contener más de un frente. |
jerojasro@336 | 59 |
jerojasro@336 | 60 \begin{figure}[ht] |
jerojasro@336 | 61 \centering |
jerojasro@336 | 62 \grafix{tour-merge-pull} |
jerojasro@384 | 63 \caption{Contenidos del repositorio después de jalar |
jerojasro@384 | 64 \dirname{my-hello} a \dirname{my-new-hello}} |
jerojasro@336 | 65 \label{fig:tour-merge:pull} |
jerojasro@336 | 66 \end{figure} |
jerojasro@336 | 67 |
jerojasro@384 | 68 En la figura~\ref{fig:tour-merge:pull} usted puede ver el efecto que |
jerojasro@384 | 69 tiene jalar los cambios de \dirname{my-hello} a \dirname{my-new-hello}. |
jerojasro@384 | 70 El historial que ya existía en \dirname{my-new-hello} se mantiene |
jerojasro@384 | 71 intacto, pero fue añadida una nueva revisión. Refiriéndonos a la |
jerojasro@384 | 72 figura~\ref{fig:tour-merge:sep-repos}, podemos ver que el \emph{ID del |
jerojasro@384 | 73 conjunto de cambios} se mantiene igual en el nuevo repositorio, pero |
jerojasro@384 | 74 el \emph{número de revisión} ha cambiado. (Incidentalmente, éste es un |
jerojasro@384 | 75 buen ejemplo de porqué no es seguro usar números de revisión cuando se |
jerojasro@384 | 76 habla de conjuntos de cambios). Podemos ver los frentes en un |
jerojasro@384 | 77 repositorio usando el comando \hgcmd{heads}\ndt{Frentes.}. |
jerojasro@336 | 78 \interaction{tour.merge.heads} |
jerojasro@336 | 79 |
jerojasro@385 | 80 \subsection{Hacer la fusión} |
jerojasro@385 | 81 |
jerojasro@385 | 82 % TODO poner interrogante de apertura |
jerojasro@385 | 83 Qué pasa si tratamos de usar el comando usual, \hgcmd{update}, para |
jerojasro@385 | 84 actualizar el nuevo frente? |
jerojasro@336 | 85 \interaction{tour.merge.update} |
jerojasro@385 | 86 Mercurial nos indica que el comando \hgcmd{update} no hará la fusión; |
jerojasro@385 | 87 no actualizará el directorio de trabajo cuando considera que lo que |
jerojasro@385 | 88 deseamos hacer es una fusión, a menos que lo obliguemos a hacerlo. |
jerojasro@385 | 89 En vez de \hgcmd{update}, usamos el comando \hgcmd{merge} para hacer |
jerojasro@385 | 90 la fusión entre los dos frentes. |
jerojasro@336 | 91 \interaction{tour.merge.merge} |
jerojasro@336 | 92 |
jerojasro@336 | 93 \begin{figure}[ht] |
jerojasro@336 | 94 \centering |
jerojasro@336 | 95 \grafix{tour-merge-merge} |
jerojasro@385 | 96 \caption{Directorio de trabajo y repositorio durante la fusión, y |
jerojasro@385 | 97 consignación consecuente} |
jerojasro@336 | 98 \label{fig:tour-merge:merge} |
jerojasro@336 | 99 \end{figure} |
jerojasro@336 | 100 |
jerojasro@385 | 101 Esto actualiza el directorio de trabajo, de tal forma que contenga los |
jerojasro@385 | 102 cambios de \emph{ambos} frentes, lo que se ve reflejado tanto en la |
jerojasro@385 | 103 salida de \hgcmd{parents} como en los contenidos de \filename{hello.c}. |
jerojasro@336 | 104 \interaction{tour.merge.parents} |
jerojasro@336 | 105 |
jerojasro@385 | 106 \subsection{Consignar los resultados de la fusión} |
jerojasro@336 | 107 |
jerojasro@390 | 108 Siempre que hacemos una fusión, \hgcmd{parents} mostrará dos padres |
jerojasro@390 | 109 hasta que consignemos (\hgcmd{commit}) los resultados de la fusión. |
jerojasro@336 | 110 \interaction{tour.merge.commit} |
jerojasro@390 | 111 Ahora tenemos una nueva revisión de punta; note que tiene \emph{los |
jerojasro@390 | 112 dos} frentes anteriores como sus padres. Estos son las mismas |
jerojasro@390 | 113 revisiones que mostró previamente el comando \hgcmd{parents}. |
jerojasro@336 | 114 \interaction{tour.merge.tip} |
jerojasro@390 | 115 En la figura~\ref{fig:tour-merge:merge} usted puede apreciar una |
jerojasro@390 | 116 representación de lo que pasa en el directorio de trabajo durante la |
jerojasro@390 | 117 fusión cuando se hace la consignación. Durante la fusión, el |
jerojasro@390 | 118 directorio de trabajo tiene dos conjuntos de cambios como sus padres, |
jerojasro@390 | 119 y éstos se vuelven los padres del nuevo conjunto de cambios. |
jerojasro@390 | 120 |
jerojasro@390 | 121 \section{Fusionar cambios con conflictos} |
jerojasro@390 | 122 |
jerojasro@390 | 123 La mayoría de las fusiones son algo simple, pero a veces usted se |
jerojasro@390 | 124 encontrará fusionando cambios donde más de uno de ellos afecta las |
jerojasro@390 | 125 mismas secciones de los mismos ficheros. A menos que ambas |
jerojasro@390 | 126 modificaciones sean idénticas, el resultado es un \emph{conflicto}, en |
jerojasro@390 | 127 donde usted debe decidir cómo reconciliar ambos cambios y producir un |
jerojasro@390 | 128 resultado coherente. |
jerojasro@336 | 129 |
jerojasro@336 | 130 \begin{figure}[ht] |
jerojasro@336 | 131 \centering |
jerojasro@336 | 132 \grafix{tour-merge-conflict} |
jerojasro@390 | 133 \caption{Cambios con conflictos a un documento} |
jerojasro@336 | 134 \label{fig:tour-merge:conflict} |
jerojasro@336 | 135 \end{figure} |
jerojasro@336 | 136 |
jerojasro@390 | 137 La figura~\ref{fig:tour-merge:conflict} ilustra un ejemplo con dos |
jerojasro@390 | 138 cambios generando conflictos en un documento. Empezamos con una sola |
jerojasro@517 | 139 versión del fichero; luego hicimos algunos cambios; mientras tanto, |
jerojasro@390 | 140 alguien más hizo cambios diferentes en el mismo texto. Lo que debemos |
jerojasro@390 | 141 hacer para resolver el conflicto causado por ambos cambios es decidir |
jerojasro@390 | 142 cómo debe quedar finalmente el fichero. |
jerojasro@390 | 143 |
jerojasro@390 | 144 Mercurial no tiene ninguna utilidad integrada para manejar conflictos. |
jerojasro@390 | 145 En vez de eso, ejecuta un programa externo llamado \command{hgmerge}. |
jerojasro@390 | 146 Es un guión de línea de comandos que es instalado junto con Mercurial; |
jerojasro@390 | 147 usted puede modificarlo para que se comporte como usted lo desee. Por |
jerojasro@390 | 148 defecto, lo que hace es tratar de encontrar una de varias herramientas |
jerojasro@390 | 149 para fusionar que es probable que estén instaladas en su sistema. |
jerojasro@390 | 150 Primero se intenta con unas herramientas para fusionar cambios |
jerojasro@390 | 151 automáticamente; si esto no tiene éxito (porque la fusión demanda |
jerojasro@390 | 152 una guía humana) o dichas herramientas no están presentes, el guión |
jerojasro@390 | 153 intenta con herramientas gráficas para fusionar. |
jerojasro@390 | 154 |
jerojasro@390 | 155 También es posible hacer que Mercurial ejecute otro programa o guión |
jerojasro@390 | 156 en vez de \command{hgmerge}, definiendo la variable de entorno |
jerojasro@390 | 157 \envar{HGMERGE} con el nombre del programa de su preferencia. |
jerojasro@390 | 158 |
jerojasro@390 | 159 \subsection{Usar una herramienta gráfica para fusión} |
jerojasro@390 | 160 |
jerojasro@390 | 161 Mi herramienta favorita para hacer fusiones es \command{kdiff3}, y la |
jerojasro@390 | 162 usaré para describir las características comunes de las herramientas |
jerojasro@390 | 163 gráficas para hacer fusiones. Puede ver una captura de pantalla de |
jerojasro@390 | 164 \command{kdiff3} ejecutándose, en la |
jerojasro@390 | 165 figura~\ref{fig:tour-merge:kdiff3}. El tipo de fusión que la |
jerojasro@390 | 166 herramienta hace se conoce como \emph{fusión de tres vías}, porque hay |
jerojasro@516 | 167 tres versiones diferentes del fichero en que estamos interesados. |
jerojasro@390 | 168 Debido a esto la herramienta divide la parte superior de la ventana en |
jerojasro@390 | 169 tres paneles. |
jerojasro@336 | 170 \begin{itemize} |
jerojasro@390 | 171 \item A la izquierda está la revisión \emph{base} del fichero, p.ej.~la |
jerojasro@390 | 172 versión más reciente de la que descienden las dos versiones que |
jerojasro@390 | 173 estamos tratando de fusionar. |
jerojasro@390 | 174 \item En la mitad está ``nuestra'' versión del fichero, con las |
jerojasro@390 | 175 modificaciones que hemos hecho. |
jerojasro@390 | 176 \item A la derecha está la versión del fichero de ``ellos'', la que |
jerojasro@390 | 177 forma parte del conjunto de cambios que estamos tratando de |
jerojasro@390 | 178 fusionar. |
jerojasro@336 | 179 \end{itemize} |
jerojasro@390 | 180 En el panel inferior se encuentra el \emph{resultado} actual de la |
jerojasro@390 | 181 fusión. Nuestra tarea es reemplazar todo el texto rojo, que muestra |
jerojasro@390 | 182 los conflictos sin resolver, con una fusión adecuada de ``nuestra'' |
jerojasro@390 | 183 versión del fichero y la de ``ellos''. |
jerojasro@390 | 184 |
jerojasro@390 | 185 Los cuatro paneles están \emph{enlazados}; si avanzamos vertical o |
jerojasro@390 | 186 horizontalmente en cualquiera de ellos, los otros son actualizados |
jerojasro@390 | 187 para mostrar las secciones correspondientes del fichero que tengan |
jerojasro@390 | 188 asociado. |
jerojasro@390 | 189 |
jerojasro@390 | 190 \begin{figure}[ht] |
jerojasro@390 | 191 \centering |
jerojasro@390 | 192 \grafix[width=\textwidth]{kdiff3} |
jerojasro@390 | 193 \caption{Usando \command{kdiff3} para fusionar versiones de un |
jerojasro@390 | 194 fichero} |
jerojasro@336 | 195 \label{fig:tour-merge:kdiff3} |
jerojasro@336 | 196 \end{figure} |
jerojasro@336 | 197 |
jerojasro@390 | 198 En cada conflicto del fichero podemos escoger resolverlo usando |
jerojasro@390 | 199 cualquier combinación del texto de la revisión base, la nuestra, o la |
jerojasro@390 | 200 de ellos. También podemos editar manualmente el fichero en que queda |
jerojasro@390 | 201 la fusión, si es necesario hacer cambios adicionales. |
jerojasro@390 | 202 |
jerojasro@390 | 203 Hay \emph{muchas} herramientas para fusionar ficheros disponibles. Se |
jerojasro@390 | 204 diferencian en las plataformas para las que están disponibles, y en |
jerojasro@390 | 205 sus fortalezas y debilidades particulares. La mayoría están afinadas |
jerojasro@390 | 206 para fusionar texto plano, mientras que otras están pensadas para |
jerojasro@516 | 207 formatos de ficheros especializados (generalmente XML). |
jerojasro@336 | 208 |
jerojasro@391 | 209 % TODO traduje "worked" como "real" |
jerojasro@391 | 210 \subsection{Un ejemplo real} |
jerojasro@391 | 211 |
jerojasro@391 | 212 En este ejemplo, reproduciremos el historial de modificaciones al |
jerojasro@391 | 213 fichero de la figura~\ref{fig:tour-merge:conflict} mostrada |
jerojasro@391 | 214 anteriormente. Empecemos creando un repositorio con la versión base |
jerojasro@391 | 215 de nuestro documento. |
jerojasro@336 | 216 \interaction{tour-merge-conflict.wife} |
jerojasro@391 | 217 Clonaremos el repositorio y haremos un cambio al fichero. |
jerojasro@336 | 218 \interaction{tour-merge-conflict.cousin} |
jerojasro@391 | 219 Y haremos otro clon, para simular a alguien más haciendo un cambio al |
jerojasro@391 | 220 mismo fichero. (Esto introduce la idea de que no es tan inusual hacer |
jerojasro@391 | 221 fusiones consigo mismo, cuando usted aísla tareas en repositorios |
jerojasro@391 | 222 separados, y de hecho encuentra conflictos al hacerlo.) |
jerojasro@336 | 223 \interaction{tour-merge-conflict.son} |
jerojasro@391 | 224 Ahora que tenemos dos versiones diferentes de nuestro fichero, |
jerojasro@391 | 225 crearemos un entorno adecuado para hacer la fusión. |
jerojasro@336 | 226 \interaction{tour-merge-conflict.pull} |
jerojasro@336 | 227 |
jerojasro@391 | 228 En este ejemplo, no usaré el comando normal de Mercurial para hacer la |
jerojasro@391 | 229 fusión (\command{hgmerge}), porque lanzaría mi linda herramienta |
jerojasro@391 | 230 automatizada para correr ejemplos dentro de una interfaz gráfica de |
jerojasro@391 | 231 usuario. En vez de eso, definiré la variable de entorno |
jerojasro@391 | 232 \envar{HGMERGE} para indicarle a Mercurial que use el comando |
jerojasro@391 | 233 \command{merge}. Este comando forma parte de la instalación base de |
jerojasro@391 | 234 muchos sistemas Unix y similares. Si usted está ejecutando este |
jerojasro@391 | 235 ejemplo en su computador, no se moleste en definir \envar{HGMERGE}. |
jerojasro@336 | 236 \interaction{tour-merge-conflict.merge} |
jerojasro@391 | 237 Debido a que \command{merge} no puede resolver los conflictos que |
jerojasro@391 | 238 aparecen, él deja \emph{marcadores de fusión} en el fichero con |
jerojasro@391 | 239 conflictos, indicando si provienen de nuestra versión o de la de |
jerojasro@391 | 240 ellos. |
jerojasro@391 | 241 |
jerojasro@391 | 242 Mercurial puede saber ---por el código de salida del comando |
jerojasro@391 | 243 \command{merge}--- que no fue posible hacer la fusión exitosamente, |
jerojasro@391 | 244 así que nos indica qué comandos debemos ejecutar si queremos rehacer |
jerojasro@391 | 245 la fusión. Esto puede ser útil si, por ejemplo, estamos ejecutando una |
jerojasro@391 | 246 herramienta gráfica de fusión y salimos de ella porque nos confundimos |
jerojasro@391 | 247 o cometimos un error. |
jerojasro@391 | 248 |
jerojasro@391 | 249 Si la fusión ---automática o manual--- falla, no hay nada que nos |
jerojasro@391 | 250 impida ``arreglar'' los ficheros afectados por nosotros mismos, y |
jerojasro@391 | 251 consignar los resultados de nuestra fusión: |
jerojasro@391 | 252 % TODO este mercurial no tiene el comando resolve. Revisar si sigue |
jerojasro@391 | 253 % siendo necesario |
jerojasro@336 | 254 \interaction{tour-merge-conflict.commit} |
jerojasro@336 | 255 |
jerojasro@392 | 256 \section{Simplificar el ciclo jalar-fusionar-consignar} |
jerojasro@336 | 257 \label{sec:tour-merge:fetch} |
jerojasro@336 | 258 |
jerojasro@392 | 259 El proceso de fusionar cambios delineado anteriomente es directo, pero |
jerojasro@392 | 260 requiere la ejecución de tres comandos en sucesión. |
jerojasro@336 | 261 \begin{codesample2} |
jerojasro@336 | 262 hg pull |
jerojasro@336 | 263 hg merge |
jerojasro@392 | 264 hg commit -m 'Fusionados cambios remotos' |
jerojasro@336 | 265 \end{codesample2} |
jerojasro@392 | 266 En la consignación final usted debe proveer un mensaje adecuado, que |
jerojasro@392 | 267 casi siempre es un fragmento de texto ``de relleno'' carente de valor |
jerojasro@392 | 268 particular. |
jerojasro@392 | 269 |
jerojasro@392 | 270 Sería agradable reducir la cantidad de pasos necesarios, si fuera |
jerojasro@392 | 271 posible. De hecho, Mercurial es distribuido junto con una extensión |
jerojasro@392 | 272 llamada \hgext{fetch}\ndt{Descargar, traer.} que hace precisamente |
jerojasro@392 | 273 esto. |
jerojasro@392 | 274 |
jerojasro@392 | 275 Mercurial cuenta con un mecanismo de extensión flexible que le permite |
jerojasro@392 | 276 % TODO lets people => permite a usuarios |
jerojasro@392 | 277 a sus usuarios extender su funcionalidad, manteniendo el núcleo de |
jerojasro@392 | 278 Mercurial pequeño y fácil de manejar. Algunas extensiones añaden |
jerojasro@392 | 279 nuevos comandos que usted puede usar desde la línea de comandos, |
jerojasro@392 | 280 mientras que otros funcionan ``tras bambalinas'', por ejemplo, |
jerojasro@392 | 281 añadiendo funcionalidad al servidor. |
jerojasro@392 | 282 |
jerojasro@392 | 283 La extensión \hgext{fetch} añade un comando llamado, no |
jerojasro@392 | 284 sorpresivamente, \hgcmd{fetch}. Esta extensión actúa como una |
jerojasro@392 | 285 combinación de \hgcmd{pull}, \hgcmd{update} y \hgcmd{merge}. Empieza |
jerojasro@392 | 286 jalando cambios de otro repositorio al repositorio actual. Si |
jerojasro@392 | 287 encuentra que los cambios añaden un nuevo frente en el repositorio |
jerojasro@392 | 288 actual, inicia una fusión, y luego consigna el resultado de la misma |
jerojasro@392 | 289 con un mensaje generado automáticamente. Si no se añadieron nuevos |
jerojasro@392 | 290 frentes, actualiza el directorio de trabajo con el nuevo conjunto de |
jerojasro@392 | 291 cambios de punta. |
jerojasro@392 | 292 |
jerojasro@392 | 293 Activar la extensión \hgext{fetch} es fácil. Edite su |
jerojasro@392 | 294 \sfilename{.hgrc}, y vaya a (o cree) la sección |
jerojasro@392 | 295 \rcsection{extensions}. Luego añada una línea que diga simplemente |
jerojasro@392 | 296 ``\Verb+fetch +''. |
jerojasro@336 | 297 \begin{codesample2} |
jerojasro@336 | 298 [extensions] |
jerojasro@336 | 299 fetch = |
jerojasro@336 | 300 \end{codesample2} |
jerojasro@392 | 301 (Normalmente, a la derecha del ``\texttt{=}'' debería aparecer la |
jerojasro@392 | 302 ubicación de la extensión, pero como el comando \hgext{fetch} es parte |
jerojasro@392 | 303 de la distribución estándar, Mercurial sabe dónde buscarla.) |
jerojasro@336 | 304 |
jerojasro@336 | 305 %%% Local Variables: |
jerojasro@336 | 306 %%% mode: latex |
jerojasro@336 | 307 %%% TeX-master: "00book" |
jerojasro@336 | 308 %%% End: |