hgbook

view es/tour-merge.tex @ 381:7ca1186c422f

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