Source

hgbook / en / ch05-daily.xml

Diff from to

File en/ch05-daily.xml

 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
 
-<chapter id="chap.daily">
+<chapter id="chap:daily">
   <?dbhtml filename="mercurial-in-daily-use.html"?>
   <title>Mercurial in daily use</title>
 
   <sect1>
     <title>Telling Mercurial which files to track</title>
 
-    <para>Mercurial does not work with files in your repository unless
+    <para id="x_1a3">Mercurial does not work with files in your repository unless
       you tell it to manage them.  The <command role="hg-cmd">hg
 	status</command> command will tell you which files Mercurial
       doesn't know about; it uses a
       <quote><literal>?</literal></quote> to display such
       files.</para>
 
-    <para>To tell Mercurial to track a file, use the <command
+    <para id="x_1a4">To tell Mercurial to track a file, use the <command
 	role="hg-cmd">hg add</command> command.  Once you have added a
       file, the entry in the output of <command role="hg-cmd">hg
 	status</command> for that file changes from
 
       &interaction.daily.files.add;
 
-    <para>After you run a <command role="hg-cmd">hg commit</command>,
+    <para id="x_1a5">After you run a <command role="hg-cmd">hg commit</command>,
       the files that you added before the commit will no longer be
       listed in the output of <command role="hg-cmd">hg
-	status</command>.  The reason for this is that <command
+	status</command>.  The reason for this is that by default, <command
 	role="hg-cmd">hg status</command> only tells you about
-      <quote>interesting</quote> files&emdash;those that you have
-      modified or told Mercurial to do something with&emdash;by
-      default.  If you have a repository that contains thousands of
-      files, you will rarely want to know about files that Mercurial
-      is tracking, but that have not changed.  (You can still get this
-      information; we'll return to this later.)</para>
+      <quote>interesting</quote> files&emdash;those that you have (for
+      example) modified, removed, or renamed.  If you have a repository
+      that contains thousands of files, you will rarely want to know
+      about files that Mercurial is tracking, but that have not
+      changed.  (You can still get this information; we'll return to
+      this later.)</para>
 
-    <para>Once you add a file, Mercurial doesn't do anything with it
+    <para id="x_1a6">Once you add a file, Mercurial doesn't do anything with it
       immediately.  Instead, it will take a snapshot of the file's
       state the next time you perform a commit.  It will then continue
       to track the changes you make to the file every time you commit,
     <sect2>
       <title>Explicit versus implicit file naming</title>
 
-      <para>A useful behaviour that Mercurial has is that if you pass
+      <para id="x_1a7">A useful behavior that Mercurial has is that if you pass
 	the name of a directory to a command, every Mercurial command
 	will treat this as <quote>I want to operate on every file in
 	  this directory and its subdirectories</quote>.</para>
 
       &interaction.daily.files.add-dir;
 
-      <para>Notice in this example that Mercurial printed the names of
-	the files it added, whereas it didn't do so when we added the
-	file named <filename>a</filename> in the earlier
-	example.</para>
+      <para id="x_1a8">Notice in this example that Mercurial printed
+	the names of the files it added, whereas it didn't do so when
+	we added the file named <filename>myfile.txt</filename> in the
+	earlier example.</para>
 
-      <para>What's going on is that in the former case, we explicitly
-	named the file to add on the command line, so the assumption
-	that Mercurial makes in such cases is that you know what you
-	were doing, and it doesn't print any output.</para>
+      <para id="x_1a9">What's going on is that in the former case, we explicitly
+	named the file to add on the command line.  The assumption
+	that Mercurial makes in such cases is that we know what we
+	are doing, and it doesn't print any output.</para>
 
-      <para>However, when we <emphasis>imply</emphasis> the names of
+      <para id="x_1aa">However, when we <emphasis>imply</emphasis> the names of
 	files by giving the name of a directory, Mercurial takes the
 	extra step of printing the name of each file that it does
 	something with.  This makes it more clear what is happening,
 	and reduces the likelihood of a silent and nasty surprise.
-	This behaviour is common to most Mercurial commands.</para>
+	This behavior is common to most Mercurial commands.</para>
+    </sect2>
 
-    </sect2>
     <sect2>
-      <title>Aside: Mercurial tracks files, not directories</title>
+      <title>Mercurial tracks files, not directories</title>
 
-      <para>Mercurial does not track directory information.  Instead,
+      <para id="x_1ab">Mercurial does not track directory information.  Instead,
 	it tracks the path to a file.  Before creating a file, it
 	first creates any missing directory components of the path.
 	After it deletes a file, it then deletes any empty directories
 	consequence: it is not possible to represent a completely
 	empty directory in Mercurial.</para>
 
-      <para>Empty directories are rarely useful, and there are
+      <para id="x_1ac">Empty directories are rarely useful, and there are
 	unintrusive workarounds that you can use to achieve an
 	appropriate effect.  The developers of Mercurial thus felt
 	that the complexity that would be required to manage empty
 	directories was not worth the limited benefit this feature
 	would bring.</para>
 
-      <para>If you need an empty directory in your repository, there
+      <para id="x_1ad">If you need an empty directory in your repository, there
 	are a few ways to achieve this. One is to create a directory,
 	then <command role="hg-cmd">hg add</command> a
 	<quote>hidden</quote> file to that directory.  On Unix-like
 
 &interaction.daily.files.hidden;
 
-      <para>Another way to tackle a need for an empty directory is to
+      <para id="x_1ae">Another way to tackle a need for an empty directory is to
 	simply create one in your automated build scripts before they
 	will need it.</para>
-
     </sect2>
   </sect1>
+
   <sect1>
     <title>How to stop tracking a file</title>
 
-    <para>Once you decide that a file no longer belongs in your
-      repository, use the <command role="hg-cmd">hg remove</command>
-      command; this deletes the file, and tells Mercurial to stop
-      tracking it.  A removed file is represented in the output of
+    <para id="x_1af">Once you decide that a file no longer belongs in
+      your repository, use the <command role="hg-cmd">hg
+	remove</command> command. This deletes the file, and tells
+      Mercurial to stop tracking it (which will occur at the next
+      commit).  A removed file is represented in the output of
       <command role="hg-cmd">hg status</command> with a
       <quote><literal>R</literal></quote>.</para>
 
     &interaction.daily.files.remove;
 
-    <para>After you <command role="hg-cmd">hg remove</command> a file,
+    <para id="x_1b0">After you <command role="hg-cmd">hg remove</command> a file,
       Mercurial will no longer track changes to that file, even if you
       recreate a file with the same name in your working directory.
       If you do recreate a file with the same name and want Mercurial
     <sect2>
       <title>Removing a file does not affect its history</title>
 
-      <para>It is important to understand that removing a file has
+      <para id="x_1b1">It is important to understand that removing a file has
 	only two effects.</para>
       <itemizedlist>
-	<listitem><para>It removes the current version of the file
+	<listitem><para id="x_1b2">It removes the current version of the file
 	    from the working directory.</para>
 	</listitem>
-	<listitem><para>It stops Mercurial from tracking changes to
+	<listitem><para id="x_1b3">It stops Mercurial from tracking changes to
 	    the file, from the time of the next commit.</para>
 	</listitem></itemizedlist>
-      <para>Removing a file <emphasis>does not</emphasis> in any way
+      <para id="x_1b4">Removing a file <emphasis>does not</emphasis> in any way
 	alter the <emphasis>history</emphasis> of the file.</para>
 
-      <para>If you update the working directory to a changeset in
-	which a file that you have removed was still tracked, it will
-	reappear in the working directory, with the contents it had
-	when you committed that changeset.  If you then update the
-	working directory to a later changeset, in which the file had
-	been removed, Mercurial will once again remove the file from
-	the working directory.</para>
+      <para id="x_1b5">If you update the working directory to a
+	changeset that was committed when it was still tracking a file
+	that you later removed, the file will reappear in the working
+	directory, with the contents it had when you committed that
+	changeset.  If you then update the working directory to a
+	later changeset, in which the file had been removed, Mercurial
+	will once again remove the file from the working
+	directory.</para>
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>Missing files</title>
 
-      <para>Mercurial considers a file that you have deleted, but not
+      <para id="x_1b6">Mercurial considers a file that you have deleted, but not
 	used <command role="hg-cmd">hg remove</command> to delete, to
 	be <emphasis>missing</emphasis>.  A missing file is
 	represented with <quote><literal>!</literal></quote> in the
 
       &interaction.daily.files.missing;
 
-      <para>If your repository contains a file that <command
+      <para id="x_1b7">If your repository contains a file that <command
 	  role="hg-cmd">hg status</command> reports as missing, and
 	you want the file to stay gone, you can run <command
 	  role="hg-cmd">hg remove <option
 
       &interaction.daily.files.remove-after;
 
-      <para>On the other hand, if you deleted the missing file by
+      <para id="x_1b8">On the other hand, if you deleted the missing file by
 	accident, give <command role="hg-cmd">hg revert</command> the
 	name of the file to recover.  It will reappear, in unmodified
 	form.</para>
 
-&interaction.daily.files.recover-missing;
+      &interaction.daily.files.recover-missing;
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>Aside: why tell Mercurial explicitly to remove a
 	file?</title>
 
-      <para>You might wonder why Mercurial requires you to explicitly
+      <para id="x_1b9">You might wonder why Mercurial requires you to explicitly
 	tell it that you are deleting a file.  Early during the
 	development of Mercurial, it let you delete a file however you
 	pleased; Mercurial would notice the absence of the file
 	  commit</command>, and stop tracking the file.  In practice,
 	this made it too easy to accidentally remove a file without
 	noticing.</para>
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>Useful shorthand&emdash;adding and removing files in one
 	step</title>
 
-      <para>Mercurial offers a combination command, <command
+      <para id="x_1ba">Mercurial offers a combination command, <command
 	  role="hg-cmd">hg addremove</command>, that adds untracked
 	files and marks missing files as removed.</para>
 
       &interaction.daily.files.addremove;
 
-      <para>The <command role="hg-cmd">hg commit</command> command
+      <para id="x_1bb">The <command role="hg-cmd">hg commit</command> command
 	also provides a <option role="hg-opt-commit">-A</option>
 	option that performs this same add-and-remove, immediately
 	followed by a commit.</para>
 
       &interaction.daily.files.commit-addremove;
-
     </sect2>
   </sect1>
-  <sect1>
+
+  <sect1 id="chap:daily.copy">
     <title>Copying files</title>
 
-    <para>Mercurial provides a <command role="hg-cmd">hg
+    <para id="x_1bc">Mercurial provides a <command role="hg-cmd">hg
 	copy</command> command that lets you make a new copy of a
       file.  When you copy a file using this command, Mercurial makes
       a record of the fact that the new file is a copy of the original
     <sect2>
       <title>The results of copying during a merge</title>
 
-      <para>What happens during a merge is that changes
+      <para id="x_1bd">What happens during a merge is that changes
 	<quote>follow</quote> a copy.  To best illustrate what this
 	means, let's create an example.  We'll start with the usual
 	tiny repository that contains a single file.</para>
 
       &interaction.daily.copy.init;
 
-      <para>We need to do some work in
+      <para id="x_1be">We need to do some work in
 	parallel, so that we'll have something to merge.  So let's
 	clone our repository.</para>
 
       &interaction.daily.copy.clone;
 
-      <para>Back in our initial repository, let's use the <command
+      <para id="x_1bf">Back in our initial repository, let's use the <command
 	  role="hg-cmd">hg copy</command> command to make a copy of
 	the first file we created.</para>
 
       &interaction.daily.copy.copy;
 
-      <para>If we look at the output of the <command role="hg-cmd">hg
+      <para id="x_1c0">If we look at the output of the <command role="hg-cmd">hg
 	  status</command> command afterwards, the copied file looks
 	just like a normal added file.</para>
 
       &interaction.daily.copy.status;
 
-      <para>But if we pass the <option
+      <para id="x_1c1">But if we pass the <option
 	  role="hg-opt-status">-C</option> option to <command
 	  role="hg-cmd">hg status</command>, it prints another line of
 	output: this is the file that our newly-added file was copied
 
       &interaction.daily.copy.status-copy;
 
-      <para>Now, back in the repository we cloned, let's make a change
+      <para id="x_1c2">Now, back in the repository we cloned, let's make a change
 	in parallel.  We'll add a line of content to the original file
 	that we created.</para>
 
       &interaction.daily.copy.other;
 
-      <para>Now we have a modified <filename>file</filename> in this
+      <para id="x_1c3">Now we have a modified <filename>file</filename> in this
 	repository.  When we pull the changes from the first
 	repository, and merge the two heads, Mercurial will propagate
 	the changes that we made locally to <filename>file</filename>
 	into its copy, <filename>new-file</filename>.</para>
 
       &interaction.daily.copy.merge;
+    </sect2>
 
-    </sect2>
-    <sect2 id="sec.daily.why-copy">
+    <sect2 id="sec:daily:why-copy">
       <title>Why should changes follow copies?</title>
 
-      <para>This behaviour, of changes to a file propagating out to
-	copies of the file, might seem esoteric, but in most cases
-	it's highly desirable.</para>
+      <para id="x_1c4">This behavior&emdash;of changes to a file
+	propagating out to copies of the file&emdash;might seem
+	esoteric, but in most cases it's highly desirable.</para>
 
-      <para>First of all, remember that this propagation
+      <para id="x_1c5">First of all, remember that this propagation
 	<emphasis>only</emphasis> happens when you merge.  So if you
 	<command role="hg-cmd">hg copy</command> a file, and
 	subsequently modify the original file during the normal course
 	of your work, nothing will happen.</para>
 
-      <para>The second thing to know is that modifications will only
-	propagate across a copy as long as the repository that you're
-	pulling changes from <emphasis>doesn't know</emphasis> about
+      <para id="x_1c6">The second thing to know is that modifications will only
+	propagate across a copy as long as the changeset that you're
+	merging changes from <emphasis>hasn't yet seen</emphasis> 
 	the copy.</para>
 
-      <para>The reason that Mercurial does this is as follows.  Let's
+      <para id="x_1c7">The reason that Mercurial does this is as follows.  Let's
 	say I make an important bug fix in a source file, and commit
 	my changes. Meanwhile, you've decided to <command
 	  role="hg-cmd">hg copy</command> the file in your repository,
 	without knowing about the bug or having seen the fix, and you
 	have started hacking on your copy of the file.</para>
 
-      <para>If you pulled and merged my changes, and Mercurial
+      <para id="x_1c8">If you pulled and merged my changes, and Mercurial
 	<emphasis>didn't</emphasis> propagate changes across copies,
-	your source file would now contain the bug, and unless you
-	remembered to propagate the bug fix by hand, the bug would
+	your new source file would now contain the bug, and unless you
+	knew to propagate the bug fix by hand, the bug would
 	<emphasis>remain</emphasis> in your copy of the file.</para>
 
-      <para>By automatically propagating the change that fixed the bug
+      <para id="x_1c9">By automatically propagating the change that fixed the bug
 	from the original file to the copy, Mercurial prevents this
 	class of problem. To my knowledge, Mercurial is the
 	<emphasis>only</emphasis> revision control system that
 	propagates changes across copies like this.</para>
 
-      <para>Once your change history has a record that the copy and
+      <para id="x_1ca">Once your change history has a record that the copy and
 	subsequent merge occurred, there's usually no further need to
 	propagate changes from the original file to the copied file,
 	and that's why Mercurial only propagates changes across copies
-	until this point, and no further.</para>
+	at the first merge, and not afterwards.</para>
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>How to make changes <emphasis>not</emphasis> follow a
 	copy</title>
 
-      <para>If, for some reason, you decide that this business of
+      <para id="x_1cb">If, for some reason, you decide that this business of
 	automatically propagating changes across copies is not for
 	you, simply use your system's normal file copy command (on
 	Unix-like systems, that's <command>cp</command>) to make a
 	copy of a file, then <command role="hg-cmd">hg add</command>
 	the new copy by hand.  Before you do so, though, please do
-	reread section <xref linkend="sec.daily.why-copy"/>, and make
+	reread <xref linkend="sec:daily:why-copy"/>, and make
 	an informed
-	decision that this behaviour is not appropriate to your
+	decision that this behavior is not appropriate to your
 	specific case.</para>
 
     </sect2>
     <sect2>
-      <title>Behaviour of the <command role="hg-cmd">hg copy</command>
+      <title>Behavior of the <command role="hg-cmd">hg copy</command>
 	command</title>
 
-      <para>When you use the <command role="hg-cmd">hg copy</command>
+      <para id="x_1cc">When you use the <command role="hg-cmd">hg copy</command>
 	command, Mercurial makes a copy of each source file as it
 	currently stands in the working directory.  This means that if
 	you make some modifications to a file, then <command
 	  role="hg-cmd">hg copy</command> it without first having
 	committed those changes, the new copy will also contain the
 	modifications you have made up until that point.  (I find this
-	behaviour a little counterintuitive, which is why I mention it
+	behavior a little counterintuitive, which is why I mention it
 	here.)</para>
 
-      <para>The <command role="hg-cmd">hg copy</command> command acts
-	similarly to the Unix <command>cp</command> command (you can
-	use the <command role="hg-cmd">hg cp</command> alias if you
-	prefer).  The last argument is the
-	<emphasis>destination</emphasis>, and all prior arguments are
-	<emphasis>sources</emphasis>.  If you pass it a single file as
-	the source, and the destination does not exist, it creates a
-	new file with that name.</para>
+      <para id="x_1cd">The <command role="hg-cmd">hg copy</command>
+	command acts similarly to the Unix <command>cp</command>
+	command (you can use the <command role="hg-cmd">hg
+	  cp</command> alias if you prefer).  We must supply two or
+	more arguments, of which the last is treated as the
+	<emphasis>destination</emphasis>, and all others are
+	<emphasis>sources</emphasis>.</para>
+
+      <para id="x_685">If you pass <command role="hg-cmd">hg copy</command> a
+	single file as the source, and the destination does not exist,
+	it creates a new file with that name.</para>
 
       &interaction.daily.copy.simple;
       
-      <para>If the destination is a directory, Mercurial copies its
+      <para id="x_1ce">If the destination is a directory, Mercurial copies its
 	sources into that directory.</para>
 
       &interaction.daily.copy.dir-dest;
 
-      <para>Copying a directory is
+      <para id="x_1cf">Copying a directory is
 	recursive, and preserves the directory structure of the
 	source.</para>
 
       &interaction.daily.copy.dir-src;
 
-      <para>If the source and destination are both directories, the
+      <para id="x_1d0">If the source and destination are both directories, the
 	source tree is recreated in the destination directory.</para>
 
 	&interaction.daily.copy.dir-src-dest;
 
-      <para>As with the <command role="hg-cmd">hg rename</command>
+      <para id="x_1d1">As with the <command role="hg-cmd">hg remove</command>
 	command, if you copy a file manually and then want Mercurial
 	to know that you've copied the file, simply use the <option
 	  role="hg-opt-copy">--after</option> option to <command
 	  role="hg-cmd">hg copy</command>.</para>
 
       &interaction.daily.copy.after;
-
     </sect2>
   </sect1>
+
   <sect1>
     <title>Renaming files</title>
 
-    <para>It's rather more common to need to rename a file than to
+    <para id="x_1d2">It's rather more common to need to rename a file than to
       make a copy of it.  The reason I discussed the <command
 	role="hg-cmd">hg copy</command> command before talking about
       renaming files is that Mercurial treats a rename in essentially
       when you copy a file tells you what to expect when you rename a
       file.</para>
 
-    <para>When you use the <command role="hg-cmd">hg rename</command>
+    <para id="x_1d3">When you use the <command role="hg-cmd">hg rename</command>
       command, Mercurial makes a copy of each source file, then
       deletes it and marks the file as removed.</para>
 
       &interaction.daily.rename.rename;
 
-    <para>The <command role="hg-cmd">hg status</command> command shows
+    <para id="x_1d4">The <command role="hg-cmd">hg status</command> command shows
       the newly copied file as added, and the copied-from file as
       removed.</para>
 
     &interaction.daily.rename.status;
 
-    <para>As with the results of a <command role="hg-cmd">hg
+    <para id="x_1d5">As with the results of a <command role="hg-cmd">hg
 	copy</command>, we must use the <option
 	role="hg-opt-status">-C</option> option to <command
 	role="hg-cmd">hg status</command> to see that the added file
 
     &interaction.daily.rename.status-copy;
 
-    <para>As with <command role="hg-cmd">hg remove</command> and
+    <para id="x_1d6">As with <command role="hg-cmd">hg remove</command> and
       <command role="hg-cmd">hg copy</command>, you can tell Mercurial
       about a rename after the fact using the <option
 	role="hg-opt-rename">--after</option> option.  In most other
-      respects, the behaviour of the <command role="hg-cmd">hg
+      respects, the behavior of the <command role="hg-cmd">hg
 	rename</command> command, and the options it accepts, are
       similar to the <command role="hg-cmd">hg copy</command>
       command.</para>
 
+    <para id="x_686">If you're familiar with the Unix command line, you'll be
+      glad to know that <command role="hg-cmd">hg rename</command>
+      command can be invoked as <command role="hg-cmd">hg
+	mv</command>.</para>
+
     <sect2>
       <title>Renaming files and merging changes</title>
 
-      <para>Since Mercurial's rename is implemented as
+      <para id="x_1d7">Since Mercurial's rename is implemented as
 	copy-and-remove, the same propagation of changes happens when
 	you merge after a rename as after a copy.</para>
 
-      <para>If I modify a file, and you rename it to a new name, and
+      <para id="x_1d8">If I modify a file, and you rename it to a new name, and
 	then we merge our respective changes, my modifications to the
 	file under its original name will be propagated into the file
 	under its new name. (This is something you might expect to
 	<quote>simply work,</quote> but not all revision control
 	systems actually do this.)</para>
 
-      <para>Whereas having changes follow a copy is a feature where
+      <para id="x_1d9">Whereas having changes follow a copy is a feature where
 	you can perhaps nod and say <quote>yes, that might be
 	  useful,</quote> it should be clear that having them follow a
 	rename is definitely important.  Without this facility, it
 	would simply be too easy for changes to become orphaned when
 	files are renamed.</para>
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>Divergent renames and merging</title>
 
-      <para>The case of diverging names occurs when two developers
+      <para id="x_1da">The case of diverging names occurs when two developers
 	start with a file&emdash;let's call it
 	<filename>foo</filename>&emdash;in their respective
 	repositories.</para>
 
       &interaction.rename.divergent.clone;
 
-      <para>Anne renames the file to <filename>bar</filename>.</para>
+      <para id="x_1db">Anne renames the file to <filename>bar</filename>.</para>
 
       &interaction.rename.divergent.rename.anne;
 
-      <para>Meanwhile, Bob renames it to
-	<filename>quux</filename>.</para>
+      <para id="x_1dc">Meanwhile, Bob renames it to
+	<filename>quux</filename>. (Remember that <command
+	  role="hg-cmd">hg mv</command> is an alias for <command
+	  role="hg-cmd">hg rename</command>.)</para>
 
 	&interaction.rename.divergent.rename.bob;
 
-      <para>I like to think of this as a conflict because each
+      <para id="x_1dd">I like to think of this as a conflict because each
 	developer has expressed different intentions about what the
 	file ought to be named.</para>
 
-      <para>What do you think should happen when they merge their
-	work? Mercurial's actual behaviour is that it always preserves
+      <para id="x_1de">What do you think should happen when they merge their
+	work? Mercurial's actual behavior is that it always preserves
 	<emphasis>both</emphasis> names when it merges changesets that
 	contain divergent renames.</para>
 
       &interaction.rename.divergent.merge;
 
-      <para>Notice that Mercurial does warn about the divergent
-	renames, but it leaves it up to you to do something about the
+      <para id="x_1df">Notice that while Mercurial warns about the divergent
+	renames, it leaves it up to you to do something about the
 	divergence after the merge.</para>
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>Convergent renames and merging</title>
 
-      <para>Another kind of rename conflict occurs when two people
+      <para id="x_1e0">Another kind of rename conflict occurs when two people
 	choose to rename different <emphasis>source</emphasis> files
 	to the same <emphasis>destination</emphasis>. In this case,
 	Mercurial runs its normal merge machinery, and lets you guide
 	it to a suitable resolution.</para>
+    </sect2>
 
-    </sect2>
     <sect2>
       <title>Other name-related corner cases</title>
 
-      <para>Mercurial has a longstanding bug in which it fails to
+      <para id="x_1e1">Mercurial has a longstanding bug in which it fails to
 	handle a merge where one side has a file with a given name,
 	while another has a directory with the same name.  This is
 	documented as <ulink role="hg-bug"
 
     </sect2>
   </sect1>
+
   <sect1>
     <title>Recovering from mistakes</title>
 
-    <para>Mercurial has some useful commands that will help you to
+    <para id="x_1e2">Mercurial has some useful commands that will help you to
       recover from some common mistakes.</para>
 
-    <para>The <command role="hg-cmd">hg revert</command> command lets
+    <para id="x_1e3">The <command role="hg-cmd">hg revert</command> command lets
       you undo changes that you have made to your working directory.
       For example, if you <command role="hg-cmd">hg add</command> a
       file by accident, just run <command role="hg-cmd">hg
       <command role="hg-cmd">hg revert</command> to get rid of
       erroneous changes to a file.</para>
 
-    <para>It's useful to remember that the <command role="hg-cmd">hg
-	revert</command> command is useful for changes that you have
-      not yet committed.  Once you've committed a change, if you
-      decide it was a mistake, you can still do something about it,
-      though your options may be more limited.</para>
+    <para id="x_1e4">It is helpful to remember that the <command
+	role="hg-cmd">hg revert</command> command is useful for
+      changes that you have not yet committed.  Once you've committed
+      a change, if you decide it was a mistake, you can still do
+      something about it, though your options may be more
+      limited.</para>
 
-    <para>For more information about the <command role="hg-cmd">hg
-	revert</command> command, and details about how to deal with
-      changes you have already committed, see chapter <xref
-	linkend="chap.undo"/>.</para>
+    <para id="x_1e5">For more information about the <command
+	role="hg-cmd">hg revert</command> command, and details about
+      how to deal with changes you have already committed, see <xref
+	linkend="chap:undo"/>.</para>
+  </sect1>
 
+  <sect1>
+    <title>Dealing with tricky merges</title>
+
+    <para id="x_687">In a complicated or large project, it's not unusual for a
+      merge of two changesets to result in some headaches.  Suppose
+      there's a big source file that's been extensively edited by each
+      side of a merge: this is almost inevitably going to result in
+      conflicts, some of which can take a few tries to sort
+      out.</para>
+
+    <para id="x_688">Let's develop a simple case of this and see how to deal with
+      it.  We'll start off with a repository containing one file, and
+      clone it twice.</para>
+
+    &interaction.ch04-resolve.init;
+
+    <para id="x_689">In one clone, we'll modify the file in one way.</para>
+
+    &interaction.ch04-resolve.left;
+
+    <para id="x_68a">In another, we'll modify the file differently.</para>
+
+    &interaction.ch04-resolve.right;
+
+    <para id="x_68b">Next, we'll pull each set of changes into our original
+      repo.</para>
+
+    &interaction.ch04-resolve.pull;
+
+    <para id="x_68c">We expect our repository to now contain two heads.</para>
+
+    &interaction.ch04-resolve.heads;
+
+    <para id="x_68d">Normally, if we run <command role="hg-cmd">hg
+	merge</command> at this point, it will drop us into a GUI that
+      will let us manually resolve the conflicting edits to
+      <filename>myfile.txt</filename>.  However, to simplify things
+      for presentation here, we'd like the merge to fail immediately
+      instead.  Here's one way we can do so.</para>
+
+    &interaction.ch04-resolve.export;
+
+    <para id="x_68e">We've told Mercurial's merge machinery to run the command
+      <command>false</command> (which, as we desire, fails
+      immediately) if it detects a merge that it can't sort out
+      automatically.</para>
+
+    <para id="x_68f">If we now fire up <command role="hg-cmd">hg
+	merge</command>, it should grind to a halt and report a
+	failure.</para>
+
+    &interaction.ch04-resolve.merge;
+
+    <para id="x_690">Even if we don't notice that the merge failed, Mercurial
+      will prevent us from accidentally committing the result of a
+      failed merge.</para>
+
+    &interaction.ch04-resolve.cifail;
+
+    <para id="x_691">When <command role="hg-cmd">hg commit</command> fails in
+      this case, it suggests that we use the unfamiliar <command
+	role="hg-cmd">hg resolve</command> command.  As usual,
+	<command role="hg-cmd">hg help resolve</command> will print a
+      helpful synopsis.</para>
+
+    <sect2>
+      <title>File resolution states</title>
+
+      <para id="x_692">When a merge occurs, most files will usually remain
+	unmodified.  For each file where Mercurial has to do
+	something, it tracks the state of the file.</para>
+
+      <itemizedlist>
+	<listitem>
+	  <para id="x_693">A <emphasis>resolved</emphasis> file has been
+	    successfully merged, either automatically by Mercurial or
+	    manually with human intervention.</para>
+	</listitem>
+	<listitem>
+	  <para id="x_694">An <emphasis>unresolved</emphasis> file was not merged
+	    successfully, and needs more attention.</para>
+	</listitem>
+      </itemizedlist>
+
+      <para id="x_695">If Mercurial sees <emphasis>any</emphasis> file in the
+	unresolved state after a merge, it considers the merge to have
+	failed.  Fortunately, we do not need to restart the entire
+	merge from scratch.</para>
+
+      <para id="x_696">The <option role="hg-opt-resolve">--list</option> or
+	<option role="hg-opt-resolve">-l</option> option to <command
+	  role="hg-cmd">hg resolve</command> prints out the state of
+	each merged file.</para>
+
+      &interaction.ch04-resolve.list;
+
+      <para id="x_697">In the output from <command role="hg-cmd">hg
+	  resolve</command>, a resolved file is marked with
+	<literal>R</literal>, while an unresolved file is marked with
+	<literal>U</literal>.  If any files are listed with
+	<literal>U</literal>, we know that an attempt to commit the
+	results of the merge will fail.</para>
+    </sect2>
+
+    <sect2>
+      <title>Resolving a file merge</title>
+
+      <para id="x_698">We have several options to move a file from the unresolved
+	into the resolved state.  By far the most common is to rerun
+	<command role="hg-cmd">hg resolve</command>.  If we pass the
+	names of individual files or directories, it will retry the
+	merges of any unresolved files present in those locations. We
+	can also pass the <option role="hg-opt-resolve">--all</option>
+	or <option role="hg-opt-resolve">-a</option> option, which
+	will retry the merges of <emphasis>all</emphasis> unresolved
+	files.</para>
+
+      <para id="x_699">Mercurial also lets us modify the resolution state of a
+	file directly.  We can manually mark a file as resolved using
+	the <option role="hg-opt-resolve">--mark</option> option, or
+	as unresolved using the <option
+	  role="hg-opt-resolve">--unmark</option> option.  This allows
+	us to clean up a particularly messy merge by hand, and to keep
+	track of our progress with each file as we go.</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>More useful diffs</title>
+
+    <para id="x_6c7">The default output of the <command role="hg-cmd">hg
+	diff</command> command is backwards compatible with the
+      regular <command>diff</command> command, but this has some
+      drawbacks.</para>
+
+    <para id="x_6c8">Consider the case where we use <command role="hg-cmd">hg
+	rename</command> to rename a file.</para>
+
+    &interaction.ch04-diff.rename.basic;
+
+    <para id="x_6c9">The output of <command role="hg-cmd">hg diff</command> above
+      obscures the fact that we simply renamed a file.  The <command
+	role="hg-cmd">hg diff</command> command accepts an option,
+      <option>--git</option> or <option>-g</option>, to use a newer
+      diff format that displays such information in a more readable
+      form.</para>
+
+    &interaction.ch04-diff.rename.git;
+
+    <para id="x_6ca">This option also helps with a case that can otherwise be
+      confusing: a file that appears to be modified according to
+      <command role="hg-cmd">hg status</command>, but for which
+      <command role="hg-cmd">hg diff</command> prints nothing. This
+      situation can arise if we change the file's execute
+      permissions.</para>
+
+    &interaction.ch04-diff.chmod;
+
+    <para id="x_6cb">The normal <command>diff</command> command pays no attention
+      to file permissions, which is why <command role="hg-cmd">hg
+	diff</command> prints nothing by default.  If we supply it
+      with the <option>-g</option> option, it tells us what really
+      happened.</para>
+
+    &interaction.ch04-diff.chmod.git;
+  </sect1>
+
+  <sect1>
+    <title>Which files to manage, and which to avoid</title>
+
+    <para id="x_6cc">Revision control systems are generally best at managing text
+      files that are written by humans, such as source code, where the
+      files do not change much from one revision to the next.  Some
+      centralized revision control systems can also deal tolerably
+      well with binary files, such as bitmap images.</para>
+
+    <para id="x_6cd">For instance, a game development team will typically manage
+      both its source code and all of its binary assets (e.g. geometry
+      data, textures, map layouts) in a revision control
+      system.</para>
+
+    <para id="x_6ce">Because it is usually impossible to merge two conflicting
+      modifications to a binary file, centralized systems often
+      provide a file locking mechanism that allow a user to say
+      <quote>I am the only person who can edit this
+	file</quote>.</para>
+
+    <para id="x_6cf">Compared to a centralized system, a distributed revision
+      control system changes some of the factors that guide decisions
+      over which files to manage and how.</para>
+
+    <para id="x_6d0">For instance, a distributed revision control system cannot,
+      by its nature, offer a file locking facility.  There is thus no
+      built-in mechanism to prevent two people from making conflicting
+      changes to a binary file.  If you have a team where several
+      people may be editing binary files frequently, it may not be a
+      good idea to use Mercurial&emdash;or any other distributed
+      revision control system&emdash;to manage those files.</para>
+
+    <para id="x_6d1">When storing modifications to a file, Mercurial usually
+      saves only the differences between the previous and current
+      versions of the file.  For most text files, this is extremely
+      efficient. However, some files (particularly binary files) are
+      laid out in such a way that even a small change to a file's
+      logical content results in many or most of the bytes inside the
+      file changing.  For instance, compressed files are particularly
+      susceptible to this. If the differences between each successive
+      version of a file are always large, Mercurial will not be able
+      to store the file's revision history very efficiently.  This can
+      affect both local storage needs and the amount of time it takes
+      to clone a repository.</para>
+
+    <para id="x_6d2">To get an idea of how this could affect you in practice,
+      suppose you want to use Mercurial to manage an OpenOffice
+      document.  OpenOffice stores documents on disk as compressed zip
+      files. Edit even a single letter of your document in OpenOffice,
+      and almost every byte in the entire file will change when you
+      save it. Now suppose that file is 2MB in size.  Because most of
+      the file changes every time you save, Mercurial will have to
+      store all 2MB of the file every time you commit, even though
+      from your perspective, perhaps only a few words are changing
+      each time.  A single frequently-edited file that is not friendly
+      to Mercurial's storage assumptions can easily have an outsized
+      effect on the size of the repository.</para>
+
+    <para id="x_6d3">Even worse, if both you and someone else edit the OpenOffice
+      document you're working on, there is no useful way to merge your
+      work. In fact, there isn't even a good way to tell what the
+      differences are between your respective changes.</para>
+
+    <para id="x_6d4">There are thus a few clear recommendations about specific
+      kinds of files to be very careful with.</para>
+
+    <itemizedlist>
+      <listitem>
+	<para id="x_6d5">Files that are very large and incompressible, e.g. ISO
+	  CD-ROM images, will by virtue of sheer size make clones over
+	  a network very slow.</para>
+      </listitem>
+      <listitem>
+	<para id="x_6d6">Files that change a lot from one revision to the next
+	  may be expensive to store if you edit them frequently, and
+	  conflicts due to concurrent edits may be difficult to
+	  resolve.</para>
+      </listitem>
+    </itemizedlist>
+  </sect1>
+
+  <sect1>
+    <title>Backups and mirroring</title>
+
+    <para id="x_6d7">Since Mercurial maintains a complete copy of history in each
+      clone, everyone who uses Mercurial to collaborate on a project
+      can potentially act as a source of backups in the event of a
+      catastrophe.  If a central repository becomes unavailable, you
+      can construct a replacement simply by cloning a copy of the
+      repository from one contributor, and pulling any changes they
+      may not have seen from others.</para>
+
+    <para id="x_6d8">It is simple to use Mercurial to perform off-site backups
+      and remote mirrors.  Set up a periodic job (e.g. via the
+      <command>cron</command> command) on a remote server to pull
+      changes from your master repositories every hour.  This will
+      only be tricky in the unlikely case that the number of master
+      repositories you maintain changes frequently, in which case
+      you'll need to do a little scripting to refresh the list of
+      repositories to back up.</para>
+
+    <para id="x_6d9">If you perform traditional backups of your master
+      repositories to tape or disk, and you want to back up a
+      repository named <filename>myrepo</filename>, use <command>hg
+	clone -U myrepo myrepo.bak</command> to create a
+      clone of <filename>myrepo</filename> before you start your
+      backups.  The <option>-U</option> option doesn't check out a
+      working directory after the clone completes, since that would be
+      superfluous and make the backup take longer.</para>
+
+    <para id="x_6da">If you then back up <filename>myrepo.bak</filename> instead
+      of <filename>myrepo</filename>, you will be guaranteed to have a
+      consistent snapshot of your repository that won't be pushed to
+      by an insomniac developer in mid-backup.</para>
   </sect1>
 </chapter>