hgbook

annotate en/ch04-daily.xml @ 650:7e7c47481e4f

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