hgbook

view es/tour-merge.tex @ 384:7f1572c365d2

translated up to section 2.1.1, included
author Javier Rojas <jerojasro@devnull.li>
date Fri Oct 31 00:19:04 2008 -0500 (2008-10-31)
parents 772b30049b80
children 0abd3d78172e
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{Performing the merge}
82 What happens if we try to use the normal \hgcmd{update} command to
83 update to the new tip?
84 \interaction{tour.merge.update}
85 Mercurial is telling us that the \hgcmd{update} command won't do a
86 merge; it won't update the working directory when it thinks we might
87 be wanting to do a merge, unless we force it to do so. Instead, we
88 use the \hgcmd{merge} command to merge the two heads.
89 \interaction{tour.merge.merge}
91 \begin{figure}[ht]
92 \centering
93 \grafix{tour-merge-merge}
94 \caption{Working directory and repository during merge, and
95 following commit}
96 \label{fig:tour-merge:merge}
97 \end{figure}
99 This updates the working directory so that it contains changes from
100 \emph{both} heads, which is reflected in both the output of
101 \hgcmd{parents} and the contents of \filename{hello.c}.
102 \interaction{tour.merge.parents}
104 \subsection{Committing the results of the merge}
106 Whenever we've done a merge, \hgcmd{parents} will display two parents
107 until we \hgcmd{commit} the results of the merge.
108 \interaction{tour.merge.commit}
109 We now have a new tip revision; notice that it has \emph{both} of
110 our former heads as its parents. These are the same revisions that
111 were previously displayed by \hgcmd{parents}.
112 \interaction{tour.merge.tip}
113 In figure~\ref{fig:tour-merge:merge}, you can see a representation of
114 what happens to the working directory during the merge, and how this
115 affects the repository when the commit happens. During the merge, the
116 working directory has two parent changesets, and these become the
117 parents of the new changeset.
119 \section{Merging conflicting changes}
121 Most merges are simple affairs, but sometimes you'll find yourself
122 merging changes where each modifies the same portions of the same
123 files. Unless both modifications are identical, this results in a
124 \emph{conflict}, where you have to decide how to reconcile the
125 different changes into something coherent.
127 \begin{figure}[ht]
128 \centering
129 \grafix{tour-merge-conflict}
130 \caption{Conflicting changes to a document}
131 \label{fig:tour-merge:conflict}
132 \end{figure}
134 Figure~\ref{fig:tour-merge:conflict} illustrates an instance of two
135 conflicting changes to a document. We started with a single version
136 of the file; then we made some changes; while someone else made
137 different changes to the same text. Our task in resolving the
138 conflicting changes is to decide what the file should look like.
140 Mercurial doesn't have a built-in facility for handling conflicts.
141 Instead, it runs an external program called \command{hgmerge}. This
142 is a shell script that is bundled with Mercurial; you can change it to
143 behave however you please. What it does by default is try to find one
144 of several different merging tools that are likely to be installed on
145 your system. It first tries a few fully automatic merging tools; if
146 these don't succeed (because the resolution process requires human
147 guidance) or aren't present, the script tries a few different
148 graphical merging tools.
150 It's also possible to get Mercurial to run another program or script
151 instead of \command{hgmerge}, by setting the \envar{HGMERGE}
152 environment variable to the name of your preferred program.
154 \subsection{Using a graphical merge tool}
156 My preferred graphical merge tool is \command{kdiff3}, which I'll use
157 to describe the features that are common to graphical file merging
158 tools. You can see a screenshot of \command{kdiff3} in action in
159 figure~\ref{fig:tour-merge:kdiff3}. The kind of merge it is
160 performing is called a \emph{three-way merge}, because there are three
161 different versions of the file of interest to us. The tool thus
162 splits the upper portion of the window into three panes:
163 \begin{itemize}
164 \item At the left is the \emph{base} version of the file, i.e.~the
165 most recent version from which the two versions we're trying to
166 merge are descended.
167 \item In the middle is ``our'' version of the file, with the contents
168 that we modified.
169 \item On the right is ``their'' version of the file, the one that
170 from the changeset that we're trying to merge with.
171 \end{itemize}
172 In the pane below these is the current \emph{result} of the merge.
173 Our task is to replace all of the red text, which indicates unresolved
174 conflicts, with some sensible merger of the ``ours'' and ``theirs''
175 versions of the file.
177 All four of these panes are \emph{locked together}; if we scroll
178 vertically or horizontally in any of them, the others are updated to
179 display the corresponding sections of their respective files.
181 \begin{figure}[ht]
182 \centering
183 \grafix{kdiff3}
184 \caption{Using \command{kdiff3} to merge versions of a file}
185 \label{fig:tour-merge:kdiff3}
186 \end{figure}
188 For each conflicting portion of the file, we can choose to resolve
189 the conflict using some combination of text from the base version,
190 ours, or theirs. We can also manually edit the merged file at any
191 time, in case we need to make further modifications.
193 There are \emph{many} file merging tools available, too many to cover
194 here. They vary in which platforms they are available for, and in
195 their particular strengths and weaknesses. Most are tuned for merging
196 files containing plain text, while a few are aimed at specialised file
197 formats (generally XML).
199 \subsection{A worked example}
201 In this example, we will reproduce the file modification history of
202 figure~\ref{fig:tour-merge:conflict} above. Let's begin by creating a
203 repository with a base version of our document.
204 \interaction{tour-merge-conflict.wife}
205 We'll clone the repository and make a change to the file.
206 \interaction{tour-merge-conflict.cousin}
207 And another clone, to simulate someone else making a change to the
208 file. (This hints at the idea that it's not all that unusual to merge
209 with yourself when you isolate tasks in separate repositories, and
210 indeed to find and resolve conflicts while doing so.)
211 \interaction{tour-merge-conflict.son}
212 Having created two different versions of the file, we'll set up an
213 environment suitable for running our merge.
214 \interaction{tour-merge-conflict.pull}
216 In this example, I won't use Mercurial's normal \command{hgmerge}
217 program to do the merge, because it would drop my nice automated
218 example-running tool into a graphical user interface. Instead, I'll
219 set \envar{HGMERGE} to tell Mercurial to use the non-interactive
220 \command{merge} command. This is bundled with many Unix-like systems.
221 If you're following this example on your computer, don't bother
222 setting \envar{HGMERGE}.
223 \interaction{tour-merge-conflict.merge}
224 Because \command{merge} can't resolve the conflicting changes, it
225 leaves \emph{merge markers} inside the file that has conflicts,
226 indicating which lines have conflicts, and whether they came from our
227 version of the file or theirs.
229 Mercurial can tell from the way \command{merge} exits that it wasn't
230 able to merge successfully, so it tells us what commands we'll need to
231 run if we want to redo the merging operation. This could be useful
232 if, for example, we were running a graphical merge tool and quit
233 because we were confused or realised we had made a mistake.
235 If automatic or manual merges fail, there's nothing to prevent us from
236 ``fixing up'' the affected files ourselves, and committing the results
237 of our merge:
238 \interaction{tour-merge-conflict.commit}
240 \section{Simplifying the pull-merge-commit sequence}
241 \label{sec:tour-merge:fetch}
243 The process of merging changes as outlined above is straightforward,
244 but requires running three commands in sequence.
245 \begin{codesample2}
246 hg pull
247 hg merge
248 hg commit -m 'Merged remote changes'
249 \end{codesample2}
250 In the case of the final commit, you also need to enter a commit
251 message, which is almost always going to be a piece of uninteresting
252 ``boilerplate'' text.
254 It would be nice to reduce the number of steps needed, if this were
255 possible. Indeed, Mercurial is distributed with an extension called
256 \hgext{fetch} that does just this.
258 Mercurial provides a flexible extension mechanism that lets people
259 extend its functionality, while keeping the core of Mercurial small
260 and easy to deal with. Some extensions add new commands that you can
261 use from the command line, while others work ``behind the scenes,''
262 for example adding capabilities to the server.
264 The \hgext{fetch} extension adds a new command called, not
265 surprisingly, \hgcmd{fetch}. This extension acts as a combination of
266 \hgcmd{pull}, \hgcmd{update} and \hgcmd{merge}. It begins by pulling
267 changes from another repository into the current repository. If it
268 finds that the changes added a new head to the repository, it begins a
269 merge, then commits the result of the merge with an
270 automatically-generated commit message. If no new heads were added,
271 it updates the working directory to the new tip changeset.
273 Enabling the \hgext{fetch} extension is easy. Edit your
274 \sfilename{.hgrc}, and either go to the \rcsection{extensions} section
275 or create an \rcsection{extensions} section. Then add a line that
276 simply reads ``\Verb+fetch +''.
277 \begin{codesample2}
278 [extensions]
279 fetch =
280 \end{codesample2}
281 (Normally, on the right-hand side of the ``\texttt{=}'' would appear
282 the location of the extension, but since the \hgext{fetch} extension
283 is in the standard distribution, Mercurial knows where to search for
284 it.)
286 %%% Local Variables:
287 %%% mode: latex
288 %%% TeX-master: "00book"
289 %%% End: