hgbook

view es/tour-merge.tex @ 398:c368e324eeb2

Finished translating bisect
author Igor TAmara <igor@tamarapatino.org>
date Thu Nov 06 23:06:16 2008 -0500 (2008-11-06)
parents 7f1572c365d2
children c3a867bba34a
line source
1 \chapter{Una gira de Mercurial: fusionar trabajo}
2 \label{chap:tour-merge}
4 Hasta ahora hemos cubierto cómo clonar un repositorio, hacer cambios,
5 y jalar o empujar dichos cambios de un repositorio a otro. Nuestro
6 siguiente paso es \emph{fusionar} cambios de repositorios separados.
8 % TODO cambié streams por líneas. check please
9 \section{Fusionar líneas de trabajo}
11 Fusionar es una parte fundamental de trabajar con una herramienta
12 de control distribuido de versiones.
13 \begin{itemize}
14 \item Alicia y Roberto tienen cada uno una copia personal del
15 repositorio de un proyecto en el que están trabajando. Alicia
16 arregla un fallo en su repositorio; Roberto añade una nueva
17 característica en el suyo. Ambos desean que el repositorio
18 compartido contenga el arreglo del fallo y la nueva
19 característica.
20 \item Frecuentemente trabajo en varias tareas diferentes en un mismo
21 proyecto al mismo tiempo, cada una aislada convenientemente de las
22 otras en su propio repositorio. Trabajar de esta manera significa
23 que a menudo debo fusionar una parte de mi propio trabajo con
24 otra.
25 \end{itemize}
27 Como fusionar es una operación tan necesaria y común, Mercurial la
28 facilita. Revisemos el proceso. Empezaremos clonando (otro)
29 % TODO poner interrogante de apertura
30 repositorio (ve lo seguido que aparecen?) y haciendo un cambio en él.
31 \interaction{tour.merge.clone}
32 Ahora deberíamos tener dos copias de \filename{hello.c} con contenidos
33 diferentes. El historial de los dos repositorios diverge ahora, como
34 se ilustra en la figura~\ref{fig:tour-merge:sep-repos}.
35 \interaction{tour.merge.cat}
37 \begin{figure}[ht]
38 \centering
39 \grafix{tour-merge-sep-repos}
40 \caption{Historial reciente divergente de los repositorios
41 \dirname{my-hello} y \dirname{my-new-hello}}
42 \label{fig:tour-merge:sep-repos}
43 \end{figure}
45 Ya sabemos que jalar los cambios desde nuestro repositorio
46 \dirname{my-hello} no tendrá efecto en el directorio de trabajo.
47 \interaction{tour.merge.pull}
48 Sin embargo, el comando \hgcmd{pull} dice algo acerca de
49 ``frentes''\ndt{El autor se refiere a \emph{heads} aquí.}.
51 \subsection{Conjuntos de cambios de frentes}
53 Un frente es un cambio que no tiene descendientes, o hijos, como
54 también se les conoce. La revisión de punta es, por tanto, un frente,
55 porque la revisión más reciente en un repositorio no tiene ningún
56 % TODO cambio en la redacción de la frase, pero espero que conserve el
57 % sentido. Querido human@, apruebe o corrija :D
58 hijo. Sin embargo, un repositorio puede contener más de un frente.
60 \begin{figure}[ht]
61 \centering
62 \grafix{tour-merge-pull}
63 \caption{Contenidos del repositorio después de jalar
64 \dirname{my-hello} a \dirname{my-new-hello}}
65 \label{fig:tour-merge:pull}
66 \end{figure}
68 En la figura~\ref{fig:tour-merge:pull} usted puede ver el efecto que
69 tiene jalar los cambios de \dirname{my-hello} a \dirname{my-new-hello}.
70 El historial que ya existía en \dirname{my-new-hello} se mantiene
71 intacto, pero fue añadida una nueva revisión. Refiriéndonos a la
72 figura~\ref{fig:tour-merge:sep-repos}, podemos ver que el \emph{ID del
73 conjunto de cambios} se mantiene igual en el nuevo repositorio, pero
74 el \emph{número de revisión} ha cambiado. (Incidentalmente, éste es un
75 buen ejemplo de porqué no es seguro usar números de revisión cuando se
76 habla de conjuntos de cambios). Podemos ver los frentes en un
77 repositorio usando el comando \hgcmd{heads}\ndt{Frentes.}.
78 \interaction{tour.merge.heads}
80 \subsection{Hacer la fusión}
82 % TODO poner interrogante de apertura
83 Qué pasa si tratamos de usar el comando usual, \hgcmd{update}, para
84 actualizar el nuevo frente?
85 \interaction{tour.merge.update}
86 Mercurial nos indica que el comando \hgcmd{update} no hará la fusión;
87 no actualizará el directorio de trabajo cuando considera que lo que
88 deseamos hacer es una fusión, a menos que lo obliguemos a hacerlo.
89 En vez de \hgcmd{update}, usamos el comando \hgcmd{merge} para hacer
90 la fusión entre los dos frentes.
91 \interaction{tour.merge.merge}
93 \begin{figure}[ht]
94 \centering
95 \grafix{tour-merge-merge}
96 \caption{Directorio de trabajo y repositorio durante la fusión, y
97 consignación consecuente}
98 \label{fig:tour-merge:merge}
99 \end{figure}
101 Esto actualiza el directorio de trabajo, de tal forma que contenga los
102 cambios de \emph{ambos} frentes, lo que se ve reflejado tanto en la
103 salida de \hgcmd{parents} como en los contenidos de \filename{hello.c}.
104 \interaction{tour.merge.parents}
106 \subsection{Consignar los resultados de la fusión}
108 Whenever we've done a merge, \hgcmd{parents} will display two parents
109 until we \hgcmd{commit} the results of the merge.
110 \interaction{tour.merge.commit}
111 We now have a new tip revision; notice that it has \emph{both} of
112 our former heads as its parents. These are the same revisions that
113 were previously displayed by \hgcmd{parents}.
114 \interaction{tour.merge.tip}
115 In figure~\ref{fig:tour-merge:merge}, you can see a representation of
116 what happens to the working directory during the merge, and how this
117 affects the repository when the commit happens. During the merge, the
118 working directory has two parent changesets, and these become the
119 parents of the new changeset.
121 \section{Merging conflicting changes}
123 Most merges are simple affairs, but sometimes you'll find yourself
124 merging changes where each modifies the same portions of the same
125 files. Unless both modifications are identical, this results in a
126 \emph{conflict}, where you have to decide how to reconcile the
127 different changes into something coherent.
129 \begin{figure}[ht]
130 \centering
131 \grafix{tour-merge-conflict}
132 \caption{Conflicting changes to a document}
133 \label{fig:tour-merge:conflict}
134 \end{figure}
136 Figure~\ref{fig:tour-merge:conflict} illustrates an instance of two
137 conflicting changes to a document. We started with a single version
138 of the file; then we made some changes; while someone else made
139 different changes to the same text. Our task in resolving the
140 conflicting changes is to decide what the file should look like.
142 Mercurial doesn't have a built-in facility for handling conflicts.
143 Instead, it runs an external program called \command{hgmerge}. This
144 is a shell script that is bundled with Mercurial; you can change it to
145 behave however you please. What it does by default is try to find one
146 of several different merging tools that are likely to be installed on
147 your system. It first tries a few fully automatic merging tools; if
148 these don't succeed (because the resolution process requires human
149 guidance) or aren't present, the script tries a few different
150 graphical merging tools.
152 It's also possible to get Mercurial to run another program or script
153 instead of \command{hgmerge}, by setting the \envar{HGMERGE}
154 environment variable to the name of your preferred program.
156 \subsection{Using a graphical merge tool}
158 My preferred graphical merge tool is \command{kdiff3}, which I'll use
159 to describe the features that are common to graphical file merging
160 tools. You can see a screenshot of \command{kdiff3} in action in
161 figure~\ref{fig:tour-merge:kdiff3}. The kind of merge it is
162 performing is called a \emph{three-way merge}, because there are three
163 different versions of the file of interest to us. The tool thus
164 splits the upper portion of the window into three panes:
165 \begin{itemize}
166 \item At the left is the \emph{base} version of the file, i.e.~the
167 most recent version from which the two versions we're trying to
168 merge are descended.
169 \item In the middle is ``our'' version of the file, with the contents
170 that we modified.
171 \item On the right is ``their'' version of the file, the one that
172 from the changeset that we're trying to merge with.
173 \end{itemize}
174 In the pane below these is the current \emph{result} of the merge.
175 Our task is to replace all of the red text, which indicates unresolved
176 conflicts, with some sensible merger of the ``ours'' and ``theirs''
177 versions of the file.
179 All four of these panes are \emph{locked together}; if we scroll
180 vertically or horizontally in any of them, the others are updated to
181 display the corresponding sections of their respective files.
183 \begin{figure}[ht]
184 \centering
185 \grafix{kdiff3}
186 \caption{Using \command{kdiff3} to merge versions of a file}
187 \label{fig:tour-merge:kdiff3}
188 \end{figure}
190 For each conflicting portion of the file, we can choose to resolve
191 the conflict using some combination of text from the base version,
192 ours, or theirs. We can also manually edit the merged file at any
193 time, in case we need to make further modifications.
195 There are \emph{many} file merging tools available, too many to cover
196 here. They vary in which platforms they are available for, and in
197 their particular strengths and weaknesses. Most are tuned for merging
198 files containing plain text, while a few are aimed at specialised file
199 formats (generally XML).
201 \subsection{A worked example}
203 In this example, we will reproduce the file modification history of
204 figure~\ref{fig:tour-merge:conflict} above. Let's begin by creating a
205 repository with a base version of our document.
206 \interaction{tour-merge-conflict.wife}
207 We'll clone the repository and make a change to the file.
208 \interaction{tour-merge-conflict.cousin}
209 And another clone, to simulate someone else making a change to the
210 file. (This hints at the idea that it's not all that unusual to merge
211 with yourself when you isolate tasks in separate repositories, and
212 indeed to find and resolve conflicts while doing so.)
213 \interaction{tour-merge-conflict.son}
214 Having created two different versions of the file, we'll set up an
215 environment suitable for running our merge.
216 \interaction{tour-merge-conflict.pull}
218 In this example, I won't use Mercurial's normal \command{hgmerge}
219 program to do the merge, because it would drop my nice automated
220 example-running tool into a graphical user interface. Instead, I'll
221 set \envar{HGMERGE} to tell Mercurial to use the non-interactive
222 \command{merge} command. This is bundled with many Unix-like systems.
223 If you're following this example on your computer, don't bother
224 setting \envar{HGMERGE}.
225 \interaction{tour-merge-conflict.merge}
226 Because \command{merge} can't resolve the conflicting changes, it
227 leaves \emph{merge markers} inside the file that has conflicts,
228 indicating which lines have conflicts, and whether they came from our
229 version of the file or theirs.
231 Mercurial can tell from the way \command{merge} exits that it wasn't
232 able to merge successfully, so it tells us what commands we'll need to
233 run if we want to redo the merging operation. This could be useful
234 if, for example, we were running a graphical merge tool and quit
235 because we were confused or realised we had made a mistake.
237 If automatic or manual merges fail, there's nothing to prevent us from
238 ``fixing up'' the affected files ourselves, and committing the results
239 of our merge:
240 \interaction{tour-merge-conflict.commit}
242 \section{Simplifying the pull-merge-commit sequence}
243 \label{sec:tour-merge:fetch}
245 The process of merging changes as outlined above is straightforward,
246 but requires running three commands in sequence.
247 \begin{codesample2}
248 hg pull
249 hg merge
250 hg commit -m 'Merged remote changes'
251 \end{codesample2}
252 In the case of the final commit, you also need to enter a commit
253 message, which is almost always going to be a piece of uninteresting
254 ``boilerplate'' text.
256 It would be nice to reduce the number of steps needed, if this were
257 possible. Indeed, Mercurial is distributed with an extension called
258 \hgext{fetch} that does just this.
260 Mercurial provides a flexible extension mechanism that lets people
261 extend its functionality, while keeping the core of Mercurial small
262 and easy to deal with. Some extensions add new commands that you can
263 use from the command line, while others work ``behind the scenes,''
264 for example adding capabilities to the server.
266 The \hgext{fetch} extension adds a new command called, not
267 surprisingly, \hgcmd{fetch}. This extension acts as a combination of
268 \hgcmd{pull}, \hgcmd{update} and \hgcmd{merge}. It begins by pulling
269 changes from another repository into the current repository. If it
270 finds that the changes added a new head to the repository, it begins a
271 merge, then commits the result of the merge with an
272 automatically-generated commit message. If no new heads were added,
273 it updates the working directory to the new tip changeset.
275 Enabling the \hgext{fetch} extension is easy. Edit your
276 \sfilename{.hgrc}, and either go to the \rcsection{extensions} section
277 or create an \rcsection{extensions} section. Then add a line that
278 simply reads ``\Verb+fetch +''.
279 \begin{codesample2}
280 [extensions]
281 fetch =
282 \end{codesample2}
283 (Normally, on the right-hand side of the ``\texttt{=}'' would appear
284 the location of the extension, but since the \hgext{fetch} extension
285 is in the standard distribution, Mercurial knows where to search for
286 it.)
288 %%% Local Variables:
289 %%% mode: latex
290 %%% TeX-master: "00book"
291 %%% End: