hgbook

view en/ch03-tour-merge.xml @ 1070:3dec81dc4543

2.4 partly zh translated
author Zhaoping Sun <zhaopingsun@gmail.com>
date Wed Nov 11 21:25:10 2009 -0500 (2009-11-11)
parents 18131160f7ee
children
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. Here are a few cases in which the need
17 to merge work arises.</para>
18 <itemizedlist>
19 <listitem>
20 <para id="x_33a">Alice and Bob each have a personal copy of a
21 repository for a project they're collaborating on. Alice
22 fixes a bug in her repository; Bob adds a new feature in
23 his. They want the shared repository to contain both the
24 bug fix and the new feature.</para>
25 </listitem>
26 <listitem>
27 <para id="x_33b">Cynthia frequently works on several different
28 tasks for a single project at once, each safely isolated in
29 its own repository. Working this way means that she often
30 needs to merge one piece of her own work with
31 another.</para>
32 </listitem>
33 </itemizedlist>
35 <para id="x_33c">Because we need to merge often, Mercurial makes
36 the process easy. Let's walk through a merge. We'll begin by
37 cloning yet another repository (see how often they spring up?)
38 and making a change in it.</para>
40 &interaction.tour.merge.clone;
42 <para id="x_33d">We should now have two copies of
43 <filename>hello.c</filename> with different contents. The
44 histories of the two repositories have also diverged, as
45 illustrated in <xref
46 linkend="fig:tour-merge:sep-repos"/>. Here is a copy of our
47 file from one repository.</para>
49 &interaction.tour.merge.cat1;
51 <para id="x_722">And here is our slightly different version from the other
52 repository.</para>
54 &interaction.tour.merge.cat2;
56 <figure id="fig:tour-merge:sep-repos">
57 <title>Divergent recent histories of the <filename
58 class="directory">my-hello</filename> and <filename
59 class="directory">my-new-hello</filename>
60 repositories</title>
61 <mediaobject>
62 <imageobject><imagedata fileref="figs/tour-merge-sep-repos.png"/></imageobject>
63 <textobject><phrase>XXX add text</phrase></textobject>
64 </mediaobject>
65 </figure>
67 <para id="x_33f">We already know that pulling changes from our <filename
68 class="directory">my-hello</filename> repository will have no
69 effect on the working directory.</para>
71 &interaction.tour.merge.pull;
73 <para id="x_340">However, the <command role="hg-cmd">hg pull</command>
74 command says something about <quote>heads</quote>.</para>
76 <sect2>
77 <title>Head changesets</title>
79 <para id="x_341">Remember that Mercurial records what the parent
80 of each change is. If a change has a parent, we call it a
81 child or descendant of the parent. A head is a change that
82 has no children. The tip revision is thus a head, because the
83 newest revision in a repository doesn't have any children.
84 There are times when a repository can contain more than one
85 head.</para>
87 <figure id="fig:tour-merge:pull">
88 <title>Repository contents after pulling from <filename
89 class="directory">my-hello</filename> into <filename
90 class="directory">my-new-hello</filename></title>
91 <mediaobject>
92 <imageobject>
93 <imagedata fileref="figs/tour-merge-pull.png"/>
94 </imageobject>
95 <textobject><phrase>XXX add text</phrase></textobject>
96 </mediaobject>
97 </figure>
99 <para id="x_343">In <xref linkend="fig:tour-merge:pull"/>, you can
100 see the effect of the pull from <filename
101 class="directory">my-hello</filename> into <filename
102 class="directory">my-new-hello</filename>. The history that
103 was already present in <filename
104 class="directory">my-new-hello</filename> is untouched, but
105 a new revision has been added. By referring to <xref
106 linkend="fig:tour-merge:sep-repos"/>, we can see that the
107 <emphasis>changeset ID</emphasis> remains the same in the new
108 repository, but the <emphasis>revision number</emphasis> has
109 changed. (This, incidentally, is a fine example of why it's
110 not safe to use revision numbers when discussing changesets.)
111 We can view the heads in a repository using the <command
112 role="hg-cmd">hg heads</command> command.</para>
114 &interaction.tour.merge.heads;
115 </sect2>
117 <sect2>
118 <title>Performing the merge</title>
120 <para id="x_344">What happens if we try to use the normal <command
121 role="hg-cmd">hg update</command> command to update to the
122 new tip?</para>
124 &interaction.tour.merge.update;
126 <para id="x_345">Mercurial is telling us that the <command
127 role="hg-cmd">hg update</command> command won't do a merge;
128 it won't update the working directory when it thinks we might
129 want to do a merge, unless we force it to do so.
130 (Incidentally, forcing the update with <command>hg update
131 -C</command> would revert any uncommitted changes in the
132 working directory.)</para>
134 <para id="x_723">To start a merge between the two heads, we use the
135 <command role="hg-cmd">hg merge</command> command.</para>
137 &interaction.tour.merge.merge;
139 <para id="x_347">We resolve the contents of <filename>hello.c</filename>
141 This updates the working directory so that it
142 contains changes from <emphasis>both</emphasis> heads, which
143 is reflected in both the output of <command role="hg-cmd">hg
144 parents</command> and the contents of
145 <filename>hello.c</filename>.</para>
147 &interaction.tour.merge.parents;
148 </sect2>
150 <sect2>
151 <title>Committing the results of the merge</title>
153 <para id="x_348">Whenever we've done a merge, <command role="hg-cmd">hg
154 parents</command> will display two parents until we <command
155 role="hg-cmd">hg commit</command> the results of the
156 merge.</para>
158 &interaction.tour.merge.commit;
160 <para id="x_349">We now have a new tip revision; notice that it has
161 <emphasis>both</emphasis> of our former heads as its parents.
162 These are the same revisions that were previously displayed by
163 <command role="hg-cmd">hg parents</command>.</para>
165 &interaction.tour.merge.tip;
167 <para id="x_34a">In <xref
168 linkend="fig:tour-merge:merge"/>, you can see a
169 representation of what happens to the working directory during
170 the merge, and how this affects the repository when the commit
171 happens. During the merge, the working directory has two
172 parent changesets, and these become the parents of the new
173 changeset.</para>
175 <figure id="fig:tour-merge:merge">
176 <title>Working directory and repository during merge, and
177 following commit</title>
178 <mediaobject>
179 <imageobject>
180 <imagedata fileref="figs/tour-merge-merge.png"/>
181 </imageobject>
182 <textobject><phrase>XXX add text</phrase></textobject>
183 </mediaobject>
184 </figure>
186 <para id="x_69c">We sometimes talk about a merge having
187 <emphasis>sides</emphasis>: the left side is the first parent
188 in the output of <command role="hg-cmd">hg parents</command>,
189 and the right side is the second. If the working directory
190 was at e.g. revision 5 before we began a merge, that revision
191 will become the left side of the merge.</para>
192 </sect2>
193 </sect1>
195 <sect1>
196 <title>Merging conflicting changes</title>
198 <para id="x_34b">Most merges are simple affairs, but sometimes you'll find
199 yourself merging changes where each side modifies the same portions
200 of the same files. Unless both modifications are identical,
201 this results in a <emphasis>conflict</emphasis>, where you have
202 to decide how to reconcile the different changes into something
203 coherent.</para>
205 <figure id="fig:tour-merge:conflict">
206 <title>Conflicting changes to a document</title>
207 <mediaobject>
208 <imageobject><imagedata fileref="figs/tour-merge-conflict.png"/></imageobject>
209 <textobject><phrase>XXX add text</phrase></textobject>
210 </mediaobject>
211 </figure>
213 <para id="x_34d"><xref linkend="fig:tour-merge:conflict"/> illustrates
214 an instance of two conflicting changes to a document. We
215 started with a single version of the file; then we made some
216 changes; while someone else made different changes to the same
217 text. Our task in resolving the conflicting changes is to
218 decide what the file should look like.</para>
220 <para id="x_34e">Mercurial doesn't have a built-in facility for handling
221 conflicts. Instead, it runs an external program, usually one
222 that displays some kind of graphical conflict resolution
223 interface. By default, Mercurial tries to find one of several
224 different merging tools that are likely to be installed on your
225 system. It first tries a few fully automatic merging tools; if
226 these don't succeed (because the resolution process requires
227 human guidance) or aren't present, it tries a few
228 different graphical merging tools.</para>
230 <para id="x_34f">It's also possible to get Mercurial to run a
231 specific program or script, by setting the
232 <envar>HGMERGE</envar> environment variable to the name of your
233 preferred program.</para>
235 <sect2>
236 <title>Using a graphical merge tool</title>
238 <para id="x_350">My preferred graphical merge tool is
239 <command>kdiff3</command>, which I'll use to describe the
240 features that are common to graphical file merging tools. You
241 can see a screenshot of <command>kdiff3</command> in action in
242 <xref linkend="fig:tour-merge:kdiff3"/>. The kind of
243 merge it is performing is called a <emphasis>three-way
244 merge</emphasis>, because there are three different versions
245 of the file of interest to us. The tool thus splits the upper
246 portion of the window into three panes:</para>
247 <itemizedlist>
248 <listitem><para id="x_351">At the left is the <emphasis>base</emphasis>
249 version of the file, i.e. the most recent version from
250 which the two versions we're trying to merge are
251 descended.</para>
252 </listitem>
253 <listitem><para id="x_352">In the middle is <quote>our</quote> version of
254 the file, with the contents that we modified.</para>
255 </listitem>
256 <listitem><para id="x_353">On the right is <quote>their</quote> version
257 of the file, the one that from the changeset that we're
258 trying to merge with.</para>
259 </listitem></itemizedlist>
260 <para id="x_354">In the pane below these is the current
261 <emphasis>result</emphasis> of the merge. Our task is to
262 replace all of the red text, which indicates unresolved
263 conflicts, with some sensible merger of the
264 <quote>ours</quote> and <quote>theirs</quote> versions of the
265 file.</para>
267 <para id="x_355">All four of these panes are <emphasis>locked
268 together</emphasis>; if we scroll vertically or horizontally
269 in any of them, the others are updated to display the
270 corresponding sections of their respective files.</para>
272 <figure id="fig:tour-merge:kdiff3">
273 <title>Using <command>kdiff3</command> to merge versions of a
274 file</title>
275 <mediaobject>
276 <imageobject>
277 <imagedata width="100%" fileref="figs/kdiff3.png"/></imageobject>
278 <textobject>
279 <phrase>XXX add text</phrase>
280 </textobject>
281 </mediaobject>
282 </figure>
284 <para id="x_357">For each conflicting portion of the file, we can choose to
285 resolve the conflict using some combination of text from the
286 base version, ours, or theirs. We can also manually edit the
287 merged file at any time, in case we need to make further
288 modifications.</para>
290 <para id="x_358">There are <emphasis>many</emphasis> file merging tools
291 available, too many to cover here. They vary in which
292 platforms they are available for, and in their particular
293 strengths and weaknesses. Most are tuned for merging files
294 containing plain text, while a few are aimed at specialised
295 file formats (generally XML).</para>
296 </sect2>
298 <sect2>
299 <title>A worked example</title>
301 <para id="x_359">In this example, we will reproduce the file modification
302 history of <xref linkend="fig:tour-merge:conflict"/>
303 above. Let's begin by creating a repository with a base
304 version of our document.</para>
306 &interaction.tour-merge-conflict.wife;
308 <para id="x_35a">We'll clone the repository and make a change to the
309 file.</para>
311 &interaction.tour-merge-conflict.cousin;
313 <para id="x_35b">And another clone, to simulate someone else making a
314 change to the file. (This hints at the idea that it's not all
315 that unusual to merge with yourself when you isolate tasks in
316 separate repositories, and indeed to find and resolve
317 conflicts while doing so.)</para>
319 &interaction.tour-merge-conflict.son;
321 <para id="x_35c">Having created two
322 different versions of the file, we'll set up an environment
323 suitable for running our merge.</para>
325 &interaction.tour-merge-conflict.pull;
327 <para id="x_35d">In this example, I'll set
328 <envar>HGMERGE</envar> to tell Mercurial to use the
329 non-interactive <command>merge</command> command. This is
330 bundled with many Unix-like systems. (If you're following this
331 example on your computer, don't bother setting
332 <envar>HGMERGE</envar>. You'll get dropped into a GUI file
333 merge tool instead, which is much preferable.)</para>
335 &interaction.tour-merge-conflict.merge;
337 <para id="x_35f">Because <command>merge</command> can't resolve the
338 conflicting changes, it leaves <emphasis>merge
339 markers</emphasis> inside the file that has conflicts,
340 indicating which lines have conflicts, and whether they came
341 from our version of the file or theirs.</para>
343 <para id="x_360">Mercurial can tell from the way <command>merge</command>
344 exits that it wasn't able to merge successfully, so it tells
345 us what commands we'll need to run if we want to redo the
346 merging operation. This could be useful if, for example, we
347 were running a graphical merge tool and quit because we were
348 confused or realised we had made a mistake.</para>
350 <para id="x_361">If automatic or manual merges fail, there's nothing to
351 prevent us from <quote>fixing up</quote> the affected files
352 ourselves, and committing the results of our merge:</para>
354 &interaction.tour-merge-conflict.commit;
356 <note>
357 <title>Where is the <command>hg resolve</command> command?</title>
359 <para id="x_724">The <command>hg resolve</command> command was introduced
360 in Mercurial 1.1, which was released in December 2008. If
361 you are using an older version of Mercurial (run <command>hg
362 version</command> to see), this command will not be
363 present. If your version of Mercurial is older than 1.1,
364 you should strongly consider upgrading to a newer version
365 before trying to tackle complicated merges.</para>
366 </note>
367 </sect2>
368 </sect1>
370 <sect1 id="sec:tour-merge:fetch">
371 <title>Simplifying the pull-merge-commit sequence</title>
373 <para id="x_362">The process of merging changes as outlined above is
374 straightforward, but requires running three commands in
375 sequence.</para>
376 <programlisting>hg pull -u
377 hg merge
378 hg commit -m 'Merged remote changes'</programlisting>
379 <para id="x_363">In the case of the final commit, you also need to enter a
380 commit message, which is almost always going to be a piece of
381 uninteresting <quote>boilerplate</quote> text.</para>
383 <para id="x_364">It would be nice to reduce the number of steps needed, if
384 this were possible. Indeed, Mercurial is distributed with an
385 extension called <literal role="hg-ext">fetch</literal> that
386 does just this.</para>
388 <para id="x_365">Mercurial provides a flexible extension mechanism that lets
389 people extend its functionality, while keeping the core of
390 Mercurial small and easy to deal with. Some extensions add new
391 commands that you can use from the command line, while others
392 work <quote>behind the scenes,</quote> for example adding
393 capabilities to Mercurial's built-in server mode.</para>
395 <para id="x_366">The <literal role="hg-ext">fetch</literal>
396 extension adds a new command called, not surprisingly, <command
397 role="hg-cmd">hg fetch</command>. This extension acts as a
398 combination of <command role="hg-cmd">hg pull -u</command>,
399 <command role="hg-cmd">hg merge</command> and <command
400 role="hg-cmd">hg commit</command>. It begins by pulling
401 changes from another repository into the current repository. If
402 it finds that the changes added a new head to the repository, it
403 updates to the new head, begins a merge, then (if the merge
404 succeeded) commits the result of the merge with an
405 automatically-generated commit message. If no new heads were
406 added, it updates the working directory to the new tip
407 changeset.</para>
409 <para id="x_367">Enabling the <literal
410 role="hg-ext">fetch</literal> extension is easy. Edit the
411 <filename role="special">.hgrc</filename> file in your home
412 directory, and either go to the <literal
413 role="rc-extensions">extensions</literal> section or create an
414 <literal role="rc-extensions">extensions</literal> section. Then
415 add a line that simply reads
416 <quote><literal>fetch=</literal></quote>.</para>
418 <programlisting>[extensions]
419 fetch =</programlisting>
421 <para id="x_368">(Normally, the right-hand side of the
422 <quote><literal>=</literal></quote> would indicate where to find
423 the extension, but since the <literal
424 role="hg-ext">fetch</literal> extension is in the standard
425 distribution, Mercurial knows where to search for it.)</para>
426 </sect1>
428 <sect1>
429 <title>Renaming, copying, and merging</title>
431 <para id="x_729">During the life of a project, we will often want to change
432 the layout of its files and directories. This can be as simple
433 as renaming a single file, or as complex as restructuring the
434 entire hierarchy of files within the project.</para>
436 <para id="x_72a">Mercurial supports these kinds of complex changes fluently,
437 provided we tell it what we're doing. If we want to rename a
438 file, we should use the <command>hg rename</command><footnote>
439 <para id="x_72b">If you're a Unix user, you'll be glad to know that the
440 <command>hg rename</command> command can be abbreviated as
441 <command>hg mv</command>.</para>
442 </footnote> command to rename it, so that Mercurial can do the
443 right thing later when we merge.</para>
445 <para id="x_72c">We will cover the use of these commands in more detail in
446 <xref linkend="chap:daily.copy"/>.</para>
447 </sect1>
448 </chapter>
450 <!--
451 local variables:
452 sgml-parent-document: ("00book.xml" "book" "chapter")
453 end:
454 -->