hgbook

view en/ch02-tour-merge.xml @ 681:557552d4699f

Add IDs to paragraphs.
author Bryan O'Sullivan <bos@serpentine.com>
date Tue Apr 21 23:51:47 2009 -0700 (2009-04-21)
parents e9ef075327c1
children a17d6390a480
line source
1 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
3 <chapter id="chap:tour-merge">
4 <?dbhtml filename="a-tour-of-mercurial-merging-work.html"?>
5 <title>A tour of Mercurial: merging work</title>
7 <para id="x_338">We've now covered cloning a repository, making changes in a
8 repository, and pulling or pushing changes from one repository
9 into another. Our next step is <emphasis>merging</emphasis>
10 changes from separate repositories.</para>
12 <sect1>
13 <title>Merging streams of work</title>
15 <para id="x_339">Merging is a fundamental part of working with a distributed
16 revision control tool.</para>
17 <itemizedlist>
18 <listitem><para id="x_33a">Alice and Bob each have a personal copy of a
19 repository for a project they're collaborating on. Alice
20 fixes a bug in her repository; Bob adds a new feature in
21 his. They want the shared repository to contain both the
22 bug fix and the new feature.</para>
23 </listitem>
24 <listitem><para id="x_33b">I frequently work on several different tasks for
25 a single project at once, each safely isolated in its own
26 repository. Working this way means that I often need to
27 merge one piece of my own work with another.</para>
28 </listitem></itemizedlist>
30 <para id="x_33c">Because merging is such a common thing to need to do,
31 Mercurial makes it easy. Let's walk through the process. We'll
32 begin by cloning yet another repository (see how often they
33 spring up?) and making a change in it.</para>
35 &interaction.tour.merge.clone;
37 <para id="x_33d">We should now have two copies of
38 <filename>hello.c</filename> with different contents. The
39 histories of the two repositories have also diverged, as
40 illustrated in <xref
41 linkend="fig:tour-merge:sep-repos"/>.</para>
43 &interaction.tour.merge.cat;
45 <figure id="fig:tour-merge:sep-repos">
46 <title>Divergent recent histories of the <filename
47 class="directory">my-hello</filename> and <filename
48 class="directory">my-new-hello</filename>
49 repositories</title>
50 <mediaobject>
51 <imageobject><imagedata fileref="figs/tour-merge-sep-repos.png"/></imageobject>
52 <textobject><phrase>XXX add text</phrase></textobject>
53 </mediaobject>
54 </figure>
56 <para id="x_33f">We already know that pulling changes from our <filename
57 class="directory">my-hello</filename> repository will have no
58 effect on the working directory.</para>
60 &interaction.tour.merge.pull;
62 <para id="x_340">However, the <command role="hg-cmd">hg pull</command>
63 command says something about <quote>heads</quote>.</para>
65 <sect2>
66 <title>Head changesets</title>
68 <para id="x_341">A head is a change that has no descendants, or children,
69 as they're also known. The tip revision is thus a head,
70 because the newest revision in a repository doesn't have any
71 children, but a repository can contain more than one
72 head.</para>
74 <figure id="fig:tour-merge:pull">
75 <title>Repository contents after pulling from <filename
76 class="directory">my-hello</filename> into <filename
77 class="directory">my-new-hello</filename></title>
78 <mediaobject>
79 <imageobject>
80 <imagedata fileref="figs/tour-merge-pull.png"/>
81 </imageobject>
82 <textobject><phrase>XXX add text</phrase></textobject>
83 </mediaobject>
84 </figure>
86 <para id="x_343">In <xref linkend="fig:tour-merge:pull"/>, you can
87 see the effect of the pull from <filename
88 class="directory">my-hello</filename> into <filename
89 class="directory">my-new-hello</filename>. The history that
90 was already present in <filename
91 class="directory">my-new-hello</filename> is untouched, but
92 a new revision has been added. By referring to <xref
93 linkend="fig:tour-merge:sep-repos"/>, we can see that the
94 <emphasis>changeset ID</emphasis> remains the same in the new
95 repository, but the <emphasis>revision number</emphasis> has
96 changed. (This, incidentally, is a fine example of why it's
97 not safe to use revision numbers when discussing changesets.)
98 We can view the heads in a repository using the <command
99 role="hg-cmd">hg heads</command> command.</para>
101 &interaction.tour.merge.heads;
103 </sect2>
104 <sect2>
105 <title>Performing the merge</title>
107 <para id="x_344">What happens if we try to use the normal <command
108 role="hg-cmd">hg update</command> command to update to the
109 new tip?</para>
111 &interaction.tour.merge.update;
113 <para id="x_345">Mercurial is telling us that the <command role="hg-cmd">hg
114 update</command> command won't do a merge; it won't update
115 the working directory when it thinks we might want to do
116 a merge, unless we force it to do so. Instead, we use the
117 <command role="hg-cmd">hg merge</command> command to merge the
118 two heads.</para>
120 &interaction.tour.merge.merge;
122 <para id="x_347">This updates the working directory so that it contains
123 changes from <emphasis>both</emphasis> heads, which is
124 reflected in both the output of <command role="hg-cmd">hg
125 parents</command> and the contents of
126 <filename>hello.c</filename>.</para>
128 &interaction.tour.merge.parents;
130 </sect2>
131 <sect2>
132 <title>Committing the results of the merge</title>
134 <para id="x_348">Whenever we've done a merge, <command role="hg-cmd">hg
135 parents</command> will display two parents until we <command
136 role="hg-cmd">hg commit</command> the results of the
137 merge.</para>
139 &interaction.tour.merge.commit;
141 <para id="x_349">We now have a new tip revision; notice that it has
142 <emphasis>both</emphasis> of our former heads as its parents.
143 These are the same revisions that were previously displayed by
144 <command role="hg-cmd">hg parents</command>.</para>
146 &interaction.tour.merge.tip;
148 <para id="x_34a">In <xref
149 linkend="fig:tour-merge:merge"/>, you can see a
150 representation of what happens to the working directory during
151 the merge, and how this affects the repository when the commit
152 happens. During the merge, the working directory has two
153 parent changesets, and these become the parents of the new
154 changeset.</para>
156 <figure id="fig:tour-merge:merge">
157 <title>Working directory and repository during merge, and
158 following commit</title>
159 <mediaobject>
160 <imageobject>
161 <imagedata fileref="figs/tour-merge-merge.png"/>
162 </imageobject>
163 <textobject><phrase>XXX add text</phrase></textobject>
164 </mediaobject>
165 </figure>
167 <para id="x_69c">We sometimes talk about a merge having
168 <emphasis>sides</emphasis>: the left side is the first parent
169 in the output of <command role="hg-cmd">hg parents</command>,
170 and the right side is the second. If the working directory
171 was at e.g. revision 5 before we began a merge, that revision
172 will become the left side of the merge.</para>
173 </sect2>
174 </sect1>
176 <sect1>
177 <title>Merging conflicting changes</title>
179 <para id="x_34b">Most merges are simple affairs, but sometimes you'll find
180 yourself merging changes where each side modifies the same portions
181 of the same files. Unless both modifications are identical,
182 this results in a <emphasis>conflict</emphasis>, where you have
183 to decide how to reconcile the different changes into something
184 coherent.</para>
186 <figure id="fig:tour-merge:conflict">
187 <title>Conflicting changes to a document</title>
188 <mediaobject>
189 <imageobject><imagedata fileref="figs/tour-merge-conflict.png"/></imageobject>
190 <textobject><phrase>XXX add text</phrase></textobject>
191 </mediaobject>
192 </figure>
194 <para id="x_34d"><xref linkend="fig:tour-merge:conflict"/> illustrates
195 an instance of two conflicting changes to a document. We
196 started with a single version of the file; then we made some
197 changes; while someone else made different changes to the same
198 text. Our task in resolving the conflicting changes is to
199 decide what the file should look like.</para>
201 <para id="x_34e">Mercurial doesn't have a built-in facility for handling
202 conflicts. Instead, it runs an external program, usually one
203 that displays some kind of graphical conflict resolution
204 interface. By default, Mercurial tries to find one of several
205 different merging tools that are likely to be installed on your
206 system. It first tries a few fully automatic merging tools; if
207 these don't succeed (because the resolution process requires
208 human guidance) or aren't present, it tries a few
209 different graphical merging tools.</para>
211 <para id="x_34f">It's also possible to get Mercurial to run another program
212 or script instead of <command>hgmerge</command>, by setting the
213 <envar>HGMERGE</envar> environment variable to the name of your
214 preferred program.</para>
216 <sect2>
217 <title>Using a graphical merge tool</title>
219 <para id="x_350">My preferred graphical merge tool is
220 <command>kdiff3</command>, which I'll use to describe the
221 features that are common to graphical file merging tools. You
222 can see a screenshot of <command>kdiff3</command> in action in
223 <xref linkend="fig:tour-merge:kdiff3"/>. The kind of
224 merge it is performing is called a <emphasis>three-way
225 merge</emphasis>, because there are three different versions
226 of the file of interest to us. The tool thus splits the upper
227 portion of the window into three panes:</para>
228 <itemizedlist>
229 <listitem><para id="x_351">At the left is the <emphasis>base</emphasis>
230 version of the file, i.e. the most recent version from
231 which the two versions we're trying to merge are
232 descended.</para>
233 </listitem>
234 <listitem><para id="x_352">In the middle is <quote>our</quote> version of
235 the file, with the contents that we modified.</para>
236 </listitem>
237 <listitem><para id="x_353">On the right is <quote>their</quote> version
238 of the file, the one that from the changeset that we're
239 trying to merge with.</para>
240 </listitem></itemizedlist>
241 <para id="x_354">In the pane below these is the current
242 <emphasis>result</emphasis> of the merge. Our task is to
243 replace all of the red text, which indicates unresolved
244 conflicts, with some sensible merger of the
245 <quote>ours</quote> and <quote>theirs</quote> versions of the
246 file.</para>
248 <para id="x_355">All four of these panes are <emphasis>locked
249 together</emphasis>; if we scroll vertically or horizontally
250 in any of them, the others are updated to display the
251 corresponding sections of their respective files.</para>
253 <figure id="fig:tour-merge:kdiff3">
254 <title>Using <command>kdiff3</command> to merge versions of a
255 file</title>
256 <mediaobject>
257 <imageobject>
258 <imagedata width="100%" fileref="figs/kdiff3.png"/></imageobject>
259 <textobject>
260 <phrase>XXX add text</phrase>
261 </textobject>
262 </mediaobject>
263 </figure>
265 <para id="x_357">For each conflicting portion of the file, we can choose to
266 resolve the conflict using some combination of text from the
267 base version, ours, or theirs. We can also manually edit the
268 merged file at any time, in case we need to make further
269 modifications.</para>
271 <para id="x_358">There are <emphasis>many</emphasis> file merging tools
272 available, too many to cover here. They vary in which
273 platforms they are available for, and in their particular
274 strengths and weaknesses. Most are tuned for merging files
275 containing plain text, while a few are aimed at specialised
276 file formats (generally XML).</para>
278 </sect2>
279 <sect2>
280 <title>A worked example</title>
282 <para id="x_359">In this example, we will reproduce the file modification
283 history of <xref linkend="fig:tour-merge:conflict"/>
284 above. Let's begin by creating a repository with a base
285 version of our document.</para>
287 &interaction.tour-merge-conflict.wife;
289 <para id="x_35a">We'll clone the repository and make a change to the
290 file.</para>
292 &interaction.tour-merge-conflict.cousin;
294 <para id="x_35b">And another clone, to simulate someone else making a
295 change to the file. (This hints at the idea that it's not all
296 that unusual to merge with yourself when you isolate tasks in
297 separate repositories, and indeed to find and resolve
298 conflicts while doing so.)</para>
300 &interaction.tour-merge-conflict.son;
302 <para id="x_35c">Having created two
303 different versions of the file, we'll set up an environment
304 suitable for running our merge.</para>
306 &interaction.tour-merge-conflict.pull;
308 <para id="x_35d">In this example, I'll set
309 <envar>HGMERGE</envar> to tell Mercurial to use the
310 non-interactive <command>merge</command> command. This is
311 bundled with many Unix-like systems. (If you're following this
312 example on your computer, don't bother setting
313 <envar>HGMERGE</envar>.)</para>
315 &interaction.tour-merge-conflict.merge;
317 <para id="x_35f">Because <command>merge</command> can't resolve the
318 conflicting changes, it leaves <emphasis>merge
319 markers</emphasis> inside the file that has conflicts,
320 indicating which lines have conflicts, and whether they came
321 from our version of the file or theirs.</para>
323 <para id="x_360">Mercurial can tell from the way <command>merge</command>
324 exits that it wasn't able to merge successfully, so it tells
325 us what commands we'll need to run if we want to redo the
326 merging operation. This could be useful if, for example, we
327 were running a graphical merge tool and quit because we were
328 confused or realised we had made a mistake.</para>
330 <para id="x_361">If automatic or manual merges fail, there's nothing to
331 prevent us from <quote>fixing up</quote> the affected files
332 ourselves, and committing the results of our merge:</para>
334 &interaction.tour-merge-conflict.commit;
336 </sect2>
337 </sect1>
338 <sect1 id="sec:tour-merge:fetch">
339 <title>Simplifying the pull-merge-commit sequence</title>
341 <para id="x_362">The process of merging changes as outlined above is
342 straightforward, but requires running three commands in
343 sequence.</para>
344 <programlisting>hg pull -u
345 hg merge
346 hg commit -m 'Merged remote changes'</programlisting>
347 <para id="x_363">In the case of the final commit, you also need to enter a
348 commit message, which is almost always going to be a piece of
349 uninteresting <quote>boilerplate</quote> text.</para>
351 <para id="x_364">It would be nice to reduce the number of steps needed, if
352 this were possible. Indeed, Mercurial is distributed with an
353 extension called <literal role="hg-ext">fetch</literal> that
354 does just this.</para>
356 <para id="x_365">Mercurial provides a flexible extension mechanism that lets
357 people extend its functionality, while keeping the core of
358 Mercurial small and easy to deal with. Some extensions add new
359 commands that you can use from the command line, while others
360 work <quote>behind the scenes,</quote> for example adding
361 capabilities to the server.</para>
363 <para id="x_366">The <literal role="hg-ext">fetch</literal>
364 extension adds a new command called, not surprisingly, <command
365 role="hg-cmd">hg fetch</command>. This extension acts as a
366 combination of <command role="hg-cmd">hg pull -u</command>,
367 <command role="hg-cmd">hg merge</command> and <command
368 role="hg-cmd">hg commit</command>. It begins by pulling
369 changes from another repository into the current repository. If
370 it finds that the changes added a new head to the repository, it
371 begins a merge, then (if the merge succeeded) commits the result
372 of the merge with an automatically-generated commit message. If
373 no new heads were added, it updates the working directory to the
374 new tip changeset.</para>
376 <para id="x_367">Enabling the <literal
377 role="hg-ext">fetch</literal> extension is easy. Edit the
378 <filename role="special">.hgrc</filename> file in your home
379 directory, and either go to the <literal
380 role="rc-extensions">extensions</literal> section or create an
381 <literal role="rc-extensions">extensions</literal> section. Then
382 add a line that simply reads
383 <quote><literal>fetch=</literal></quote>.</para>
385 <programlisting>[extensions]
386 fetch =</programlisting>
388 <para id="x_368">(Normally, the right-hand side of the
389 <quote><literal>=</literal></quote> would indicate where to find
390 the extension, but since the <literal
391 role="hg-ext">fetch</literal> extension is in the standard
392 distribution, Mercurial knows where to search for it.)</para>
394 </sect1>
395 </chapter>
397 <!--
398 local variables:
399 sgml-parent-document: ("00book.xml" "book" "chapter")
400 end:
401 -->