hgbook

view es/tour-merge.tex @ 383:772b30049b80

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