hgbook

view en/ch05-daily.xml @ 567:8fcd44708f41

Uncomment all the mangled interaction examples.
author Bryan O'Sullivan <bos@serpentine.com>
date Mon Mar 09 23:22:09 2009 -0700 (2009-03-09)
parents b90b024729f1
children 13513d2a128d
line source
1 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
3 <chapter id="chap:daily">
4 <title>Mercurial in daily use</title>
6 <sect1>
7 <title>Telling Mercurial which files to track</title>
9 <para>Mercurial does not work with files in your repository unless
10 you tell it to manage them. The <command role="hg-cmd">hg
11 status</command> command will tell you which files Mercurial
12 doesn't know about; it uses a
13 <quote><literal>?</literal></quote> to display such
14 files.</para>
16 <para>To tell Mercurial to track a file, use the <command
17 role="hg-cmd">hg add</command> command. Once you have added a
18 file, the entry in the output of <command role="hg-cmd">hg
19 status</command> for that file changes from
20 <quote><literal>?</literal></quote> to
21 <quote><literal>A</literal></quote>.</para>
23 &interaction.daily.files.add;
25 <para>After you run a <command role="hg-cmd">hg commit</command>,
26 the files that you added before the commit will no longer be
27 listed in the output of <command role="hg-cmd">hg
28 status</command>. The reason for this is that <command
29 role="hg-cmd">hg status</command> only tells you about
30 <quote>interesting</quote> files&emdash;those that you have
31 modified or told Mercurial to do something with&emdash;by
32 default. If you have a repository that contains thousands of
33 files, you will rarely want to know about files that Mercurial
34 is tracking, but that have not changed. (You can still get this
35 information; we'll return to this later.)</para>
37 <para>Once you add a file, Mercurial doesn't do anything with it
38 immediately. Instead, it will take a snapshot of the file's
39 state the next time you perform a commit. It will then continue
40 to track the changes you make to the file every time you commit,
41 until you remove the file.</para>
43 <sect2>
44 <title>Explicit versus implicit file naming</title>
46 <para>A useful behaviour that Mercurial has is that if you pass
47 the name of a directory to a command, every Mercurial command
48 will treat this as <quote>I want to operate on every file in
49 this directory and its subdirectories</quote>.</para>
51 &interaction.daily.files.add-dir;
53 <para>Notice in this example that Mercurial printed the names of
54 the files it added, whereas it didn't do so when we added the
55 file named <filename>a</filename> in the earlier
56 example.</para>
58 <para>What's going on is that in the former case, we explicitly
59 named the file to add on the command line, so the assumption
60 that Mercurial makes in such cases is that you know what you
61 were doing, and it doesn't print any output.</para>
63 <para>However, when we <emphasis>imply</emphasis> the names of
64 files by giving the name of a directory, Mercurial takes the
65 extra step of printing the name of each file that it does
66 something with. This makes it more clear what is happening,
67 and reduces the likelihood of a silent and nasty surprise.
68 This behaviour is common to most Mercurial commands.</para>
70 </sect2>
71 <sect2>
72 <title>Aside: Mercurial tracks files, not directories</title>
74 <para>Mercurial does not track directory information. Instead,
75 it tracks the path to a file. Before creating a file, it
76 first creates any missing directory components of the path.
77 After it deletes a file, it then deletes any empty directories
78 that were in the deleted file's path. This sounds like a
79 trivial distinction, but it has one minor practical
80 consequence: it is not possible to represent a completely
81 empty directory in Mercurial.</para>
83 <para>Empty directories are rarely useful, and there are
84 unintrusive workarounds that you can use to achieve an
85 appropriate effect. The developers of Mercurial thus felt
86 that the complexity that would be required to manage empty
87 directories was not worth the limited benefit this feature
88 would bring.</para>
90 <para>If you need an empty directory in your repository, there
91 are a few ways to achieve this. One is to create a directory,
92 then <command role="hg-cmd">hg add</command> a
93 <quote>hidden</quote> file to that directory. On Unix-like
94 systems, any file name that begins with a period
95 (<quote><literal>.</literal></quote>) is treated as hidden by
96 most commands and GUI tools. This approach is illustrated
97 below.</para>
99 &interaction.daily.files.hidden;
101 <para>Another way to tackle a need for an empty directory is to
102 simply create one in your automated build scripts before they
103 will need it.</para>
105 </sect2>
106 </sect1>
107 <sect1>
108 <title>How to stop tracking a file</title>
110 <para>Once you decide that a file no longer belongs in your
111 repository, use the <command role="hg-cmd">hg remove</command>
112 command; this deletes the file, and tells Mercurial to stop
113 tracking it. A removed file is represented in the output of
114 <command role="hg-cmd">hg status</command> with a
115 <quote><literal>R</literal></quote>.</para>
117 &interaction.daily.files.remove;
119 <para>After you <command role="hg-cmd">hg remove</command> a file,
120 Mercurial will no longer track changes to that file, even if you
121 recreate a file with the same name in your working directory.
122 If you do recreate a file with the same name and want Mercurial
123 to track the new file, simply <command role="hg-cmd">hg
124 add</command> it. Mercurial will know that the newly added
125 file is not related to the old file of the same name.</para>
127 <sect2>
128 <title>Removing a file does not affect its history</title>
130 <para>It is important to understand that removing a file has
131 only two effects.</para>
132 <itemizedlist>
133 <listitem><para>It removes the current version of the file
134 from the working directory.</para>
135 </listitem>
136 <listitem><para>It stops Mercurial from tracking changes to
137 the file, from the time of the next commit.</para>
138 </listitem></itemizedlist>
139 <para>Removing a file <emphasis>does not</emphasis> in any way
140 alter the <emphasis>history</emphasis> of the file.</para>
142 <para>If you update the working directory to a changeset in
143 which a file that you have removed was still tracked, it will
144 reappear in the working directory, with the contents it had
145 when you committed that changeset. If you then update the
146 working directory to a later changeset, in which the file had
147 been removed, Mercurial will once again remove the file from
148 the working directory.</para>
150 </sect2>
151 <sect2>
152 <title>Missing files</title>
154 <para>Mercurial considers a file that you have deleted, but not
155 used <command role="hg-cmd">hg remove</command> to delete, to
156 be <emphasis>missing</emphasis>. A missing file is
157 represented with <quote><literal>!</literal></quote> in the
158 output of <command role="hg-cmd">hg status</command>.
159 Mercurial commands will not generally do anything with missing
160 files.</para>
162 &interaction.daily.files.missing;
164 <para>If your repository contains a file that <command
165 role="hg-cmd">hg status</command> reports as missing, and
166 you want the file to stay gone, you can run <command
167 role="hg-cmd">hg remove <option
168 role="hg-opt-remove">--after</option></command> at any
169 time later on, to tell Mercurial that you really did mean to
170 remove the file.</para>
172 &interaction.daily.files.remove-after;
174 <para>On the other hand, if you deleted the missing file by
175 accident, give <command role="hg-cmd">hg revert</command> the
176 name of the file to recover. It will reappear, in unmodified
177 form.</para>
179 &interaction.daily.files.recover-missing;
181 </sect2>
182 <sect2>
183 <title>Aside: why tell Mercurial explicitly to remove a
184 file?</title>
186 <para>You might wonder why Mercurial requires you to explicitly
187 tell it that you are deleting a file. Early during the
188 development of Mercurial, it let you delete a file however you
189 pleased; Mercurial would notice the absence of the file
190 automatically when you next ran a <command role="hg-cmd">hg
191 commit</command>, and stop tracking the file. In practice,
192 this made it too easy to accidentally remove a file without
193 noticing.</para>
195 </sect2>
196 <sect2>
197 <title>Useful shorthand&emdash;adding and removing files in one
198 step</title>
200 <para>Mercurial offers a combination command, <command
201 role="hg-cmd">hg addremove</command>, that adds untracked
202 files and marks missing files as removed.</para>
204 &interaction.daily.files.addremove;
206 <para>The <command role="hg-cmd">hg commit</command> command
207 also provides a <option role="hg-opt-commit">-A</option>
208 option that performs this same add-and-remove, immediately
209 followed by a commit.</para>
211 &interaction.daily.files.commit-addremove;
213 </sect2>
214 </sect1>
215 <sect1>
216 <title>Copying files</title>
218 <para>Mercurial provides a <command role="hg-cmd">hg
219 copy</command> command that lets you make a new copy of a
220 file. When you copy a file using this command, Mercurial makes
221 a record of the fact that the new file is a copy of the original
222 file. It treats these copied files specially when you merge
223 your work with someone else's.</para>
225 <sect2>
226 <title>The results of copying during a merge</title>
228 <para>What happens during a merge is that changes
229 <quote>follow</quote> a copy. To best illustrate what this
230 means, let's create an example. We'll start with the usual
231 tiny repository that contains a single file.</para>
233 &interaction.daily.copy.init;
235 <para>We need to do some work in
236 parallel, so that we'll have something to merge. So let's
237 clone our repository.</para>
239 &interaction.daily.copy.clone;
241 <para>Back in our initial repository, let's use the <command
242 role="hg-cmd">hg copy</command> command to make a copy of
243 the first file we created.</para>
245 &interaction.daily.copy.copy;
247 <para>If we look at the output of the <command role="hg-cmd">hg
248 status</command> command afterwards, the copied file looks
249 just like a normal added file.</para>
251 &interaction.daily.copy.status;
253 <para>But if we pass the <option
254 role="hg-opt-status">-C</option> option to <command
255 role="hg-cmd">hg status</command>, it prints another line of
256 output: this is the file that our newly-added file was copied
257 <emphasis>from</emphasis>.</para>
259 &interaction.daily.copy.status-copy;
261 <para>Now, back in the repository we cloned, let's make a change
262 in parallel. We'll add a line of content to the original file
263 that we created.</para>
265 &interaction.daily.copy.other;
267 <para>Now we have a modified <filename>file</filename> in this
268 repository. When we pull the changes from the first
269 repository, and merge the two heads, Mercurial will propagate
270 the changes that we made locally to <filename>file</filename>
271 into its copy, <filename>new-file</filename>.</para>
273 &interaction.daily.copy.merge;
275 </sect2>
276 <sect2 id="sec:daily:why-copy">
277 <title>Why should changes follow copies?</title>
279 <para>This behaviour, of changes to a file propagating out to
280 copies of the file, might seem esoteric, but in most cases
281 it's highly desirable.</para>
283 <para>First of all, remember that this propagation
284 <emphasis>only</emphasis> happens when you merge. So if you
285 <command role="hg-cmd">hg copy</command> a file, and
286 subsequently modify the original file during the normal course
287 of your work, nothing will happen.</para>
289 <para>The second thing to know is that modifications will only
290 propagate across a copy as long as the repository that you're
291 pulling changes from <emphasis>doesn't know</emphasis> about
292 the copy.</para>
294 <para>The reason that Mercurial does this is as follows. Let's
295 say I make an important bug fix in a source file, and commit
296 my changes. Meanwhile, you've decided to <command
297 role="hg-cmd">hg copy</command> the file in your repository,
298 without knowing about the bug or having seen the fix, and you
299 have started hacking on your copy of the file.</para>
301 <para>If you pulled and merged my changes, and Mercurial
302 <emphasis>didn't</emphasis> propagate changes across copies,
303 your source file would now contain the bug, and unless you
304 remembered to propagate the bug fix by hand, the bug would
305 <emphasis>remain</emphasis> in your copy of the file.</para>
307 <para>By automatically propagating the change that fixed the bug
308 from the original file to the copy, Mercurial prevents this
309 class of problem. To my knowledge, Mercurial is the
310 <emphasis>only</emphasis> revision control system that
311 propagates changes across copies like this.</para>
313 <para>Once your change history has a record that the copy and
314 subsequent merge occurred, there's usually no further need to
315 propagate changes from the original file to the copied file,
316 and that's why Mercurial only propagates changes across copies
317 until this point, and no further.</para>
319 </sect2>
320 <sect2>
321 <title>How to make changes <emphasis>not</emphasis> follow a
322 copy</title>
324 <para>If, for some reason, you decide that this business of
325 automatically propagating changes across copies is not for
326 you, simply use your system's normal file copy command (on
327 Unix-like systems, that's <command>cp</command>) to make a
328 copy of a file, then <command role="hg-cmd">hg add</command>
329 the new copy by hand. Before you do so, though, please do
330 reread section <xref linkend="sec:daily:why-copy"/>, and make
331 an informed
332 decision that this behaviour is not appropriate to your
333 specific case.</para>
335 </sect2>
336 <sect2>
337 <title>Behaviour of the <command role="hg-cmd">hg copy</command>
338 command</title>
340 <para>When you use the <command role="hg-cmd">hg copy</command>
341 command, Mercurial makes a copy of each source file as it
342 currently stands in the working directory. This means that if
343 you make some modifications to a file, then <command
344 role="hg-cmd">hg copy</command> it without first having
345 committed those changes, the new copy will also contain the
346 modifications you have made up until that point. (I find this
347 behaviour a little counterintuitive, which is why I mention it
348 here.)</para>
350 <para>The <command role="hg-cmd">hg copy</command> command acts
351 similarly to the Unix <command>cp</command> command (you can
352 use the <command role="hg-cmd">hg cp</command> alias if you
353 prefer). The last argument is the
354 <emphasis>destination</emphasis>, and all prior arguments are
355 <emphasis>sources</emphasis>. If you pass it a single file as
356 the source, and the destination does not exist, it creates a
357 new file with that name.</para>
359 &interaction.daily.copy.simple;
361 <para>If the destination is a directory, Mercurial copies its
362 sources into that directory.</para>
364 &interaction.daily.copy.dir-dest;
366 <para>Copying a directory is
367 recursive, and preserves the directory structure of the
368 source.</para>
370 &interaction.daily.copy.dir-src;
372 <para>If the source and destination are both directories, the
373 source tree is recreated in the destination directory.</para>
375 &interaction.daily.copy.dir-src-dest;
377 <para>As with the <command role="hg-cmd">hg rename</command>
378 command, if you copy a file manually and then want Mercurial
379 to know that you've copied the file, simply use the <option
380 role="hg-opt-copy">--after</option> option to <command
381 role="hg-cmd">hg copy</command>.</para>
383 &interaction.daily.copy.after;
385 </sect2>
386 </sect1>
387 <sect1>
388 <title>Renaming files</title>
390 <para>It's rather more common to need to rename a file than to
391 make a copy of it. The reason I discussed the <command
392 role="hg-cmd">hg copy</command> command before talking about
393 renaming files is that Mercurial treats a rename in essentially
394 the same way as a copy. Therefore, knowing what Mercurial does
395 when you copy a file tells you what to expect when you rename a
396 file.</para>
398 <para>When you use the <command role="hg-cmd">hg rename</command>
399 command, Mercurial makes a copy of each source file, then
400 deletes it and marks the file as removed.</para>
402 &interaction.daily.rename.rename;
404 <para>The <command role="hg-cmd">hg status</command> command shows
405 the newly copied file as added, and the copied-from file as
406 removed.</para>
408 &interaction.daily.rename.status;
410 <para>As with the results of a <command role="hg-cmd">hg
411 copy</command>, we must use the <option
412 role="hg-opt-status">-C</option> option to <command
413 role="hg-cmd">hg status</command> to see that the added file
414 is really being tracked by Mercurial as a copy of the original,
415 now removed, file.</para>
417 &interaction.daily.rename.status-copy;
419 <para>As with <command role="hg-cmd">hg remove</command> and
420 <command role="hg-cmd">hg copy</command>, you can tell Mercurial
421 about a rename after the fact using the <option
422 role="hg-opt-rename">--after</option> option. In most other
423 respects, the behaviour of the <command role="hg-cmd">hg
424 rename</command> command, and the options it accepts, are
425 similar to the <command role="hg-cmd">hg copy</command>
426 command.</para>
428 <sect2>
429 <title>Renaming files and merging changes</title>
431 <para>Since Mercurial's rename is implemented as
432 copy-and-remove, the same propagation of changes happens when
433 you merge after a rename as after a copy.</para>
435 <para>If I modify a file, and you rename it to a new name, and
436 then we merge our respective changes, my modifications to the
437 file under its original name will be propagated into the file
438 under its new name. (This is something you might expect to
439 <quote>simply work,</quote> but not all revision control
440 systems actually do this.)</para>
442 <para>Whereas having changes follow a copy is a feature where
443 you can perhaps nod and say <quote>yes, that might be
444 useful,</quote> it should be clear that having them follow a
445 rename is definitely important. Without this facility, it
446 would simply be too easy for changes to become orphaned when
447 files are renamed.</para>
449 </sect2>
450 <sect2>
451 <title>Divergent renames and merging</title>
453 <para>The case of diverging names occurs when two developers
454 start with a file&emdash;let's call it
455 <filename>foo</filename>&emdash;in their respective
456 repositories.</para>
458 &interaction.rename.divergent.clone;
460 <para>Anne renames the file to <filename>bar</filename>.</para>
462 &interaction.rename.divergent.rename.anne;
464 <para>Meanwhile, Bob renames it to
465 <filename>quux</filename>.</para>
467 &interaction.rename.divergent.rename.bob;
469 <para>I like to think of this as a conflict because each
470 developer has expressed different intentions about what the
471 file ought to be named.</para>
473 <para>What do you think should happen when they merge their
474 work? Mercurial's actual behaviour is that it always preserves
475 <emphasis>both</emphasis> names when it merges changesets that
476 contain divergent renames.</para>
478 &interaction.rename.divergent.merge;
480 <para>Notice that Mercurial does warn about the divergent
481 renames, but it leaves it up to you to do something about the
482 divergence after the merge.</para>
484 </sect2>
485 <sect2>
486 <title>Convergent renames and merging</title>
488 <para>Another kind of rename conflict occurs when two people
489 choose to rename different <emphasis>source</emphasis> files
490 to the same <emphasis>destination</emphasis>. In this case,
491 Mercurial runs its normal merge machinery, and lets you guide
492 it to a suitable resolution.</para>
494 </sect2>
495 <sect2>
496 <title>Other name-related corner cases</title>
498 <para>Mercurial has a longstanding bug in which it fails to
499 handle a merge where one side has a file with a given name,
500 while another has a directory with the same name. This is
501 documented as <ulink role="hg-bug"
502 url="http://www.selenic.com/mercurial/bts/issue29">issue
503 29</ulink>.</para>
505 &interaction.issue29.go;
507 </sect2>
508 </sect1>
509 <sect1>
510 <title>Recovering from mistakes</title>
512 <para>Mercurial has some useful commands that will help you to
513 recover from some common mistakes.</para>
515 <para>The <command role="hg-cmd">hg revert</command> command lets
516 you undo changes that you have made to your working directory.
517 For example, if you <command role="hg-cmd">hg add</command> a
518 file by accident, just run <command role="hg-cmd">hg
519 revert</command> with the name of the file you added, and
520 while the file won't be touched in any way, it won't be tracked
521 for adding by Mercurial any longer, either. You can also use
522 <command role="hg-cmd">hg revert</command> to get rid of
523 erroneous changes to a file.</para>
525 <para>It's useful to remember that the <command role="hg-cmd">hg
526 revert</command> command is useful for changes that you have
527 not yet committed. Once you've committed a change, if you
528 decide it was a mistake, you can still do something about it,
529 though your options may be more limited.</para>
531 <para>For more information about the <command role="hg-cmd">hg
532 revert</command> command, and details about how to deal with
533 changes you have already committed, see chapter <xref
534 linkend="chap:undo"/>.</para>
536 </sect1>
537 </chapter>
539 <!--
540 local variables:
541 sgml-parent-document: ("00book.xml" "book" "chapter")
542 end:
543 -->