hgbook

annotate en/ch05-daily.xml @ 728:20defffb2a53

Typo.
author Giulio@puck
date Sun Jun 14 17:53:38 2009 +0200 (2009-06-14)
parents 477d6a3e5023
children
rev   line source
bos@559 1 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
bos@559 2
bos@685 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
bos@584 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
bos@584 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
bos@584 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@674 29 status</command>. The reason for this is that by default, <command
bos@559 30 role="hg-cmd">hg status</command> only tells you about
bos@674 31 <quote>interesting</quote> files&emdash;those that you have (for
bos@674 32 example) modified, removed, or renamed. If you have a repository
bos@674 33 that contains thousands of files, you will rarely want to know
bos@674 34 about files that Mercurial is tracking, but that have not
bos@674 35 changed. (You can still get this information; we'll return to
bos@674 36 this later.)</para>
bos@559 37
bos@584 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
bos@672 47 <para id="x_1a7">A useful behavior 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
bos@674 54 <para id="x_1a8">Notice in this example that Mercurial printed
bos@674 55 the names of the files it added, whereas it didn't do so when
bos@674 56 we added the file named <filename>myfile.txt</filename> in the
bos@674 57 earlier example.</para>
bos@559 58
bos@584 59 <para id="x_1a9">What's going on is that in the former case, we explicitly
bos@674 60 named the file to add on the command line. The assumption
bos@674 61 that Mercurial makes in such cases is that we know what we
bos@674 62 are doing, and it doesn't print any output.</para>
bos@559 63
bos@584 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@672 69 This behavior is common to most Mercurial commands.</para>
bos@674 70 </sect2>
bos@674 71
bos@672 72 <sect2>
bos@672 73 <title>Mercurial tracks files, not directories</title>
bos@559 74
bos@584 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
bos@584 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
bos@584 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
bos@584 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 </sect2>
bos@559 106 </sect1>
bos@674 107
bos@559 108 <sect1>
bos@559 109 <title>How to stop tracking a file</title>
bos@559 110
bos@701 111 <para id="x_1af">Once you decide that a file no longer belongs in
bos@701 112 your repository, use the <command role="hg-cmd">hg
bos@701 113 remove</command> command. This deletes the file, and tells
bos@701 114 Mercurial to stop tracking it (which will occur at the next
bos@701 115 commit). A removed file is represented in the output of
bos@559 116 <command role="hg-cmd">hg status</command> with a
bos@567 117 <quote><literal>R</literal></quote>.</para>
bos@567 118
bos@567 119 &interaction.daily.files.remove;
bos@559 120
bos@584 121 <para id="x_1b0">After you <command role="hg-cmd">hg remove</command> a file,
bos@559 122 Mercurial will no longer track changes to that file, even if you
bos@559 123 recreate a file with the same name in your working directory.
bos@559 124 If you do recreate a file with the same name and want Mercurial
bos@559 125 to track the new file, simply <command role="hg-cmd">hg
bos@559 126 add</command> it. Mercurial will know that the newly added
bos@559 127 file is not related to the old file of the same name.</para>
bos@559 128
bos@559 129 <sect2>
bos@559 130 <title>Removing a file does not affect its history</title>
bos@559 131
bos@584 132 <para id="x_1b1">It is important to understand that removing a file has
bos@559 133 only two effects.</para>
bos@559 134 <itemizedlist>
bos@584 135 <listitem><para id="x_1b2">It removes the current version of the file
bos@559 136 from the working directory.</para>
bos@559 137 </listitem>
bos@584 138 <listitem><para id="x_1b3">It stops Mercurial from tracking changes to
bos@559 139 the file, from the time of the next commit.</para>
bos@559 140 </listitem></itemizedlist>
bos@584 141 <para id="x_1b4">Removing a file <emphasis>does not</emphasis> in any way
bos@559 142 alter the <emphasis>history</emphasis> of the file.</para>
bos@559 143
bos@674 144 <para id="x_1b5">If you update the working directory to a
bos@674 145 changeset that was committed when it was still tracking a file
bos@674 146 that you later removed, the file will reappear in the working
bos@674 147 directory, with the contents it had when you committed that
bos@674 148 changeset. If you then update the working directory to a
bos@674 149 later changeset, in which the file had been removed, Mercurial
bos@674 150 will once again remove the file from the working
bos@674 151 directory.</para>
bos@674 152 </sect2>
bos@674 153
bos@559 154 <sect2>
bos@559 155 <title>Missing files</title>
bos@559 156
bos@584 157 <para id="x_1b6">Mercurial considers a file that you have deleted, but not
bos@559 158 used <command role="hg-cmd">hg remove</command> to delete, to
bos@559 159 be <emphasis>missing</emphasis>. A missing file is
bos@559 160 represented with <quote><literal>!</literal></quote> in the
bos@559 161 output of <command role="hg-cmd">hg status</command>.
bos@559 162 Mercurial commands will not generally do anything with missing
bos@567 163 files.</para>
bos@567 164
bos@567 165 &interaction.daily.files.missing;
bos@559 166
bos@584 167 <para id="x_1b7">If your repository contains a file that <command
bos@559 168 role="hg-cmd">hg status</command> reports as missing, and
bos@559 169 you want the file to stay gone, you can run <command
bos@559 170 role="hg-cmd">hg remove <option
bos@559 171 role="hg-opt-remove">--after</option></command> at any
bos@559 172 time later on, to tell Mercurial that you really did mean to
bos@567 173 remove the file.</para>
bos@567 174
bos@567 175 &interaction.daily.files.remove-after;
bos@559 176
bos@584 177 <para id="x_1b8">On the other hand, if you deleted the missing file by
bos@559 178 accident, give <command role="hg-cmd">hg revert</command> the
bos@559 179 name of the file to recover. It will reappear, in unmodified
bos@559 180 form.</para>
bos@559 181
bos@674 182 &interaction.daily.files.recover-missing;
bos@674 183 </sect2>
bos@674 184
bos@559 185 <sect2>
bos@559 186 <title>Aside: why tell Mercurial explicitly to remove a
bos@559 187 file?</title>
bos@559 188
bos@584 189 <para id="x_1b9">You might wonder why Mercurial requires you to explicitly
bos@559 190 tell it that you are deleting a file. Early during the
bos@559 191 development of Mercurial, it let you delete a file however you
bos@559 192 pleased; Mercurial would notice the absence of the file
bos@559 193 automatically when you next ran a <command role="hg-cmd">hg
bos@559 194 commit</command>, and stop tracking the file. In practice,
bos@559 195 this made it too easy to accidentally remove a file without
bos@559 196 noticing.</para>
bos@674 197 </sect2>
bos@674 198
bos@559 199 <sect2>
bos@559 200 <title>Useful shorthand&emdash;adding and removing files in one
bos@559 201 step</title>
bos@559 202
bos@584 203 <para id="x_1ba">Mercurial offers a combination command, <command
bos@559 204 role="hg-cmd">hg addremove</command>, that adds untracked
bos@567 205 files and marks missing files as removed.</para>
bos@567 206
bos@567 207 &interaction.daily.files.addremove;
bos@567 208
bos@584 209 <para id="x_1bb">The <command role="hg-cmd">hg commit</command> command
bos@567 210 also provides a <option role="hg-opt-commit">-A</option>
bos@567 211 option that performs this same add-and-remove, immediately
bos@567 212 followed by a commit.</para>
bos@567 213
bos@567 214 &interaction.daily.files.commit-addremove;
bos@559 215 </sect2>
bos@559 216 </sect1>
bos@674 217
bos@701 218 <sect1 id="chap:daily.copy">
bos@559 219 <title>Copying files</title>
bos@559 220
bos@584 221 <para id="x_1bc">Mercurial provides a <command role="hg-cmd">hg
bos@559 222 copy</command> command that lets you make a new copy of a
bos@559 223 file. When you copy a file using this command, Mercurial makes
bos@559 224 a record of the fact that the new file is a copy of the original
bos@559 225 file. It treats these copied files specially when you merge
bos@559 226 your work with someone else's.</para>
bos@559 227
bos@559 228 <sect2>
bos@559 229 <title>The results of copying during a merge</title>
bos@559 230
bos@584 231 <para id="x_1bd">What happens during a merge is that changes
bos@559 232 <quote>follow</quote> a copy. To best illustrate what this
bos@559 233 means, let's create an example. We'll start with the usual
bos@567 234 tiny repository that contains a single file.</para>
bos@567 235
bos@567 236 &interaction.daily.copy.init;
bos@567 237
bos@584 238 <para id="x_1be">We need to do some work in
bos@559 239 parallel, so that we'll have something to merge. So let's
bos@567 240 clone our repository.</para>
bos@567 241
bos@567 242 &interaction.daily.copy.clone;
bos@567 243
bos@584 244 <para id="x_1bf">Back in our initial repository, let's use the <command
bos@559 245 role="hg-cmd">hg copy</command> command to make a copy of
bos@567 246 the first file we created.</para>
bos@567 247
bos@567 248 &interaction.daily.copy.copy;
bos@559 249
bos@584 250 <para id="x_1c0">If we look at the output of the <command role="hg-cmd">hg
bos@559 251 status</command> command afterwards, the copied file looks
bos@567 252 just like a normal added file.</para>
bos@567 253
bos@567 254 &interaction.daily.copy.status;
bos@567 255
bos@584 256 <para id="x_1c1">But if we pass the <option
bos@559 257 role="hg-opt-status">-C</option> option to <command
bos@559 258 role="hg-cmd">hg status</command>, it prints another line of
bos@559 259 output: this is the file that our newly-added file was copied
bos@567 260 <emphasis>from</emphasis>.</para>
bos@567 261
bos@567 262 &interaction.daily.copy.status-copy;
bos@559 263
bos@584 264 <para id="x_1c2">Now, back in the repository we cloned, let's make a change
bos@559 265 in parallel. We'll add a line of content to the original file
bos@567 266 that we created.</para>
bos@567 267
bos@567 268 &interaction.daily.copy.other;
bos@567 269
bos@584 270 <para id="x_1c3">Now we have a modified <filename>file</filename> in this
bos@559 271 repository. When we pull the changes from the first
bos@559 272 repository, and merge the two heads, Mercurial will propagate
bos@559 273 the changes that we made locally to <filename>file</filename>
bos@567 274 into its copy, <filename>new-file</filename>.</para>
bos@567 275
bos@567 276 &interaction.daily.copy.merge;
bos@674 277 </sect2>
bos@674 278
bos@559 279 <sect2 id="sec:daily:why-copy">
bos@559 280 <title>Why should changes follow copies?</title>
bos@559 281
bos@674 282 <para id="x_1c4">This behavior&emdash;of changes to a file
bos@674 283 propagating out to copies of the file&emdash;might seem
bos@674 284 esoteric, but in most cases it's highly desirable.</para>
bos@559 285
bos@584 286 <para id="x_1c5">First of all, remember that this propagation
bos@559 287 <emphasis>only</emphasis> happens when you merge. So if you
bos@559 288 <command role="hg-cmd">hg copy</command> a file, and
bos@559 289 subsequently modify the original file during the normal course
bos@559 290 of your work, nothing will happen.</para>
bos@559 291
bos@584 292 <para id="x_1c6">The second thing to know is that modifications will only
bos@674 293 propagate across a copy as long as the changeset that you're
bos@674 294 merging changes from <emphasis>hasn't yet seen</emphasis>
bos@559 295 the copy.</para>
bos@559 296
bos@584 297 <para id="x_1c7">The reason that Mercurial does this is as follows. Let's
bos@559 298 say I make an important bug fix in a source file, and commit
bos@559 299 my changes. Meanwhile, you've decided to <command
bos@559 300 role="hg-cmd">hg copy</command> the file in your repository,
bos@559 301 without knowing about the bug or having seen the fix, and you
bos@559 302 have started hacking on your copy of the file.</para>
bos@559 303
bos@584 304 <para id="x_1c8">If you pulled and merged my changes, and Mercurial
bos@559 305 <emphasis>didn't</emphasis> propagate changes across copies,
bos@674 306 your new source file would now contain the bug, and unless you
bos@674 307 knew to propagate the bug fix by hand, the bug would
bos@559 308 <emphasis>remain</emphasis> in your copy of the file.</para>
bos@559 309
bos@584 310 <para id="x_1c9">By automatically propagating the change that fixed the bug
bos@559 311 from the original file to the copy, Mercurial prevents this
bos@559 312 class of problem. To my knowledge, Mercurial is the
bos@559 313 <emphasis>only</emphasis> revision control system that
bos@559 314 propagates changes across copies like this.</para>
bos@559 315
bos@584 316 <para id="x_1ca">Once your change history has a record that the copy and
bos@559 317 subsequent merge occurred, there's usually no further need to
bos@559 318 propagate changes from the original file to the copied file,
bos@559 319 and that's why Mercurial only propagates changes across copies
bos@674 320 at the first merge, and not afterwards.</para>
bos@674 321 </sect2>
bos@674 322
bos@559 323 <sect2>
bos@559 324 <title>How to make changes <emphasis>not</emphasis> follow a
bos@559 325 copy</title>
bos@559 326
bos@584 327 <para id="x_1cb">If, for some reason, you decide that this business of
bos@559 328 automatically propagating changes across copies is not for
bos@559 329 you, simply use your system's normal file copy command (on
bos@559 330 Unix-like systems, that's <command>cp</command>) to make a
bos@559 331 copy of a file, then <command role="hg-cmd">hg add</command>
bos@559 332 the new copy by hand. Before you do so, though, please do
bos@592 333 reread <xref linkend="sec:daily:why-copy"/>, and make
bos@559 334 an informed
bos@672 335 decision that this behavior is not appropriate to your
bos@559 336 specific case.</para>
bos@559 337
bos@559 338 </sect2>
bos@559 339 <sect2>
bos@674 340 <title>Behavior of the <command role="hg-cmd">hg copy</command>
bos@559 341 command</title>
bos@559 342
bos@584 343 <para id="x_1cc">When you use the <command role="hg-cmd">hg copy</command>
bos@559 344 command, Mercurial makes a copy of each source file as it
bos@559 345 currently stands in the working directory. This means that if
bos@559 346 you make some modifications to a file, then <command
bos@559 347 role="hg-cmd">hg copy</command> it without first having
bos@559 348 committed those changes, the new copy will also contain the
bos@559 349 modifications you have made up until that point. (I find this
bos@672 350 behavior a little counterintuitive, which is why I mention it
bos@559 351 here.)</para>
bos@559 352
bos@674 353 <para id="x_1cd">The <command role="hg-cmd">hg copy</command>
bos@674 354 command acts similarly to the Unix <command>cp</command>
bos@674 355 command (you can use the <command role="hg-cmd">hg
bos@674 356 cp</command> alias if you prefer). We must supply two or
bos@674 357 more arguments, of which the last is treated as the
bos@674 358 <emphasis>destination</emphasis>, and all others are
bos@674 359 <emphasis>sources</emphasis>.</para>
bos@674 360
bos@676 361 <para id="x_685">If you pass <command role="hg-cmd">hg copy</command> a
bos@674 362 single file as the source, and the destination does not exist,
bos@674 363 it creates a new file with that name.</para>
bos@567 364
bos@567 365 &interaction.daily.copy.simple;
bos@567 366
bos@584 367 <para id="x_1ce">If the destination is a directory, Mercurial copies its
bos@567 368 sources into that directory.</para>
bos@567 369
bos@567 370 &interaction.daily.copy.dir-dest;
bos@567 371
bos@584 372 <para id="x_1cf">Copying a directory is
bos@559 373 recursive, and preserves the directory structure of the
bos@567 374 source.</para>
bos@567 375
bos@567 376 &interaction.daily.copy.dir-src;
bos@567 377
bos@584 378 <para id="x_1d0">If the source and destination are both directories, the
bos@567 379 source tree is recreated in the destination directory.</para>
bos@567 380
bos@567 381 &interaction.daily.copy.dir-src-dest;
bos@559 382
bos@674 383 <para id="x_1d1">As with the <command role="hg-cmd">hg remove</command>
bos@559 384 command, if you copy a file manually and then want Mercurial
bos@559 385 to know that you've copied the file, simply use the <option
bos@559 386 role="hg-opt-copy">--after</option> option to <command
bos@567 387 role="hg-cmd">hg copy</command>.</para>
bos@567 388
bos@567 389 &interaction.daily.copy.after;
bos@559 390 </sect2>
bos@559 391 </sect1>
bos@674 392
bos@559 393 <sect1>
bos@559 394 <title>Renaming files</title>
bos@559 395
bos@584 396 <para id="x_1d2">It's rather more common to need to rename a file than to
bos@559 397 make a copy of it. The reason I discussed the <command
bos@559 398 role="hg-cmd">hg copy</command> command before talking about
bos@559 399 renaming files is that Mercurial treats a rename in essentially
bos@559 400 the same way as a copy. Therefore, knowing what Mercurial does
bos@559 401 when you copy a file tells you what to expect when you rename a
bos@559 402 file.</para>
bos@559 403
bos@584 404 <para id="x_1d3">When you use the <command role="hg-cmd">hg rename</command>
bos@559 405 command, Mercurial makes a copy of each source file, then
bos@567 406 deletes it and marks the file as removed.</para>
bos@567 407
bos@567 408 &interaction.daily.rename.rename;
bos@567 409
bos@584 410 <para id="x_1d4">The <command role="hg-cmd">hg status</command> command shows
bos@567 411 the newly copied file as added, and the copied-from file as
bos@567 412 removed.</para>
bos@567 413
bos@567 414 &interaction.daily.rename.status;
bos@567 415
bos@584 416 <para id="x_1d5">As with the results of a <command role="hg-cmd">hg
bos@567 417 copy</command>, we must use the <option
bos@567 418 role="hg-opt-status">-C</option> option to <command
bos@559 419 role="hg-cmd">hg status</command> to see that the added file
bos@559 420 is really being tracked by Mercurial as a copy of the original,
bos@567 421 now removed, file.</para>
bos@567 422
bos@567 423 &interaction.daily.rename.status-copy;
bos@559 424
bos@584 425 <para id="x_1d6">As with <command role="hg-cmd">hg remove</command> and
bos@559 426 <command role="hg-cmd">hg copy</command>, you can tell Mercurial
bos@559 427 about a rename after the fact using the <option
bos@559 428 role="hg-opt-rename">--after</option> option. In most other
bos@672 429 respects, the behavior of the <command role="hg-cmd">hg
bos@559 430 rename</command> command, and the options it accepts, are
bos@559 431 similar to the <command role="hg-cmd">hg copy</command>
bos@559 432 command.</para>
bos@559 433
bos@676 434 <para id="x_686">If you're familiar with the Unix command line, you'll be
bos@674 435 glad to know that <command role="hg-cmd">hg rename</command>
bos@674 436 command can be invoked as <command role="hg-cmd">hg
bos@674 437 mv</command>.</para>
bos@674 438
bos@559 439 <sect2>
bos@559 440 <title>Renaming files and merging changes</title>
bos@559 441
bos@584 442 <para id="x_1d7">Since Mercurial's rename is implemented as
bos@559 443 copy-and-remove, the same propagation of changes happens when
bos@559 444 you merge after a rename as after a copy.</para>
bos@559 445
bos@584 446 <para id="x_1d8">If I modify a file, and you rename it to a new name, and
bos@559 447 then we merge our respective changes, my modifications to the
bos@559 448 file under its original name will be propagated into the file
bos@559 449 under its new name. (This is something you might expect to
bos@559 450 <quote>simply work,</quote> but not all revision control
bos@559 451 systems actually do this.)</para>
bos@559 452
bos@584 453 <para id="x_1d9">Whereas having changes follow a copy is a feature where
bos@559 454 you can perhaps nod and say <quote>yes, that might be
bos@559 455 useful,</quote> it should be clear that having them follow a
bos@559 456 rename is definitely important. Without this facility, it
bos@559 457 would simply be too easy for changes to become orphaned when
bos@559 458 files are renamed.</para>
bos@674 459 </sect2>
bos@674 460
bos@559 461 <sect2>
bos@559 462 <title>Divergent renames and merging</title>
bos@559 463
bos@584 464 <para id="x_1da">The case of diverging names occurs when two developers
bos@559 465 start with a file&emdash;let's call it
bos@559 466 <filename>foo</filename>&emdash;in their respective
bos@559 467 repositories.</para>
bos@559 468
bos@567 469 &interaction.rename.divergent.clone;
bos@567 470
bos@584 471 <para id="x_1db">Anne renames the file to <filename>bar</filename>.</para>
bos@567 472
bos@567 473 &interaction.rename.divergent.rename.anne;
bos@567 474
bos@584 475 <para id="x_1dc">Meanwhile, Bob renames it to
bos@674 476 <filename>quux</filename>. (Remember that <command
bos@674 477 role="hg-cmd">hg mv</command> is an alias for <command
bos@674 478 role="hg-cmd">hg rename</command>.)</para>
bos@567 479
bos@567 480 &interaction.rename.divergent.rename.bob;
bos@559 481
bos@584 482 <para id="x_1dd">I like to think of this as a conflict because each
bos@559 483 developer has expressed different intentions about what the
bos@559 484 file ought to be named.</para>
bos@559 485
bos@584 486 <para id="x_1de">What do you think should happen when they merge their
bos@672 487 work? Mercurial's actual behavior is that it always preserves
bos@559 488 <emphasis>both</emphasis> names when it merges changesets that
bos@567 489 contain divergent renames.</para>
bos@567 490
bos@567 491 &interaction.rename.divergent.merge;
bos@559 492
bos@674 493 <para id="x_1df">Notice that while Mercurial warns about the divergent
bos@674 494 renames, it leaves it up to you to do something about the
bos@559 495 divergence after the merge.</para>
bos@674 496 </sect2>
bos@674 497
bos@559 498 <sect2>
bos@559 499 <title>Convergent renames and merging</title>
bos@559 500
bos@584 501 <para id="x_1e0">Another kind of rename conflict occurs when two people
bos@559 502 choose to rename different <emphasis>source</emphasis> files
bos@559 503 to the same <emphasis>destination</emphasis>. In this case,
bos@559 504 Mercurial runs its normal merge machinery, and lets you guide
bos@559 505 it to a suitable resolution.</para>
bos@674 506 </sect2>
bos@674 507
bos@559 508 <sect2>
bos@559 509 <title>Other name-related corner cases</title>
bos@559 510
bos@584 511 <para id="x_1e1">Mercurial has a longstanding bug in which it fails to
bos@559 512 handle a merge where one side has a file with a given name,
bos@559 513 while another has a directory with the same name. This is
bos@559 514 documented as <ulink role="hg-bug"
bos@559 515 url="http://www.selenic.com/mercurial/bts/issue29">issue
bos@567 516 29</ulink>.</para>
bos@567 517
bos@567 518 &interaction.issue29.go;
bos@559 519
bos@559 520 </sect2>
bos@559 521 </sect1>
bos@674 522
bos@559 523 <sect1>
bos@559 524 <title>Recovering from mistakes</title>
bos@559 525
bos@584 526 <para id="x_1e2">Mercurial has some useful commands that will help you to
bos@559 527 recover from some common mistakes.</para>
bos@559 528
bos@584 529 <para id="x_1e3">The <command role="hg-cmd">hg revert</command> command lets
bos@559 530 you undo changes that you have made to your working directory.
bos@559 531 For example, if you <command role="hg-cmd">hg add</command> a
bos@559 532 file by accident, just run <command role="hg-cmd">hg
bos@559 533 revert</command> with the name of the file you added, and
bos@559 534 while the file won't be touched in any way, it won't be tracked
bos@559 535 for adding by Mercurial any longer, either. You can also use
bos@559 536 <command role="hg-cmd">hg revert</command> to get rid of
bos@559 537 erroneous changes to a file.</para>
bos@559 538
bos@701 539 <para id="x_1e4">It is helpful to remember that the <command
bos@701 540 role="hg-cmd">hg revert</command> command is useful for
bos@701 541 changes that you have not yet committed. Once you've committed
bos@701 542 a change, if you decide it was a mistake, you can still do
bos@701 543 something about it, though your options may be more
bos@701 544 limited.</para>
bos@559 545
bos@592 546 <para id="x_1e5">For more information about the <command
bos@592 547 role="hg-cmd">hg revert</command> command, and details about
bos@592 548 how to deal with changes you have already committed, see <xref
bos@559 549 linkend="chap:undo"/>.</para>
bos@674 550 </sect1>
bos@674 551
bos@674 552 <sect1>
bos@674 553 <title>Dealing with tricky merges</title>
bos@674 554
bos@676 555 <para id="x_687">In a complicated or large project, it's not unusual for a
bos@674 556 merge of two changesets to result in some headaches. Suppose
bos@674 557 there's a big source file that's been extensively edited by each
bos@674 558 side of a merge: this is almost inevitably going to result in
bos@674 559 conflicts, some of which can take a few tries to sort
bos@674 560 out.</para>
bos@674 561
bos@676 562 <para id="x_688">Let's develop a simple case of this and see how to deal with
bos@674 563 it. We'll start off with a repository containing one file, and
bos@674 564 clone it twice.</para>
bos@674 565
bos@674 566 &interaction.ch04-resolve.init;
bos@674 567
bos@676 568 <para id="x_689">In one clone, we'll modify the file in one way.</para>
bos@674 569
bos@674 570 &interaction.ch04-resolve.left;
bos@674 571
bos@676 572 <para id="x_68a">In another, we'll modify the file differently.</para>
bos@674 573
bos@674 574 &interaction.ch04-resolve.right;
bos@674 575
bos@676 576 <para id="x_68b">Next, we'll pull each set of changes into our original
bos@674 577 repo.</para>
bos@674 578
bos@674 579 &interaction.ch04-resolve.pull;
bos@674 580
bos@676 581 <para id="x_68c">We expect our repository to now contain two heads.</para>
bos@674 582
bos@674 583 &interaction.ch04-resolve.heads;
bos@674 584
bos@676 585 <para id="x_68d">Normally, if we run <command role="hg-cmd">hg
bos@674 586 merge</command> at this point, it will drop us into a GUI that
bos@674 587 will let us manually resolve the conflicting edits to
bos@674 588 <filename>myfile.txt</filename>. However, to simplify things
bos@674 589 for presentation here, we'd like the merge to fail immediately
bos@674 590 instead. Here's one way we can do so.</para>
bos@674 591
bos@674 592 &interaction.ch04-resolve.export;
bos@674 593
bos@676 594 <para id="x_68e">We've told Mercurial's merge machinery to run the command
bos@674 595 <command>false</command> (which, as we desire, fails
bos@674 596 immediately) if it detects a merge that it can't sort out
bos@674 597 automatically.</para>
bos@674 598
bos@676 599 <para id="x_68f">If we now fire up <command role="hg-cmd">hg
bos@674 600 merge</command>, it should grind to a halt and report a
bos@674 601 failure.</para>
bos@674 602
bos@674 603 &interaction.ch04-resolve.merge;
bos@674 604
bos@676 605 <para id="x_690">Even if we don't notice that the merge failed, Mercurial
bos@674 606 will prevent us from accidentally committing the result of a
bos@674 607 failed merge.</para>
bos@674 608
bos@674 609 &interaction.ch04-resolve.cifail;
bos@674 610
bos@676 611 <para id="x_691">When <command role="hg-cmd">hg commit</command> fails in
bos@674 612 this case, it suggests that we use the unfamiliar <command
bos@674 613 role="hg-cmd">hg resolve</command> command. As usual,
bos@674 614 <command role="hg-cmd">hg help resolve</command> will print a
bos@674 615 helpful synopsis.</para>
bos@674 616
bos@674 617 <sect2>
bos@674 618 <title>File resolution states</title>
bos@674 619
bos@676 620 <para id="x_692">When a merge occurs, most files will usually remain
bos@674 621 unmodified. For each file where Mercurial has to do
bos@674 622 something, it tracks the state of the file.</para>
bos@674 623
bos@674 624 <itemizedlist>
bos@674 625 <listitem>
bos@676 626 <para id="x_693">A <emphasis>resolved</emphasis> file has been
bos@674 627 successfully merged, either automatically by Mercurial or
bos@674 628 manually with human intervention.</para>
bos@674 629 </listitem>
bos@674 630 <listitem>
bos@676 631 <para id="x_694">An <emphasis>unresolved</emphasis> file was not merged
bos@674 632 successfully, and needs more attention.</para>
bos@674 633 </listitem>
bos@674 634 </itemizedlist>
bos@674 635
bos@676 636 <para id="x_695">If Mercurial sees <emphasis>any</emphasis> file in the
bos@674 637 unresolved state after a merge, it considers the merge to have
bos@674 638 failed. Fortunately, we do not need to restart the entire
bos@674 639 merge from scratch.</para>
bos@674 640
bos@676 641 <para id="x_696">The <option role="hg-opt-resolve">--list</option> or
bos@674 642 <option role="hg-opt-resolve">-l</option> option to <command
bos@674 643 role="hg-cmd">hg resolve</command> prints out the state of
bos@674 644 each merged file.</para>
bos@674 645
bos@674 646 &interaction.ch04-resolve.list;
bos@674 647
bos@676 648 <para id="x_697">In the output from <command role="hg-cmd">hg
bos@674 649 resolve</command>, a resolved file is marked with
bos@674 650 <literal>R</literal>, while an unresolved file is marked with
bos@674 651 <literal>U</literal>. If any files are listed with
bos@674 652 <literal>U</literal>, we know that an attempt to commit the
bos@674 653 results of the merge will fail.</para>
bos@674 654 </sect2>
bos@674 655
bos@674 656 <sect2>
bos@674 657 <title>Resolving a file merge</title>
bos@674 658
bos@676 659 <para id="x_698">We have several options to move a file from the unresolved
bos@674 660 into the resolved state. By far the most common is to rerun
bos@674 661 <command role="hg-cmd">hg resolve</command>. If we pass the
bos@674 662 names of individual files or directories, it will retry the
bos@674 663 merges of any unresolved files present in those locations. We
bos@674 664 can also pass the <option role="hg-opt-resolve">--all</option>
bos@674 665 or <option role="hg-opt-resolve">-a</option> option, which
bos@674 666 will retry the merges of <emphasis>all</emphasis> unresolved
bos@674 667 files.</para>
bos@674 668
bos@676 669 <para id="x_699">Mercurial also lets us modify the resolution state of a
bos@674 670 file directly. We can manually mark a file as resolved using
bos@674 671 the <option role="hg-opt-resolve">--mark</option> option, or
bos@674 672 as unresolved using the <option
bos@674 673 role="hg-opt-resolve">--unmark</option> option. This allows
bos@674 674 us to clean up a particularly messy merge by hand, and to keep
bos@674 675 track of our progress with each file as we go.</para>
bos@674 676 </sect2>
bos@559 677 </sect1>
bos@683 678
bos@683 679 <sect1>
bos@683 680 <title>More useful diffs</title>
bos@683 681
bos@684 682 <para id="x_6c7">The default output of the <command role="hg-cmd">hg
bos@683 683 diff</command> command is backwards compatible with the
bos@683 684 regular <command>diff</command> command, but this has some
bos@683 685 drawbacks.</para>
bos@683 686
bos@684 687 <para id="x_6c8">Consider the case where we use <command role="hg-cmd">hg
bos@683 688 rename</command> to rename a file.</para>
bos@683 689
bos@683 690 &interaction.ch04-diff.rename.basic;
bos@683 691
bos@684 692 <para id="x_6c9">The output of <command role="hg-cmd">hg diff</command> above
bos@683 693 obscures the fact that we simply renamed a file. The <command
bos@683 694 role="hg-cmd">hg diff</command> command accepts an option,
bos@683 695 <option>--git</option> or <option>-g</option>, to use a newer
bos@683 696 diff format that displays such information in a more readable
bos@683 697 form.</para>
bos@683 698
bos@683 699 &interaction.ch04-diff.rename.git;
bos@683 700
bos@684 701 <para id="x_6ca">This option also helps with a case that can otherwise be
bos@683 702 confusing: a file that appears to be modified according to
bos@683 703 <command role="hg-cmd">hg status</command>, but for which
bos@683 704 <command role="hg-cmd">hg diff</command> prints nothing. This
bos@683 705 situation can arise if we change the file's execute
bos@683 706 permissions.</para>
bos@683 707
bos@683 708 &interaction.ch04-diff.chmod;
bos@683 709
bos@684 710 <para id="x_6cb">The normal <command>diff</command> command pays no attention
bos@683 711 to file permissions, which is why <command role="hg-cmd">hg
bos@683 712 diff</command> prints nothing by default. If we supply it
bos@683 713 with the <option>-g</option> option, it tells us what really
bos@683 714 happened.</para>
bos@683 715
bos@683 716 &interaction.ch04-diff.chmod.git;
bos@683 717 </sect1>
bos@683 718
bos@683 719 <sect1>
bos@683 720 <title>Which files to manage, and which to avoid</title>
bos@683 721
bos@684 722 <para id="x_6cc">Revision control systems are generally best at managing text
bos@683 723 files that are written by humans, such as source code, where the
bos@683 724 files do not change much from one revision to the next. Some
bos@683 725 centralized revision control systems can also deal tolerably
bos@683 726 well with binary files, such as bitmap images.</para>
bos@683 727
bos@684 728 <para id="x_6cd">For instance, a game development team will typically manage
bos@683 729 both its source code and all of its binary assets (e.g. geometry
bos@683 730 data, textures, map layouts) in a revision control
bos@683 731 system.</para>
bos@683 732
bos@684 733 <para id="x_6ce">Because it is usually impossible to merge two conflicting
bos@683 734 modifications to a binary file, centralized systems often
bos@683 735 provide a file locking mechanism that allow a user to say
bos@683 736 <quote>I am the only person who can edit this
bos@683 737 file</quote>.</para>
bos@683 738
bos@684 739 <para id="x_6cf">Compared to a centralized system, a distributed revision
bos@683 740 control system changes some of the factors that guide decisions
bos@683 741 over which files to manage and how.</para>
bos@683 742
bos@684 743 <para id="x_6d0">For instance, a distributed revision control system cannot,
bos@683 744 by its nature, offer a file locking facility. There is thus no
bos@683 745 built-in mechanism to prevent two people from making conflicting
bos@683 746 changes to a binary file. If you have a team where several
bos@683 747 people may be editing binary files frequently, it may not be a
bos@683 748 good idea to use Mercurial&emdash;or any other distributed
bos@683 749 revision control system&emdash;to manage those files.</para>
bos@683 750
bos@684 751 <para id="x_6d1">When storing modifications to a file, Mercurial usually
bos@683 752 saves only the differences between the previous and current
bos@683 753 versions of the file. For most text files, this is extremely
bos@683 754 efficient. However, some files (particularly binary files) are
bos@683 755 laid out in such a way that even a small change to a file's
bos@683 756 logical content results in many or most of the bytes inside the
bos@683 757 file changing. For instance, compressed files are particularly
bos@683 758 susceptible to this. If the differences between each successive
bos@683 759 version of a file are always large, Mercurial will not be able
bos@683 760 to store the file's revision history very efficiently. This can
bos@683 761 affect both local storage needs and the amount of time it takes
bos@683 762 to clone a repository.</para>
bos@683 763
bos@684 764 <para id="x_6d2">To get an idea of how this could affect you in practice,
bos@683 765 suppose you want to use Mercurial to manage an OpenOffice
bos@683 766 document. OpenOffice stores documents on disk as compressed zip
bos@683 767 files. Edit even a single letter of your document in OpenOffice,
bos@683 768 and almost every byte in the entire file will change when you
bos@683 769 save it. Now suppose that file is 2MB in size. Because most of
bos@683 770 the file changes every time you save, Mercurial will have to
bos@683 771 store all 2MB of the file every time you commit, even though
bos@683 772 from your perspective, perhaps only a few words are changing
bos@683 773 each time. A single frequently-edited file that is not friendly
bos@683 774 to Mercurial's storage assumptions can easily have an outsized
bos@683 775 effect on the size of the repository.</para>
bos@683 776
bos@684 777 <para id="x_6d3">Even worse, if both you and someone else edit the OpenOffice
bos@683 778 document you're working on, there is no useful way to merge your
bos@683 779 work. In fact, there isn't even a good way to tell what the
bos@683 780 differences are between your respective changes.</para>
bos@683 781
bos@684 782 <para id="x_6d4">There are thus a few clear recommendations about specific
bos@683 783 kinds of files to be very careful with.</para>
bos@683 784
bos@683 785 <itemizedlist>
bos@683 786 <listitem>
bos@684 787 <para id="x_6d5">Files that are very large and incompressible, e.g. ISO
bos@683 788 CD-ROM images, will by virtue of sheer size make clones over
bos@683 789 a network very slow.</para>
bos@683 790 </listitem>
bos@683 791 <listitem>
bos@684 792 <para id="x_6d6">Files that change a lot from one revision to the next
bos@683 793 may be expensive to store if you edit them frequently, and
bos@683 794 conflicts due to concurrent edits may be difficult to
bos@683 795 resolve.</para>
bos@683 796 </listitem>
bos@683 797 </itemizedlist>
bos@683 798 </sect1>
bos@683 799
bos@683 800 <sect1>
bos@683 801 <title>Backups and mirroring</title>
bos@683 802
bos@684 803 <para id="x_6d7">Since Mercurial maintains a complete copy of history in each
bos@683 804 clone, everyone who uses Mercurial to collaborate on a project
bos@683 805 can potentially act as a source of backups in the event of a
bos@683 806 catastrophe. If a central repository becomes unavailable, you
bos@683 807 can construct a replacement simply by cloning a copy of the
bos@683 808 repository from one contributor, and pulling any changes they
bos@683 809 may not have seen from others.</para>
bos@683 810
bos@684 811 <para id="x_6d8">It is simple to use Mercurial to perform off-site backups
bos@683 812 and remote mirrors. Set up a periodic job (e.g. via the
bos@683 813 <command>cron</command> command) on a remote server to pull
bos@683 814 changes from your master repositories every hour. This will
bos@683 815 only be tricky in the unlikely case that the number of master
bos@683 816 repositories you maintain changes frequently, in which case
bos@683 817 you'll need to do a little scripting to refresh the list of
bos@683 818 repositories to back up.</para>
bos@683 819
bos@684 820 <para id="x_6d9">If you perform traditional backups of your master
bos@683 821 repositories to tape or disk, and you want to back up a
bos@701 822 repository named <filename>myrepo</filename>, use <command>hg
bos@683 823 clone -U myrepo myrepo.bak</command> to create a
bos@683 824 clone of <filename>myrepo</filename> before you start your
bos@683 825 backups. The <option>-U</option> option doesn't check out a
bos@683 826 working directory after the clone completes, since that would be
bos@685 827 superfluous and make the backup take longer.</para>
bos@683 828
bos@684 829 <para id="x_6da">If you then back up <filename>myrepo.bak</filename> instead
bos@683 830 of <filename>myrepo</filename>, you will be guaranteed to have a
bos@683 831 consistent snapshot of your repository that won't be pushed to
bos@683 832 by an insomniac developer in mid-backup.</para>
bos@683 833 </sect1>
bos@559 834 </chapter>
bos@559 835
bos@559 836 <!--
bos@559 837 local variables:
bos@559 838 sgml-parent-document: ("00book.xml" "book" "chapter")
bos@559 839 end:
bos@559 840 -->