hgbook
annotate es/tour-merge.tex @ 390:c3a867bba34a
modified definitions to allow optional arguments for the inclusion of images.
This needs to be tested for html generation.
translated up to section 2.2.1 ot tour-merge
This needs to be tested for html generation.
translated up to section 2.2.1 ot tour-merge
author | Javier Rojas <jerojasro@devnull.li> |
---|---|
date | Sun Nov 02 20:08:45 2008 -0500 (2008-11-02) |
parents | 0abd3d78172e |
children | 53b4a0d0052e |
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@390 | 139 versión de el 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@390 | 167 tres versiones diferentes del archivo 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@390 | 207 formatos de archivos especializados (generalmente XML). |
jerojasro@336 | 208 |
jerojasro@336 | 209 \subsection{A worked example} |
jerojasro@336 | 210 |
jerojasro@336 | 211 In this example, we will reproduce the file modification history of |
jerojasro@336 | 212 figure~\ref{fig:tour-merge:conflict} above. Let's begin by creating a |
jerojasro@336 | 213 repository with a base version of our document. |
jerojasro@336 | 214 \interaction{tour-merge-conflict.wife} |
jerojasro@336 | 215 We'll clone the repository and make a change to the file. |
jerojasro@336 | 216 \interaction{tour-merge-conflict.cousin} |
jerojasro@336 | 217 And another clone, to simulate someone else making a change to the |
jerojasro@336 | 218 file. (This hints at the idea that it's not all that unusual to merge |
jerojasro@336 | 219 with yourself when you isolate tasks in separate repositories, and |
jerojasro@336 | 220 indeed to find and resolve conflicts while doing so.) |
jerojasro@336 | 221 \interaction{tour-merge-conflict.son} |
jerojasro@336 | 222 Having created two different versions of the file, we'll set up an |
jerojasro@336 | 223 environment suitable for running our merge. |
jerojasro@336 | 224 \interaction{tour-merge-conflict.pull} |
jerojasro@336 | 225 |
jerojasro@336 | 226 In this example, I won't use Mercurial's normal \command{hgmerge} |
jerojasro@336 | 227 program to do the merge, because it would drop my nice automated |
jerojasro@336 | 228 example-running tool into a graphical user interface. Instead, I'll |
jerojasro@336 | 229 set \envar{HGMERGE} to tell Mercurial to use the non-interactive |
jerojasro@336 | 230 \command{merge} command. This is bundled with many Unix-like systems. |
jerojasro@336 | 231 If you're following this example on your computer, don't bother |
jerojasro@336 | 232 setting \envar{HGMERGE}. |
jerojasro@336 | 233 \interaction{tour-merge-conflict.merge} |
jerojasro@336 | 234 Because \command{merge} can't resolve the conflicting changes, it |
jerojasro@336 | 235 leaves \emph{merge markers} inside the file that has conflicts, |
jerojasro@336 | 236 indicating which lines have conflicts, and whether they came from our |
jerojasro@336 | 237 version of the file or theirs. |
jerojasro@336 | 238 |
jerojasro@336 | 239 Mercurial can tell from the way \command{merge} exits that it wasn't |
jerojasro@336 | 240 able to merge successfully, so it tells us what commands we'll need to |
jerojasro@336 | 241 run if we want to redo the merging operation. This could be useful |
jerojasro@336 | 242 if, for example, we were running a graphical merge tool and quit |
jerojasro@336 | 243 because we were confused or realised we had made a mistake. |
jerojasro@336 | 244 |
jerojasro@336 | 245 If automatic or manual merges fail, there's nothing to prevent us from |
jerojasro@336 | 246 ``fixing up'' the affected files ourselves, and committing the results |
jerojasro@336 | 247 of our merge: |
jerojasro@336 | 248 \interaction{tour-merge-conflict.commit} |
jerojasro@336 | 249 |
jerojasro@336 | 250 \section{Simplifying the pull-merge-commit sequence} |
jerojasro@336 | 251 \label{sec:tour-merge:fetch} |
jerojasro@336 | 252 |
jerojasro@336 | 253 The process of merging changes as outlined above is straightforward, |
jerojasro@336 | 254 but requires running three commands in sequence. |
jerojasro@336 | 255 \begin{codesample2} |
jerojasro@336 | 256 hg pull |
jerojasro@336 | 257 hg merge |
jerojasro@336 | 258 hg commit -m 'Merged remote changes' |
jerojasro@336 | 259 \end{codesample2} |
jerojasro@336 | 260 In the case of the final commit, you also need to enter a commit |
jerojasro@336 | 261 message, which is almost always going to be a piece of uninteresting |
jerojasro@336 | 262 ``boilerplate'' text. |
jerojasro@336 | 263 |
jerojasro@336 | 264 It would be nice to reduce the number of steps needed, if this were |
jerojasro@336 | 265 possible. Indeed, Mercurial is distributed with an extension called |
jerojasro@336 | 266 \hgext{fetch} that does just this. |
jerojasro@336 | 267 |
jerojasro@336 | 268 Mercurial provides a flexible extension mechanism that lets people |
jerojasro@336 | 269 extend its functionality, while keeping the core of Mercurial small |
jerojasro@336 | 270 and easy to deal with. Some extensions add new commands that you can |
jerojasro@336 | 271 use from the command line, while others work ``behind the scenes,'' |
jerojasro@336 | 272 for example adding capabilities to the server. |
jerojasro@336 | 273 |
jerojasro@336 | 274 The \hgext{fetch} extension adds a new command called, not |
jerojasro@336 | 275 surprisingly, \hgcmd{fetch}. This extension acts as a combination of |
jerojasro@336 | 276 \hgcmd{pull}, \hgcmd{update} and \hgcmd{merge}. It begins by pulling |
jerojasro@336 | 277 changes from another repository into the current repository. If it |
jerojasro@336 | 278 finds that the changes added a new head to the repository, it begins a |
jerojasro@336 | 279 merge, then commits the result of the merge with an |
jerojasro@336 | 280 automatically-generated commit message. If no new heads were added, |
jerojasro@336 | 281 it updates the working directory to the new tip changeset. |
jerojasro@336 | 282 |
jerojasro@336 | 283 Enabling the \hgext{fetch} extension is easy. Edit your |
jerojasro@336 | 284 \sfilename{.hgrc}, and either go to the \rcsection{extensions} section |
jerojasro@336 | 285 or create an \rcsection{extensions} section. Then add a line that |
jerojasro@336 | 286 simply reads ``\Verb+fetch +''. |
jerojasro@336 | 287 \begin{codesample2} |
jerojasro@336 | 288 [extensions] |
jerojasro@336 | 289 fetch = |
jerojasro@336 | 290 \end{codesample2} |
jerojasro@336 | 291 (Normally, on the right-hand side of the ``\texttt{=}'' would appear |
jerojasro@336 | 292 the location of the extension, but since the \hgext{fetch} extension |
jerojasro@336 | 293 is in the standard distribution, Mercurial knows where to search for |
jerojasro@336 | 294 it.) |
jerojasro@336 | 295 |
jerojasro@336 | 296 %%% Local Variables: |
jerojasro@336 | 297 %%% mode: latex |
jerojasro@336 | 298 %%% TeX-master: "00book" |
jerojasro@336 | 299 %%% End: |