hgbook

annotate en/ch05-daily.xml @ 890:2887b61fa4fe

Change fields to fieldsets in the Comment admin model. The 'date'
field isn't working properly for an unknown reason, so it has been
removed from the interface temporarily.
author dukebody <dukebody@gmail.com>
date Sun Oct 11 21:12:46 2009 +0200 (2009-10-11)
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 -->