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@619
|
149 <sect2>
|
bos@619
|
150 <title>Committing the results of the merge</title>
|
bos@619
|
151
|
bos@619
|
152 <para id="x_348">Whenever we've done a merge, <command role="hg-cmd">hg
|
bos@619
|
153 parents</command> will display two parents until we <command
|
bos@619
|
154 role="hg-cmd">hg commit</command> the results of the
|
bos@619
|
155 merge.</para>
|
bos@619
|
156
|
bos@619
|
157 &interaction.tour.merge.commit;
|
bos@619
|
158
|
bos@619
|
159 <para id="x_349">We now have a new tip revision; notice that it has
|
bos@619
|
160 <emphasis>both</emphasis> of our former heads as its parents.
|
bos@619
|
161 These are the same revisions that were previously displayed by
|
bos@619
|
162 <command role="hg-cmd">hg parents</command>.</para>
|
bos@619
|
163
|
bos@619
|
164 &interaction.tour.merge.tip;
|
bos@619
|
165
|
bos@619
|
166 <para id="x_34a">In <xref
|
bos@619
|
167 linkend="fig:tour-merge:merge"/>, you can see a
|
bos@619
|
168 representation of what happens to the working directory during
|
bos@619
|
169 the merge, and how this affects the repository when the commit
|
bos@619
|
170 happens. During the merge, the working directory has two
|
bos@619
|
171 parent changesets, and these become the parents of the new
|
bos@619
|
172 changeset.</para>
|
bos@619
|
173
|
bos@591
|
174 <figure id="fig:tour-merge:merge">
|
bos@591
|
175 <title>Working directory and repository during merge, and
|
bos@591
|
176 following commit</title>
|
bos@591
|
177 <mediaobject>
|
bos@591
|
178 <imageobject>
|
bos@594
|
179 <imagedata fileref="figs/tour-merge-merge.png"/>
|
bos@591
|
180 </imageobject>
|
bos@591
|
181 <textobject><phrase>XXX add text</phrase></textobject>
|
bos@559
|
182 </mediaobject>
|
bos@591
|
183 </figure>
|
bos@559
|
184
|
bos@676
|
185 <para id="x_69c">We sometimes talk about a merge having
|
bos@619
|
186 <emphasis>sides</emphasis>: the left side is the first parent
|
bos@670
|
187 in the output of <command role="hg-cmd">hg parents</command>,
|
bos@619
|
188 and the right side is the second. If the working directory
|
bos@619
|
189 was at e.g. revision 5 before we began a merge, that revision
|
bos@619
|
190 will become the left side of the merge.</para>
|
bos@559
|
191 </sect2>
|
bos@559
|
192 </sect1>
|
bos@619
|
193
|
bos@559
|
194 <sect1>
|
bos@559
|
195 <title>Merging conflicting changes</title>
|
bos@559
|
196
|
bos@584
|
197 <para id="x_34b">Most merges are simple affairs, but sometimes you'll find
|
bos@619
|
198 yourself merging changes where each side modifies the same portions
|
bos@559
|
199 of the same files. Unless both modifications are identical,
|
bos@559
|
200 this results in a <emphasis>conflict</emphasis>, where you have
|
bos@559
|
201 to decide how to reconcile the different changes into something
|
bos@559
|
202 coherent.</para>
|
bos@559
|
203
|
bos@591
|
204 <figure id="fig:tour-merge:conflict">
|
bos@591
|
205 <title>Conflicting changes to a document</title>
|
bos@591
|
206 <mediaobject>
|
bos@594
|
207 <imageobject><imagedata fileref="figs/tour-merge-conflict.png"/></imageobject>
|
bos@559
|
208 <textobject><phrase>XXX add text</phrase></textobject>
|
bos@591
|
209 </mediaobject>
|
bos@591
|
210 </figure>
|
bos@559
|
211
|
bos@592
|
212 <para id="x_34d"><xref linkend="fig:tour-merge:conflict"/> illustrates
|
bos@559
|
213 an instance of two conflicting changes to a document. We
|
bos@559
|
214 started with a single version of the file; then we made some
|
bos@559
|
215 changes; while someone else made different changes to the same
|
bos@559
|
216 text. Our task in resolving the conflicting changes is to
|
bos@559
|
217 decide what the file should look like.</para>
|
bos@559
|
218
|
bos@584
|
219 <para id="x_34e">Mercurial doesn't have a built-in facility for handling
|
bos@619
|
220 conflicts. Instead, it runs an external program, usually one
|
bos@619
|
221 that displays some kind of graphical conflict resolution
|
bos@619
|
222 interface. By default, Mercurial tries to find one of several
|
bos@559
|
223 different merging tools that are likely to be installed on your
|
bos@559
|
224 system. It first tries a few fully automatic merging tools; if
|
bos@559
|
225 these don't succeed (because the resolution process requires
|
bos@619
|
226 human guidance) or aren't present, it tries a few
|
bos@559
|
227 different graphical merging tools.</para>
|
bos@559
|
228
|
bos@699
|
229 <para id="x_34f">It's also possible to get Mercurial to run a
|
bos@699
|
230 specific program or script, by setting the
|
bos@559
|
231 <envar>HGMERGE</envar> environment variable to the name of your
|
bos@559
|
232 preferred program.</para>
|
bos@559
|
233
|
bos@559
|
234 <sect2>
|
bos@559
|
235 <title>Using a graphical merge tool</title>
|
bos@559
|
236
|
bos@584
|
237 <para id="x_350">My preferred graphical merge tool is
|
bos@559
|
238 <command>kdiff3</command>, which I'll use to describe the
|
bos@559
|
239 features that are common to graphical file merging tools. You
|
bos@559
|
240 can see a screenshot of <command>kdiff3</command> in action in
|
bos@592
|
241 <xref linkend="fig:tour-merge:kdiff3"/>. The kind of
|
bos@559
|
242 merge it is performing is called a <emphasis>three-way
|
bos@559
|
243 merge</emphasis>, because there are three different versions
|
bos@559
|
244 of the file of interest to us. The tool thus splits the upper
|
bos@559
|
245 portion of the window into three panes:</para>
|
bos@559
|
246 <itemizedlist>
|
bos@584
|
247 <listitem><para id="x_351">At the left is the <emphasis>base</emphasis>
|
bos@559
|
248 version of the file, i.e. the most recent version from
|
bos@559
|
249 which the two versions we're trying to merge are
|
bos@559
|
250 descended.</para>
|
bos@559
|
251 </listitem>
|
bos@584
|
252 <listitem><para id="x_352">In the middle is <quote>our</quote> version of
|
bos@559
|
253 the file, with the contents that we modified.</para>
|
bos@559
|
254 </listitem>
|
bos@584
|
255 <listitem><para id="x_353">On the right is <quote>their</quote> version
|
bos@559
|
256 of the file, the one that from the changeset that we're
|
bos@559
|
257 trying to merge with.</para>
|
bos@559
|
258 </listitem></itemizedlist>
|
bos@584
|
259 <para id="x_354">In the pane below these is the current
|
bos@559
|
260 <emphasis>result</emphasis> of the merge. Our task is to
|
bos@559
|
261 replace all of the red text, which indicates unresolved
|
bos@559
|
262 conflicts, with some sensible merger of the
|
bos@559
|
263 <quote>ours</quote> and <quote>theirs</quote> versions of the
|
bos@559
|
264 file.</para>
|
bos@559
|
265
|
bos@584
|
266 <para id="x_355">All four of these panes are <emphasis>locked
|
bos@559
|
267 together</emphasis>; if we scroll vertically or horizontally
|
bos@559
|
268 in any of them, the others are updated to display the
|
bos@559
|
269 corresponding sections of their respective files.</para>
|
bos@559
|
270
|
bos@591
|
271 <figure id="fig:tour-merge:kdiff3">
|
bos@591
|
272 <title>Using <command>kdiff3</command> to merge versions of a
|
bos@591
|
273 file</title>
|
bos@591
|
274 <mediaobject>
|
bos@591
|
275 <imageobject>
|
dongsheng@655
|
276 <imagedata width="100%" fileref="figs/kdiff3.png"/></imageobject>
|
bos@591
|
277 <textobject>
|
bos@591
|
278 <phrase>XXX add text</phrase>
|
bos@591
|
279 </textobject>
|
bos@559
|
280 </mediaobject>
|
bos@591
|
281 </figure>
|
bos@559
|
282
|
bos@584
|
283 <para id="x_357">For each conflicting portion of the file, we can choose to
|
bos@559
|
284 resolve the conflict using some combination of text from the
|
bos@559
|
285 base version, ours, or theirs. We can also manually edit the
|
bos@559
|
286 merged file at any time, in case we need to make further
|
bos@559
|
287 modifications.</para>
|
bos@559
|
288
|
bos@584
|
289 <para id="x_358">There are <emphasis>many</emphasis> file merging tools
|
bos@559
|
290 available, too many to cover here. They vary in which
|
bos@559
|
291 platforms they are available for, and in their particular
|
bos@559
|
292 strengths and weaknesses. Most are tuned for merging files
|
bos@559
|
293 containing plain text, while a few are aimed at specialised
|
bos@559
|
294 file formats (generally XML).</para>
|
bos@559
|
295
|
bos@559
|
296 </sect2>
|
bos@559
|
297 <sect2>
|
bos@559
|
298 <title>A worked example</title>
|
bos@559
|
299
|
bos@584
|
300 <para id="x_359">In this example, we will reproduce the file modification
|
bos@592
|
301 history of <xref linkend="fig:tour-merge:conflict"/>
|
bos@559
|
302 above. Let's begin by creating a repository with a base
|
bos@559
|
303 version of our document.</para>
|
bos@559
|
304
|
bos@567
|
305 &interaction.tour-merge-conflict.wife;
|
bos@559
|
306
|
bos@584
|
307 <para id="x_35a">We'll clone the repository and make a change to the
|
bos@559
|
308 file.</para>
|
bos@559
|
309
|
bos@567
|
310 &interaction.tour-merge-conflict.cousin;
|
bos@559
|
311
|
bos@584
|
312 <para id="x_35b">And another clone, to simulate someone else making a
|
bos@559
|
313 change to the file. (This hints at the idea that it's not all
|
bos@559
|
314 that unusual to merge with yourself when you isolate tasks in
|
bos@559
|
315 separate repositories, and indeed to find and resolve
|
bos@559
|
316 conflicts while doing so.)</para>
|
bos@559
|
317
|
bos@567
|
318 &interaction.tour-merge-conflict.son;
|
bos@559
|
319
|
bos@584
|
320 <para id="x_35c">Having created two
|
bos@559
|
321 different versions of the file, we'll set up an environment
|
bos@559
|
322 suitable for running our merge.</para>
|
bos@559
|
323
|
bos@567
|
324 &interaction.tour-merge-conflict.pull;
|
bos@559
|
325
|
bos@619
|
326 <para id="x_35d">In this example, I'll set
|
bos@559
|
327 <envar>HGMERGE</envar> to tell Mercurial to use the
|
bos@559
|
328 non-interactive <command>merge</command> command. This is
|
bos@619
|
329 bundled with many Unix-like systems. (If you're following this
|
bos@559
|
330 example on your computer, don't bother setting
|
bos@699
|
331 <envar>HGMERGE</envar>. You'll get dropped into a GUI file
|
bos@699
|
332 merge tool instead, which is much preferable.)</para>
|
bos@559
|
333
|
bos@567
|
334 &interaction.tour-merge-conflict.merge;
|
bos@559
|
335
|
bos@584
|
336 <para id="x_35f">Because <command>merge</command> can't resolve the
|
bos@559
|
337 conflicting changes, it leaves <emphasis>merge
|
bos@559
|
338 markers</emphasis> inside the file that has conflicts,
|
bos@559
|
339 indicating which lines have conflicts, and whether they came
|
bos@559
|
340 from our version of the file or theirs.</para>
|
bos@559
|
341
|
bos@584
|
342 <para id="x_360">Mercurial can tell from the way <command>merge</command>
|
bos@559
|
343 exits that it wasn't able to merge successfully, so it tells
|
bos@559
|
344 us what commands we'll need to run if we want to redo the
|
bos@559
|
345 merging operation. This could be useful if, for example, we
|
bos@559
|
346 were running a graphical merge tool and quit because we were
|
bos@559
|
347 confused or realised we had made a mistake.</para>
|
bos@559
|
348
|
bos@584
|
349 <para id="x_361">If automatic or manual merges fail, there's nothing to
|
bos@559
|
350 prevent us from <quote>fixing up</quote> the affected files
|
bos@559
|
351 ourselves, and committing the results of our merge:</para>
|
bos@559
|
352
|
bos@567
|
353 &interaction.tour-merge-conflict.commit;
|
bos@559
|
354
|
bos@699
|
355 <note>
|
bos@699
|
356 <title>Where is the <command>hg resolve</command> command?</title>
|
bos@699
|
357
|
bos@700
|
358 <para id="x_724">The <command>hg resolve</command> command was introduced
|
bos@699
|
359 in Mercurial 1.1, which was released in December 2008. If
|
bos@699
|
360 you are using an older version of Mercurial (run <command>hg
|
bos@699
|
361 version</command> to see), this command will not be
|
bos@699
|
362 present. If your version of Mercurial is older than 1.1,
|
bos@699
|
363 you should strongly consider upgrading to a newer version
|
bos@699
|
364 before trying to tackle complicated merges.</para>
|
bos@699
|
365 </note>
|
bos@559
|
366 </sect2>
|
bos@559
|
367 </sect1>
|
bos@559
|
368 <sect1 id="sec:tour-merge:fetch">
|
bos@559
|
369 <title>Simplifying the pull-merge-commit sequence</title>
|
bos@559
|
370
|
bos@584
|
371 <para id="x_362">The process of merging changes as outlined above is
|
bos@559
|
372 straightforward, but requires running three commands in
|
bos@559
|
373 sequence.</para>
|
bos@619
|
374 <programlisting>hg pull -u
|
bos@579
|
375 hg merge
|
bos@579
|
376 hg commit -m 'Merged remote changes'</programlisting>
|
bos@584
|
377 <para id="x_363">In the case of the final commit, you also need to enter a
|
bos@559
|
378 commit message, which is almost always going to be a piece of
|
bos@559
|
379 uninteresting <quote>boilerplate</quote> text.</para>
|
bos@559
|
380
|
bos@584
|
381 <para id="x_364">It would be nice to reduce the number of steps needed, if
|
bos@559
|
382 this were possible. Indeed, Mercurial is distributed with an
|
bos@559
|
383 extension called <literal role="hg-ext">fetch</literal> that
|
bos@559
|
384 does just this.</para>
|
bos@559
|
385
|
bos@584
|
386 <para id="x_365">Mercurial provides a flexible extension mechanism that lets
|
bos@559
|
387 people extend its functionality, while keeping the core of
|
bos@559
|
388 Mercurial small and easy to deal with. Some extensions add new
|
bos@559
|
389 commands that you can use from the command line, while others
|
bos@559
|
390 work <quote>behind the scenes,</quote> for example adding
|
bos@699
|
391 capabilities to Mercurial's built-in server mode.</para>
|
bos@559
|
392
|
bos@619
|
393 <para id="x_366">The <literal role="hg-ext">fetch</literal>
|
bos@619
|
394 extension adds a new command called, not surprisingly, <command
|
bos@619
|
395 role="hg-cmd">hg fetch</command>. This extension acts as a
|
bos@619
|
396 combination of <command role="hg-cmd">hg pull -u</command>,
|
bos@619
|
397 <command role="hg-cmd">hg merge</command> and <command
|
bos@619
|
398 role="hg-cmd">hg commit</command>. It begins by pulling
|
bos@559
|
399 changes from another repository into the current repository. If
|
bos@559
|
400 it finds that the changes added a new head to the repository, it
|
bos@699
|
401 updates to the new head, begins a merge, then (if the merge
|
bos@699
|
402 succeeded) commits the result of the merge with an
|
bos@699
|
403 automatically-generated commit message. If no new heads were
|
bos@699
|
404 added, it updates the working directory to the new tip
|
bos@699
|
405 changeset.</para>
|
bos@619
|
406
|
bos@619
|
407 <para id="x_367">Enabling the <literal
|
bos@619
|
408 role="hg-ext">fetch</literal> extension is easy. Edit the
|
bos@619
|
409 <filename role="special">.hgrc</filename> file in your home
|
bos@619
|
410 directory, and either go to the <literal
|
bos@559
|
411 role="rc-extensions">extensions</literal> section or create an
|
bos@559
|
412 <literal role="rc-extensions">extensions</literal> section. Then
|
bos@619
|
413 add a line that simply reads
|
bos@619
|
414 <quote><literal>fetch=</literal></quote>.</para>
|
bos@619
|
415
|
bos@579
|
416 <programlisting>[extensions]
|
bos@579
|
417 fetch =</programlisting>
|
bos@619
|
418
|
bos@619
|
419 <para id="x_368">(Normally, the right-hand side of the
|
bos@619
|
420 <quote><literal>=</literal></quote> would indicate where to find
|
bos@559
|
421 the extension, but since the <literal
|
bos@559
|
422 role="hg-ext">fetch</literal> extension is in the standard
|
bos@559
|
423 distribution, Mercurial knows where to search for it.)</para>
|
bos@559
|
424
|
bos@559
|
425 </sect1>
|
bos@559
|
426 </chapter>
|
bos@559
|
427
|
bos@559
|
428 <!--
|
bos@559
|
429 local variables:
|
bos@559
|
430 sgml-parent-document: ("00book.xml" "book" "chapter")
|
bos@559
|
431 end:
|
bos@559
|
432 -->
|