hgbook

annotate en/ch03-tour-merge.xml @ 893:40e41b3eeaf6

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