hgbook

changeset 650:7e7c47481e4f

Oops, this is the real merge for my hg's oddity
author Dongsheng Song <dongsheng.song@gmail.com>
date Fri Mar 20 16:43:35 2009 +0800 (2009-03-20)
parents d13c7c706a58
children c15e039d98b8
files .hgignore en/00book.xml en/Makefile en/appA-cmdref.xml en/appB-mq-ref.xml en/appC-srcinstall.xml en/appD-license.xml en/autoid.py en/ch00-preface.xml en/ch01-intro.xml en/ch01-tour-basic.xml en/ch02-tour-basic.xml en/ch02-tour-merge.xml en/ch03-concepts.xml en/ch03-tour-merge.xml en/ch04-concepts.xml en/ch04-daily.xml en/ch05-collab.xml en/ch05-daily.xml en/ch06-collab.xml en/ch06-filenames.xml en/ch07-branch.xml en/ch07-filenames.xml en/ch08-branch.xml en/ch08-undo.xml en/ch09-hook.xml en/ch09-undo.xml en/ch10-hook.xml en/ch10-template.xml en/ch11-mq.xml en/ch11-template.xml en/ch12-mq-collab.xml en/ch12-mq.xml en/ch13-hgext.xml en/ch13-mq-collab.xml en/ch14-hgext.xml po/zh.po web/hgbook/dbutil.py web/hgbook/load_elements.py
line diff
     1.1 --- a/.hgignore	Fri Mar 20 15:40:06 2009 +0800
     1.2 +++ b/.hgignore	Fri Mar 20 16:43:35 2009 +0800
     1.3 @@ -19,6 +19,7 @@
     1.4  .\#*
     1.5  .run
     1.6  .validated-00book.xml
     1.7 +en/all-ids.dat
     1.8  web/hgbook/.database.sqlite3
     1.9  web/hgbook/secrets.py
    1.10  stylesheets/system-xsl
     2.1 --- a/en/00book.xml	Fri Mar 20 15:40:06 2009 +0800
     2.2 +++ b/en/00book.xml	Fri Mar 20 16:43:35 2009 +0800
     2.3 @@ -7,20 +7,20 @@
     2.4  
     2.5  <!-- Chapters. -->
     2.6  
     2.7 -<!ENTITY ch01     SYSTEM "ch01-intro.xml">
     2.8 -<!ENTITY ch02     SYSTEM "ch02-tour-basic.xml">
     2.9 -<!ENTITY ch03     SYSTEM "ch03-tour-merge.xml">
    2.10 -<!ENTITY ch04     SYSTEM "ch04-concepts.xml">
    2.11 -<!ENTITY ch05     SYSTEM "ch05-daily.xml">
    2.12 -<!ENTITY ch06     SYSTEM "ch06-collab.xml">
    2.13 -<!ENTITY ch07     SYSTEM "ch07-filenames.xml">
    2.14 -<!ENTITY ch08     SYSTEM "ch08-branch.xml">
    2.15 -<!ENTITY ch09     SYSTEM "ch09-undo.xml">
    2.16 -<!ENTITY ch10     SYSTEM "ch10-hook.xml">
    2.17 -<!ENTITY ch11     SYSTEM "ch11-template.xml">
    2.18 -<!ENTITY ch12     SYSTEM "ch12-mq.xml">
    2.19 -<!ENTITY ch13     SYSTEM "ch13-mq-collab.xml">
    2.20 -<!ENTITY ch14     SYSTEM "ch14-hgext.xml">
    2.21 +<!ENTITY ch00     SYSTEM "ch00-preface.xml">
    2.22 +<!ENTITY ch01     SYSTEM "ch01-tour-basic.xml">
    2.23 +<!ENTITY ch02     SYSTEM "ch02-tour-merge.xml">
    2.24 +<!ENTITY ch03     SYSTEM "ch03-concepts.xml">
    2.25 +<!ENTITY ch04     SYSTEM "ch04-daily.xml">
    2.26 +<!ENTITY ch05     SYSTEM "ch05-collab.xml">
    2.27 +<!ENTITY ch06     SYSTEM "ch06-filenames.xml">
    2.28 +<!ENTITY ch07     SYSTEM "ch07-branch.xml">
    2.29 +<!ENTITY ch08     SYSTEM "ch08-undo.xml">
    2.30 +<!ENTITY ch09     SYSTEM "ch09-hook.xml">
    2.31 +<!ENTITY ch10     SYSTEM "ch10-template.xml">
    2.32 +<!ENTITY ch11     SYSTEM "ch11-mq.xml">
    2.33 +<!ENTITY ch12     SYSTEM "ch12-mq-collab.xml">
    2.34 +<!ENTITY ch13     SYSTEM "ch13-hgext.xml">
    2.35  <!ENTITY appA     SYSTEM "appA-cmdref.xml">
    2.36  <!ENTITY appB     SYSTEM "appB-mq-ref.xml">
    2.37  <!ENTITY appC     SYSTEM "appC-srcinstall.xml">
    2.38 @@ -79,7 +79,6 @@
    2.39    &ch11;
    2.40    &ch12;
    2.41    &ch13;
    2.42 -  &ch14;
    2.43    <!-- &appA; -->
    2.44    &appB;
    2.45    &appC;
     3.1 --- a/en/Makefile	Fri Mar 20 15:40:06 2009 +0800
     3.2 +++ b/en/Makefile	Fri Mar 20 16:43:35 2009 +0800
     3.3 @@ -130,21 +130,24 @@
     3.4  
     3.5  all: web
     3.6  
     3.7 -../stylesheets/system-xsl: $(system-xsl-dir)
     3.8 +../xsl/system-xsl: $(system-xsl-dir)
     3.9  	ln -s $< $@
    3.10  
    3.11  web: ../xsl/system-xsl websup html
    3.12  
    3.13 -html: ../stylesheets/system-xsl $(xml-src-files) valid
    3.14 -	xsltproc $(xsltproc-opts) -o html/read/x ../stylesheets/chunk-stylesheet.xsl 00book.xml
    3.15 +html: ../xsl/system-xsl $(xml-src-files) valid
    3.16 +	xsltproc $(xsltproc-opts) -o html/read/x ../xsl/chunk-stylesheet.xsl 00book.xml
    3.17  	for i in html/read/*.html; do \
    3.18  	  gzip -9 -c $$i > $$i.gz; \
    3.19  	done
    3.20  
    3.21  websup: $(extras-web)
    3.22 -	mkdir -p $(obj-websup)/images
    3.23 -	cp ../stylesheets/system-xsl/images/*.png $(obj-websup)/images
    3.24 -	cp -f ../web/icons/*.png $(obj-websup)/images
    3.25 +	mkdir -p $(obj-websup)/figs
    3.26 +	cp ../xsl/system-xsl/images/*.png $(obj-websup)/figs
    3.27 +	cp -f ../web/icons/*.png $(obj-websup)/figs
    3.28 +
    3.29 +all-ids.dat: ../xsl/all-ids.xsl $(xml-src-files)
    3.30 +	$(xsltproc) $(xsltproc-opts) -o $@ ../xsl/all-ids.xsl 00book.xml
    3.31  
    3.32  web: websup
    3.33  
     4.1 --- a/en/appA-cmdref.xml	Fri Mar 20 15:40:06 2009 +0800
     4.2 +++ b/en/appA-cmdref.xml	Fri Mar 20 16:43:35 2009 +0800
     4.3 @@ -3,113 +3,113 @@
     4.4  <appendix id="cmdref">
     4.5  <title>Command reference</title>
     4.6  
     4.7 -<para>\cmdref{add}{add files at the next commit}
     4.8 +<para id="x_653">\cmdref{add}{add files at the next commit}
     4.9  \optref{add}{I}{include}
    4.10  \optref{add}{X}{exclude}
    4.11  \optref{add}{n}{dry-run}</para>
    4.12  
    4.13 -<para>\cmdref{diff}{print changes in history or working directory}</para>
    4.14 -
    4.15 -<para>Show differences between revisions for the specified files or
    4.16 +<para id="x_654">\cmdref{diff}{print changes in history or working directory}</para>
    4.17 +
    4.18 +<para id="x_655">Show differences between revisions for the specified files or
    4.19  directories, using the unified diff format.  For a description of the
    4.20  unified diff format, see section <xref linkend="sec.mq.patch"/>.</para>
    4.21  
    4.22 -<para>By default, this command does not print diffs for files that Mercurial
    4.23 +<para id="x_656">By default, this command does not print diffs for files that Mercurial
    4.24  considers to contain binary data.  To control this behaviour, see the
    4.25  <option role="hg-opt-diff">-a</option> and <option role="hg-opt-diff">--git</option> options.</para>
    4.26  
    4.27  <sect2>
    4.28  <title>Options</title>
    4.29  
    4.30 -<para>\loptref{diff}{nodates}</para>
    4.31 -
    4.32 -<para>Omit date and time information when printing diff headers.</para>
    4.33 -
    4.34 -<para>\optref{diff}{B}{ignore-blank-lines}</para>
    4.35 -
    4.36 -<para>Do not print changes that only insert or delete blank lines.  A line
    4.37 +<para id="x_657">\loptref{diff}{nodates}</para>
    4.38 +
    4.39 +<para id="x_658">Omit date and time information when printing diff headers.</para>
    4.40 +
    4.41 +<para id="x_659">\optref{diff}{B}{ignore-blank-lines}</para>
    4.42 +
    4.43 +<para id="x_65a">Do not print changes that only insert or delete blank lines.  A line
    4.44  that contains only whitespace is not considered blank.
    4.45  </para>
    4.46  
    4.47 -<para>\optref{diff}{I}{include}
    4.48 -</para>
    4.49 -
    4.50 -<para>Include files and directories whose names match the given patterns.
    4.51 -</para>
    4.52 -
    4.53 -<para>\optref{diff}{X}{exclude}
    4.54 -</para>
    4.55 -
    4.56 -<para>Exclude files and directories whose names match the given patterns.
    4.57 -</para>
    4.58 -
    4.59 -<para>\optref{diff}{a}{text}
    4.60 -</para>
    4.61 -
    4.62 -<para>If this option is not specified, <command role="hg-cmd">hg diff</command> will refuse to print
    4.63 +<para id="x_65b">\optref{diff}{I}{include}
    4.64 +</para>
    4.65 +
    4.66 +<para id="x_65c">Include files and directories whose names match the given patterns.
    4.67 +</para>
    4.68 +
    4.69 +<para id="x_65d">\optref{diff}{X}{exclude}
    4.70 +</para>
    4.71 +
    4.72 +<para id="x_65e">Exclude files and directories whose names match the given patterns.
    4.73 +</para>
    4.74 +
    4.75 +<para id="x_65f">\optref{diff}{a}{text}
    4.76 +</para>
    4.77 +
    4.78 +<para id="x_660">If this option is not specified, <command role="hg-cmd">hg diff</command> will refuse to print
    4.79  diffs for files that it detects as binary. Specifying <option role="hg-opt-diff">-a</option>
    4.80  forces <command role="hg-cmd">hg diff</command> to treat all files as text, and generate diffs for
    4.81  all of them.
    4.82  </para>
    4.83  
    4.84 -<para>This option is useful for files that are <quote>mostly text</quote> but have a
    4.85 +<para id="x_661">This option is useful for files that are <quote>mostly text</quote> but have a
    4.86  few embedded NUL characters.  If you use it on files that contain a
    4.87  lot of binary data, its output will be incomprehensible.
    4.88  </para>
    4.89  
    4.90 -<para>\optref{diff}{b}{ignore-space-change}
    4.91 -</para>
    4.92 -
    4.93 -<para>Do not print a line if the only change to that line is in the amount
    4.94 +<para id="x_662">\optref{diff}{b}{ignore-space-change}
    4.95 +</para>
    4.96 +
    4.97 +<para id="x_663">Do not print a line if the only change to that line is in the amount
    4.98  of white space it contains.
    4.99  </para>
   4.100  
   4.101 -<para>\optref{diff}{g}{git}
   4.102 -</para>
   4.103 -
   4.104 -<para>Print <command>git</command>-compatible diffs.  XXX reference a format
   4.105 +<para id="x_664">\optref{diff}{g}{git}
   4.106 +</para>
   4.107 +
   4.108 +<para id="x_665">Print <command>git</command>-compatible diffs.  XXX reference a format
   4.109  description.
   4.110  </para>
   4.111  
   4.112 -<para>\optref{diff}{p}{show-function}
   4.113 -</para>
   4.114 -
   4.115 -<para>Display the name of the enclosing function in a hunk header, using a
   4.116 +<para id="x_666">\optref{diff}{p}{show-function}
   4.117 +</para>
   4.118 +
   4.119 +<para id="x_667">Display the name of the enclosing function in a hunk header, using a
   4.120  simple heuristic.  This functionality is enabled by default, so the
   4.121  <option role="hg-opt-diff">-p</option> option has no effect unless you change the value of
   4.122  the <envar role="rc-item-diff">showfunc</envar> config item, as in the following example.</para>
   4.123  
   4.124  <!-- &interaction.cmdref.diff-p; -->
   4.125  
   4.126 -<para>\optref{diff}{r}{rev}
   4.127 -</para>
   4.128 -
   4.129 -<para>Specify one or more revisions to compare.  The <command role="hg-cmd">hg diff</command> command
   4.130 +<para id="x_668">\optref{diff}{r}{rev}
   4.131 +</para>
   4.132 +
   4.133 +<para id="x_669">Specify one or more revisions to compare.  The <command role="hg-cmd">hg diff</command> command
   4.134  accepts up to two <option role="hg-opt-diff">-r</option> options to specify the revisions to
   4.135  compare.
   4.136  </para>
   4.137  
   4.138  <orderedlist>
   4.139 -<listitem><para>Display the differences between the parent revision of the
   4.140 +<listitem><para id="x_66a">Display the differences between the parent revision of the
   4.141    working directory and the working directory.
   4.142  </para>
   4.143  </listitem>
   4.144 -<listitem><para>Display the differences between the specified changeset and the
   4.145 +<listitem><para id="x_66b">Display the differences between the specified changeset and the
   4.146    working directory.
   4.147  </para>
   4.148  </listitem>
   4.149 -<listitem><para>Display the differences between the two specified changesets.
   4.150 +<listitem><para id="x_66c">Display the differences between the two specified changesets.
   4.151  </para>
   4.152  </listitem></orderedlist>
   4.153  
   4.154 -<para>You can specify two revisions using either two <option role="hg-opt-diff">-r</option>
   4.155 +<para id="x_66d">You can specify two revisions using either two <option role="hg-opt-diff">-r</option>
   4.156  options or revision range notation.  For example, the two revision
   4.157  specifications below are equivalent.
   4.158  </para>
   4.159  <programlisting>hg diff -r 10 -r 20
   4.160  hg diff -r10:20</programlisting>
   4.161  
   4.162 -<para>When you provide two revisions, Mercurial treats the order of those
   4.163 +<para id="x_66e">When you provide two revisions, Mercurial treats the order of those
   4.164  revisions as significant.  Thus, <command role="hg-cmd">hg diff -r10:20</command> will
   4.165  produce a diff that will transform files from their contents as of
   4.166  revision 10 to their contents as of revision 20, while
   4.167 @@ -119,23 +119,23 @@
   4.168  diffing against the working directory.
   4.169  </para>
   4.170  
   4.171 -<para>\optref{diff}{w}{ignore-all-space}
   4.172 -</para>
   4.173 -
   4.174 -<para>\cmdref{version}{print version and copyright information}
   4.175 -</para>
   4.176 -
   4.177 -<para>This command displays the version of Mercurial you are running, and
   4.178 +<para id="x_66f">\optref{diff}{w}{ignore-all-space}
   4.179 +</para>
   4.180 +
   4.181 +<para id="x_670">\cmdref{version}{print version and copyright information}
   4.182 +</para>
   4.183 +
   4.184 +<para id="x_671">This command displays the version of Mercurial you are running, and
   4.185  its copyright license.  There are four kinds of version string that
   4.186  you may see.
   4.187  </para>
   4.188  <itemizedlist>
   4.189 -<listitem><para>The string <quote><literal>unknown</literal></quote>. This version of Mercurial was
   4.190 +<listitem><para id="x_672">The string <quote><literal>unknown</literal></quote>. This version of Mercurial was
   4.191    not built in a Mercurial repository, and cannot determine its own
   4.192    version.
   4.193  </para>
   4.194  </listitem>
   4.195 -<listitem><para>A short numeric string, such as <quote><literal>1.1</literal></quote>. This is a
   4.196 +<listitem><para id="x_673">A short numeric string, such as <quote><literal>1.1</literal></quote>. This is a
   4.197    build of a revision of Mercurial that was identified by a specific
   4.198    tag in the repository where it was built.  (This doesn't necessarily
   4.199    mean that you're running an official release; someone else could
   4.200 @@ -143,11 +143,11 @@
   4.201    built Mercurial.)
   4.202  </para>
   4.203  </listitem>
   4.204 -<listitem><para>A hexadecimal string, such as <quote><literal>875489e31abe</literal></quote>.  This
   4.205 +<listitem><para id="x_674">A hexadecimal string, such as <quote><literal>875489e31abe</literal></quote>.  This
   4.206    is a build of the given revision of Mercurial.
   4.207  </para>
   4.208  </listitem>
   4.209 -<listitem><para>A hexadecimal string followed by a date, such as
   4.210 +<listitem><para id="x_675">A hexadecimal string followed by a date, such as
   4.211    <quote><literal>875489e31abe+20070205</literal></quote>.  This is a build of the given
   4.212    revision of Mercurial, where the build repository contained some
   4.213    local changes that had not been committed.
   4.214 @@ -161,14 +161,14 @@
   4.215  <sect3 id="cmdref.diff-vs-status">
   4.216  <title>Why do the results of <command role="hg-cmd">hg diff</command> and <command role="hg-cmd">hg status</command> differ?</title>
   4.217  
   4.218 -<para>When you run the <command role="hg-cmd">hg status</command> command, you'll see a list of files
   4.219 +<para id="x_676">When you run the <command role="hg-cmd">hg status</command> command, you'll see a list of files
   4.220  that Mercurial will record changes for the next time you perform a
   4.221  commit.  If you run the <command role="hg-cmd">hg diff</command> command, you may notice that it
   4.222  prints diffs for only a <emphasis>subset</emphasis> of the files that <command role="hg-cmd">hg status</command>
   4.223  listed.  There are two possible reasons for this.
   4.224  </para>
   4.225  
   4.226 -<para>The first is that <command role="hg-cmd">hg status</command> prints some kinds of modifications
   4.227 +<para id="x_677">The first is that <command role="hg-cmd">hg status</command> prints some kinds of modifications
   4.228  that <command role="hg-cmd">hg diff</command> doesn't normally display.  The <command role="hg-cmd">hg diff</command> command
   4.229  normally outputs unified diffs, which don't have the ability to
   4.230  represent some changes that Mercurial can track.  Most notably,
   4.231 @@ -176,12 +176,12 @@
   4.232  executable, but Mercurial records this information.
   4.233  </para>
   4.234  
   4.235 -<para>If you use the <option role="hg-opt-diff">--git</option> option to <command role="hg-cmd">hg diff</command>, it will
   4.236 +<para id="x_678">If you use the <option role="hg-opt-diff">--git</option> option to <command role="hg-cmd">hg diff</command>, it will
   4.237  display <command>git</command>-compatible diffs that <emphasis>can</emphasis> display this
   4.238  extra information.
   4.239  </para>
   4.240  
   4.241 -<para>The second possible reason that <command role="hg-cmd">hg diff</command> might be printing diffs
   4.242 +<para id="x_679">The second possible reason that <command role="hg-cmd">hg diff</command> might be printing diffs
   4.243  for a subset of the files displayed by <command role="hg-cmd">hg status</command> is that if you
   4.244  invoke it without any arguments, <command role="hg-cmd">hg diff</command> prints diffs against the
   4.245  first parent of the working directory.  If you have run <command role="hg-cmd">hg merge</command>
   4.246 @@ -199,14 +199,14 @@
   4.247  <sect3>
   4.248  <title>Generating safe binary diffs</title>
   4.249  
   4.250 -<para>If you use the <option role="hg-opt-diff">-a</option> option to force Mercurial to print
   4.251 +<para id="x_67a">If you use the <option role="hg-opt-diff">-a</option> option to force Mercurial to print
   4.252  diffs of files that are either <quote>mostly text</quote> or contain lots of
   4.253  binary data, those diffs cannot subsequently be applied by either
   4.254  Mercurial's <command role="hg-cmd">hg import</command> command or the system's <command>patch</command>
   4.255  command.
   4.256  </para>
   4.257  
   4.258 -<para>If you want to generate a diff of a binary file that is safe to use as
   4.259 +<para id="x_67b">If you want to generate a diff of a binary file that is safe to use as
   4.260  input for <command role="hg-cmd">hg import</command>, use the <command role="hg-cmd">hg diff</command>{--git} option when you
   4.261  generate the patch.  The system <command>patch</command> command cannot handle
   4.262  binary patches at all.
     5.1 --- a/en/appB-mq-ref.xml	Fri Mar 20 15:40:06 2009 +0800
     5.2 +++ b/en/appB-mq-ref.xml	Fri Mar 20 16:43:35 2009 +0800
     5.3 @@ -7,14 +7,14 @@
     5.4    <sect1 id="sec.mqref.cmdref">
     5.5      <title>MQ command reference</title>
     5.6  
     5.7 -    <para>For an overview of the commands provided by MQ, use the
     5.8 +    <para id="x_5e8">For an overview of the commands provided by MQ, use the
     5.9        command <command role="hg-cmd">hg help mq</command>.</para>
    5.10  
    5.11      <sect2>
    5.12        <title><command role="hg-ext-mq">qapplied</command>&emdash;print
    5.13  	applied patches</title>
    5.14  
    5.15 -      <para>The <command role="hg-ext-mq">qapplied</command> command
    5.16 +      <para id="x_5e9">The <command role="hg-ext-mq">qapplied</command> command
    5.17  	prints the current stack of applied patches.  Patches are
    5.18  	printed in oldest-to-newest order, so the last patch in the
    5.19  	list is the <quote>top</quote> patch.</para>
    5.20 @@ -24,7 +24,7 @@
    5.21        <title><command role="hg-ext-mq">qcommit</command>&emdash;commit
    5.22  	changes in the queue repository</title>
    5.23  
    5.24 -      <para>The <command role="hg-ext-mq">qcommit</command> command
    5.25 +      <para id="x_5ea">The <command role="hg-ext-mq">qcommit</command> command
    5.26  	commits any outstanding changes in the <filename
    5.27  	  role="special" class="directory">.hg/patches</filename>
    5.28  	repository.  This command only works if the <filename
    5.29 @@ -36,7 +36,7 @@
    5.30  	after running <command
    5.31  	  role="hg-ext-mq">qinit</command>.</para>
    5.32  
    5.33 -      <para>This command is shorthand for <command role="hg-cmd">hg
    5.34 +      <para id="x_5eb">This command is shorthand for <command role="hg-cmd">hg
    5.35  	  commit --cwd .hg/patches</command>.</para>
    5.36      </sect2>
    5.37      <sect2>
    5.38 @@ -45,7 +45,7 @@
    5.39  	from the <filename role="special">series</filename>
    5.40  	file}</title>
    5.41  
    5.42 -      <para>The <command role="hg-ext-mq">qdelete</command> command
    5.43 +      <para id="x_5ec">The <command role="hg-ext-mq">qdelete</command> command
    5.44  	removes the entry for a patch from the <filename
    5.45  	  role="special">series</filename> file in the <filename
    5.46  	  role="special" class="directory">.hg/patches</filename>
    5.47 @@ -54,9 +54,9 @@
    5.48  	the <option role="hg-ext-mq-cmd-qdel-opt">-f</option> option
    5.49  	to do that.</para>
    5.50  
    5.51 -      <para>Options:</para>
    5.52 -      <itemizedlist>
    5.53 -	<listitem><para><option
    5.54 +      <para id="x_5ed">Options:</para>
    5.55 +      <itemizedlist>
    5.56 +	<listitem><para id="x_5ee"><option
    5.57  	      role="hg-ext-mq-cmd-qdel-opt">-f</option>: Delete the
    5.58  	    patch file.</para>
    5.59  	</listitem></itemizedlist>
    5.60 @@ -66,7 +66,7 @@
    5.61        <title><command role="hg-ext-mq">qdiff</command>&emdash;print a
    5.62  	diff of the topmost applied patch</title>
    5.63  
    5.64 -      <para>The <command role="hg-ext-mq">qdiff</command> command
    5.65 +      <para id="x_5ef">The <command role="hg-ext-mq">qdiff</command> command
    5.66  	prints a diff of the topmost applied patch. It is equivalent
    5.67  	to <command role="hg-cmd">hg diff -r-2:-1</command>.</para>
    5.68  
    5.69 @@ -75,12 +75,12 @@
    5.70        <title><command role="hg-ext-mq">qfold</command>&emdash;merge
    5.71  	(<quote>fold</quote>) several patches into one</title>
    5.72  
    5.73 -      <para>The <command role="hg-ext-mq">qfold</command> command
    5.74 +      <para id="x_5f0">The <command role="hg-ext-mq">qfold</command> command
    5.75  	merges multiple patches into the topmost applied patch, so
    5.76  	that the topmost applied patch makes the union of all of the
    5.77  	changes in the patches in question.</para>
    5.78  
    5.79 -      <para>The patches to fold must not be applied; <command
    5.80 +      <para id="x_5f1">The patches to fold must not be applied; <command
    5.81  	  role="hg-ext-mq">qfold</command> will exit with an error if
    5.82  	any is.  The order in which patches are folded is significant;
    5.83  	<command role="hg-cmd">hg qfold a b</command> means
    5.84 @@ -88,7 +88,7 @@
    5.85  	  <literal>a</literal>, followed by
    5.86  	  <literal>b</literal></quote>.</para>
    5.87  
    5.88 -      <para>The comments from the folded patches are appended to the
    5.89 +      <para id="x_5f2">The comments from the folded patches are appended to the
    5.90  	comments of the destination patch, with each block of comments
    5.91  	separated by three asterisk
    5.92  	(<quote><literal>*</literal></quote>) characters.  Use the
    5.93 @@ -96,19 +96,19 @@
    5.94  	edit the commit message for the combined patch/changeset after
    5.95  	the folding has completed.</para>
    5.96  
    5.97 -      <para>Options:</para>
    5.98 -      <itemizedlist>
    5.99 -	<listitem><para><option
   5.100 +      <para id="x_5f3">Options:</para>
   5.101 +      <itemizedlist>
   5.102 +	<listitem><para id="x_5f4"><option
   5.103  	      role="hg-ext-mq-cmd-qfold-opt">-e</option>: Edit the
   5.104  	    commit message and patch description for the newly folded
   5.105  	    patch.</para>
   5.106  	</listitem>
   5.107 -	<listitem><para><option
   5.108 +	<listitem><para id="x_5f5"><option
   5.109  	      role="hg-ext-mq-cmd-qfold-opt">-l</option>: Use the
   5.110  	    contents of the given file as the new commit message and
   5.111  	    patch description for the folded patch.</para>
   5.112  	</listitem>
   5.113 -	<listitem><para><option
   5.114 +	<listitem><para id="x_5f6"><option
   5.115  	      role="hg-ext-mq-cmd-qfold-opt">-m</option>: Use the
   5.116  	    given text as the new commit message and patch description
   5.117  	    for the folded patch.</para>
   5.118 @@ -120,7 +120,7 @@
   5.119  	  role="hg-ext-mq">qheader</command>&emdash;display the
   5.120  	header/description of a patch</title>
   5.121  
   5.122 -      <para>The <command role="hg-ext-mq">qheader</command> command
   5.123 +      <para id="x_5f7">The <command role="hg-ext-mq">qheader</command> command
   5.124  	prints the header, or description, of a patch.  By default, it
   5.125  	prints the header of the topmost applied patch. Given an
   5.126  	argument, it prints the header of the named patch.</para>
   5.127 @@ -130,7 +130,7 @@
   5.128        <title><command role="hg-ext-mq">qimport</command>&emdash;import
   5.129  	a third-party patch into the queue</title>
   5.130  
   5.131 -      <para>The <command role="hg-ext-mq">qimport</command> command
   5.132 +      <para id="x_5f8">The <command role="hg-ext-mq">qimport</command> command
   5.133  	adds an entry for an external patch to the <filename
   5.134  	  role="special">series</filename> file, and copies the patch
   5.135  	into the <filename role="special"
   5.136 @@ -138,7 +138,7 @@
   5.137  	the entry immediately after the topmost applied patch, but
   5.138  	does not push the patch.</para>
   5.139  
   5.140 -      <para>If the <filename role="special"
   5.141 +      <para id="x_5f9">If the <filename role="special"
   5.142  	  class="directory">.hg/patches</filename> directory is a
   5.143  	repository, <command role="hg-ext-mq">qimport</command>
   5.144  	automatically does an <command role="hg-cmd">hg add</command>
   5.145 @@ -149,14 +149,14 @@
   5.146        <title><command role="hg-ext-mq">qinit</command>&emdash;prepare
   5.147  	a repository to work with MQ</title>
   5.148  
   5.149 -      <para>The <command role="hg-ext-mq">qinit</command> command
   5.150 +      <para id="x_5fa">The <command role="hg-ext-mq">qinit</command> command
   5.151  	prepares a repository to work with MQ.  It creates a directory
   5.152  	called <filename role="special"
   5.153  	  class="directory">.hg/patches</filename>.</para>
   5.154  
   5.155 -      <para>Options:</para>
   5.156 -      <itemizedlist>
   5.157 -	<listitem><para><option
   5.158 +      <para id="x_5fb">Options:</para>
   5.159 +      <itemizedlist>
   5.160 +	<listitem><para id="x_5fc"><option
   5.161  	      role="hg-ext-mq-cmd-qinit-opt">-c</option>: Create
   5.162  	    <filename role="special"
   5.163  	      class="directory">.hg/patches</filename> as a repository
   5.164 @@ -166,7 +166,7 @@
   5.165  	    file.</para>
   5.166  	</listitem></itemizedlist>
   5.167  
   5.168 -      <para>When the <filename role="special"
   5.169 +      <para id="x_5fd">When the <filename role="special"
   5.170  	  class="directory">.hg/patches</filename> directory is a
   5.171  	repository, the <command role="hg-ext-mq">qimport</command>
   5.172  	and <command role="hg-ext-mq">qnew</command> commands
   5.173 @@ -178,7 +178,7 @@
   5.174        <title><command role="hg-ext-mq">qnew</command>&emdash;create a
   5.175  	new patch</title>
   5.176  
   5.177 -      <para>The <command role="hg-ext-mq">qnew</command> command
   5.178 +      <para id="x_5fe">The <command role="hg-ext-mq">qnew</command> command
   5.179  	creates a new patch.  It takes one mandatory argument, the
   5.180  	name to use for the patch file.  The newly created patch is
   5.181  	created empty by default.  It is added to the <filename
   5.182 @@ -186,7 +186,7 @@
   5.183  	topmost applied patch, and is immediately pushed on top of
   5.184  	that patch.</para>
   5.185  
   5.186 -      <para>If <command role="hg-ext-mq">qnew</command> finds modified
   5.187 +      <para id="x_5ff">If <command role="hg-ext-mq">qnew</command> finds modified
   5.188  	files in the working directory, it will refuse to create a new
   5.189  	patch unless the <option
   5.190  	  role="hg-ext-mq-cmd-qnew-opt">-f</option> option is used
   5.191 @@ -194,16 +194,16 @@
   5.192  	  role="hg-ext-mq">qrefresh</command> your topmost applied
   5.193  	patch before you apply a new patch on top of it.</para>
   5.194  
   5.195 -      <para>Options:</para>
   5.196 -      <itemizedlist>
   5.197 -	<listitem><para><option
   5.198 +      <para id="x_600">Options:</para>
   5.199 +      <itemizedlist>
   5.200 +	<listitem><para id="x_601"><option
   5.201  	      role="hg-ext-mq-cmd-qnew-opt">-f</option>: Create a new
   5.202  	    patch if the contents of the working directory are
   5.203  	    modified.  Any outstanding modifications are added to the
   5.204  	    newly created patch, so after this command completes, the
   5.205  	    working directory will no longer be modified.</para>
   5.206  	</listitem>
   5.207 -	<listitem><para><option
   5.208 +	<listitem><para id="x_602"><option
   5.209  	      role="hg-ext-mq-cmd-qnew-opt">-m</option>: Use the given
   5.210  	    text as the commit message. This text will be stored at
   5.211  	    the beginning of the patch file, before the patch
   5.212 @@ -215,7 +215,7 @@
   5.213        <title><command role="hg-ext-mq">qnext</command>&emdash;print
   5.214  	the name of the next patch</title>
   5.215  
   5.216 -      <para>The <command role="hg-ext-mq">qnext</command> command
   5.217 +      <para id="x_603">The <command role="hg-ext-mq">qnext</command> command
   5.218  	prints the name name of the next patch in the <filename
   5.219  	  role="special">series</filename> file after the topmost
   5.220  	applied patch.  This patch will become the topmost applied
   5.221 @@ -227,15 +227,15 @@
   5.222        <title><command role="hg-ext-mq">qpop</command>&emdash;pop
   5.223  	patches off the stack</title>
   5.224  
   5.225 -      <para>The <command role="hg-ext-mq">qpop</command> command
   5.226 +      <para id="x_604">The <command role="hg-ext-mq">qpop</command> command
   5.227  	removes applied patches from the top of the stack of applied
   5.228  	patches.  By default, it removes only one patch.</para>
   5.229  
   5.230 -      <para>This command removes the changesets that represent the
   5.231 +      <para id="x_605">This command removes the changesets that represent the
   5.232  	popped patches from the repository, and updates the working
   5.233  	directory to undo the effects of the patches.</para>
   5.234  
   5.235 -      <para>This command takes an optional argument, which it uses as
   5.236 +      <para id="x_606">This command takes an optional argument, which it uses as
   5.237  	the name or index of the patch to pop to.  If given a name, it
   5.238  	will pop patches until the named patch is the topmost applied
   5.239  	patch.  If given a number, <command
   5.240 @@ -245,7 +245,7 @@
   5.241  	It pops patches until the patch identified by the given index
   5.242  	is the topmost applied patch.</para>
   5.243  
   5.244 -      <para>The <command role="hg-ext-mq">qpop</command> command does
   5.245 +      <para id="x_607">The <command role="hg-ext-mq">qpop</command> command does
   5.246  	not read or write patches or the <filename
   5.247  	  role="special">series</filename> file.  It is thus safe to
   5.248  	<command role="hg-ext-mq">qpop</command> a patch that you have
   5.249 @@ -254,31 +254,31 @@
   5.250  	In the latter two cases, use the name of the patch as it was
   5.251  	when you applied it.</para>
   5.252  
   5.253 -      <para>By default, the <command role="hg-ext-mq">qpop</command>
   5.254 +      <para id="x_608">By default, the <command role="hg-ext-mq">qpop</command>
   5.255  	command will not pop any patches if the working directory has
   5.256  	been modified.  You can override this behaviour using the
   5.257  	<option role="hg-ext-mq-cmd-qpop-opt">-f</option> option,
   5.258  	which reverts all modifications in the working
   5.259  	directory.</para>
   5.260  
   5.261 -      <para>Options:</para>
   5.262 -      <itemizedlist>
   5.263 -	<listitem><para><option
   5.264 +      <para id="x_609">Options:</para>
   5.265 +      <itemizedlist>
   5.266 +	<listitem><para id="x_60a"><option
   5.267  	      role="hg-ext-mq-cmd-qpop-opt">-a</option>: Pop all
   5.268  	    applied patches.  This returns the repository to its state
   5.269  	    before you applied any patches.</para>
   5.270  	</listitem>
   5.271 -	<listitem><para><option
   5.272 +	<listitem><para id="x_60b"><option
   5.273  	      role="hg-ext-mq-cmd-qpop-opt">-f</option>: Forcibly
   5.274  	    revert any modifications to the working directory when
   5.275  	    popping.</para>
   5.276  	</listitem>
   5.277 -	<listitem><para><option
   5.278 +	<listitem><para id="x_60c"><option
   5.279  	      role="hg-ext-mq-cmd-qpop-opt">-n</option>: Pop a patch
   5.280  	    from the named queue.</para>
   5.281  	</listitem></itemizedlist>
   5.282  
   5.283 -      <para>The <command role="hg-ext-mq">qpop</command> command
   5.284 +      <para id="x_60d">The <command role="hg-ext-mq">qpop</command> command
   5.285  	removes one line from the end of the <filename
   5.286  	  role="special">status</filename> file for each patch that it
   5.287  	pops.</para>
   5.288 @@ -288,7 +288,7 @@
   5.289        <title><command role="hg-ext-mq">qprev</command>&emdash;print
   5.290  	the name of the previous patch</title>
   5.291  
   5.292 -      <para>The <command role="hg-ext-mq">qprev</command> command
   5.293 +      <para id="x_60e">The <command role="hg-ext-mq">qprev</command> command
   5.294  	prints the name of the patch in the <filename
   5.295  	  role="special">series</filename> file that comes before the
   5.296  	topmost applied patch. This will become the topmost applied
   5.297 @@ -300,18 +300,18 @@
   5.298        <title><command role="hg-ext-mq">qpush</command>&emdash;push
   5.299  	patches onto the stack</title>
   5.300  
   5.301 -      <para>The <command role="hg-ext-mq">qpush</command> command adds
   5.302 +      <para id="x_60f">The <command role="hg-ext-mq">qpush</command> command adds
   5.303  	patches onto the applied stack.  By default, it adds only one
   5.304  	patch.</para>
   5.305  
   5.306 -      <para>This command creates a new changeset to represent each
   5.307 +      <para id="x_610">This command creates a new changeset to represent each
   5.308  	applied patch, and updates the working directory to apply the
   5.309  	effects of the patches.</para>
   5.310  
   5.311 -      <para>The default data used when creating a changeset are as
   5.312 +      <para id="x_611">The default data used when creating a changeset are as
   5.313  	follows:</para>
   5.314        <itemizedlist>
   5.315 -	<listitem><para>The commit date and time zone are the current
   5.316 +	<listitem><para id="x_612">The commit date and time zone are the current
   5.317  	    date and time zone.  Because these data are used to
   5.318  	    compute the identity of a changeset, this means that if
   5.319  	    you <command role="hg-ext-mq">qpop</command> a patch and
   5.320 @@ -319,32 +319,32 @@
   5.321  	    changeset that you push will have a different identity
   5.322  	    than the changeset you popped.</para>
   5.323  	</listitem>
   5.324 -	<listitem><para>The author is the same as the default used by
   5.325 +	<listitem><para id="x_613">The author is the same as the default used by
   5.326  	    the <command role="hg-cmd">hg commit</command>
   5.327  	    command.</para>
   5.328  	</listitem>
   5.329 -	<listitem><para>The commit message is any text from the patch
   5.330 +	<listitem><para id="x_614">The commit message is any text from the patch
   5.331  	    file that comes before the first diff header.  If there is
   5.332  	    no such text, a default commit message is used that
   5.333  	    identifies the name of the patch.</para>
   5.334  	</listitem></itemizedlist>
   5.335 -      <para>If a patch contains a Mercurial patch header (XXX add
   5.336 +      <para id="x_615">If a patch contains a Mercurial patch header (XXX add
   5.337  	link), the information in the patch header overrides these
   5.338  	defaults.</para>
   5.339  
   5.340 -      <para>Options:</para>
   5.341 -      <itemizedlist>
   5.342 -	<listitem><para><option
   5.343 +      <para id="x_616">Options:</para>
   5.344 +      <itemizedlist>
   5.345 +	<listitem><para id="x_617"><option
   5.346  	      role="hg-ext-mq-cmd-qpush-opt">-a</option>: Push all
   5.347  	    unapplied patches from the <filename
   5.348  	      role="special">series</filename> file until there are
   5.349  	    none left to push.</para>
   5.350  	</listitem>
   5.351 -	<listitem><para><option
   5.352 +	<listitem><para id="x_618"><option
   5.353  	      role="hg-ext-mq-cmd-qpush-opt">-l</option>: Add the name
   5.354  	    of the patch to the end of the commit message.</para>
   5.355  	</listitem>
   5.356 -	<listitem><para><option
   5.357 +	<listitem><para id="x_619"><option
   5.358  	      role="hg-ext-mq-cmd-qpush-opt">-m</option>: If a patch
   5.359  	    fails to apply cleanly, use the entry for the patch in
   5.360  	    another saved queue to compute the parameters for a
   5.361 @@ -352,12 +352,12 @@
   5.362  	    normal Mercurial merge machinery.  Use the resolution of
   5.363  	    the merge as the new patch content.</para>
   5.364  	</listitem>
   5.365 -	<listitem><para><option
   5.366 +	<listitem><para id="x_61a"><option
   5.367  	      role="hg-ext-mq-cmd-qpush-opt">-n</option>: Use the
   5.368  	    named queue if merging while pushing.</para>
   5.369  	</listitem></itemizedlist>
   5.370  
   5.371 -      <para>The <command role="hg-ext-mq">qpush</command> command
   5.372 +      <para id="x_61b">The <command role="hg-ext-mq">qpush</command> command
   5.373  	reads, but does not modify, the <filename
   5.374  	  role="special">series</filename> file.  It appends one line
   5.375  	to the <command role="hg-cmd">hg status</command> file for
   5.376 @@ -369,24 +369,24 @@
   5.377  	  role="hg-ext-mq">qrefresh</command>&emdash;update the
   5.378  	topmost applied patch</title>
   5.379  
   5.380 -      <para>The <command role="hg-ext-mq">qrefresh</command> command
   5.381 +      <para id="x_61c">The <command role="hg-ext-mq">qrefresh</command> command
   5.382  	updates the topmost applied patch.  It modifies the patch,
   5.383  	removes the old changeset that represented the patch, and
   5.384  	creates a new changeset to represent the modified
   5.385  	patch.</para>
   5.386  
   5.387 -      <para>The <command role="hg-ext-mq">qrefresh</command> command
   5.388 +      <para id="x_61d">The <command role="hg-ext-mq">qrefresh</command> command
   5.389  	looks for the following modifications:</para>
   5.390        <itemizedlist>
   5.391 -	<listitem><para>Changes to the commit message, i.e. the text
   5.392 +	<listitem><para id="x_61e">Changes to the commit message, i.e. the text
   5.393  	    before the first diff header in the patch file, are
   5.394  	    reflected in the new changeset that represents the
   5.395  	    patch.</para>
   5.396  	</listitem>
   5.397 -	<listitem><para>Modifications to tracked files in the working
   5.398 +	<listitem><para id="x_61f">Modifications to tracked files in the working
   5.399  	    directory are added to the patch.</para>
   5.400  	</listitem>
   5.401 -	<listitem><para>Changes to the files tracked using <command
   5.402 +	<listitem><para id="x_620">Changes to the files tracked using <command
   5.403  	      role="hg-cmd">hg add</command>, <command
   5.404  	      role="hg-cmd">hg copy</command>, <command
   5.405  	      role="hg-cmd">hg remove</command>, or <command
   5.406 @@ -395,25 +395,25 @@
   5.407  	    removed files and rename sources are removed.</para>
   5.408  	</listitem></itemizedlist>
   5.409  
   5.410 -      <para>Even if <command role="hg-ext-mq">qrefresh</command>
   5.411 +      <para id="x_621">Even if <command role="hg-ext-mq">qrefresh</command>
   5.412  	detects no changes, it still recreates the changeset that
   5.413  	represents the patch.  This causes the identity of the
   5.414  	changeset to differ from the previous changeset that
   5.415  	identified the patch.</para>
   5.416  
   5.417 -      <para>Options:</para>
   5.418 -      <itemizedlist>
   5.419 -	<listitem><para><option
   5.420 +      <para id="x_622">Options:</para>
   5.421 +      <itemizedlist>
   5.422 +	<listitem><para id="x_623"><option
   5.423  	      role="hg-ext-mq-cmd-qrefresh-opt">-e</option>: Modify
   5.424  	    the commit and patch description, using the preferred text
   5.425  	    editor.</para>
   5.426  	</listitem>
   5.427 -	<listitem><para><option
   5.428 +	<listitem><para id="x_624"><option
   5.429  	      role="hg-ext-mq-cmd-qrefresh-opt">-m</option>: Modify
   5.430  	    the commit message and patch description, using the given
   5.431  	    text.</para>
   5.432  	</listitem>
   5.433 -	<listitem><para><option
   5.434 +	<listitem><para id="x_625"><option
   5.435  	      role="hg-ext-mq-cmd-qrefresh-opt">-l</option>: Modify
   5.436  	    the commit message and patch description, using text from
   5.437  	    the given file.</para>
   5.438 @@ -424,11 +424,11 @@
   5.439        <title><command role="hg-ext-mq">qrename</command>&emdash;rename
   5.440  	a patch</title>
   5.441  
   5.442 -      <para>The <command role="hg-ext-mq">qrename</command> command
   5.443 +      <para id="x_626">The <command role="hg-ext-mq">qrename</command> command
   5.444  	renames a patch, and changes the entry for the patch in the
   5.445  	<filename role="special">series</filename> file.</para>
   5.446  
   5.447 -      <para>With a single argument, <command
   5.448 +      <para id="x_627">With a single argument, <command
   5.449  	  role="hg-ext-mq">qrename</command> renames the topmost
   5.450  	applied patch.  With two arguments, it renames its first
   5.451  	argument to its second.</para>
   5.452 @@ -439,21 +439,21 @@
   5.453  	  role="hg-ext-mq">qrestore</command>&emdash;restore saved
   5.454  	queue state</title>
   5.455  
   5.456 -      <para>XXX No idea what this does.</para>
   5.457 +      <para id="x_628">XXX No idea what this does.</para>
   5.458  
   5.459      </sect2>
   5.460      <sect2>
   5.461        <title><command role="hg-ext-mq">qsave</command>&emdash;save
   5.462  	current queue state</title>
   5.463  
   5.464 -      <para>XXX Likewise.</para>
   5.465 +      <para id="x_629">XXX Likewise.</para>
   5.466  
   5.467      </sect2>
   5.468      <sect2>
   5.469        <title><command role="hg-ext-mq">qseries</command>&emdash;print
   5.470  	the entire patch series</title>
   5.471  
   5.472 -      <para>The <command role="hg-ext-mq">qseries</command> command
   5.473 +      <para id="x_62a">The <command role="hg-ext-mq">qseries</command> command
   5.474  	prints the entire patch series from the <filename
   5.475  	  role="special">series</filename> file.  It prints only patch
   5.476  	names, not empty lines or comments.  It prints in order from
   5.477 @@ -464,7 +464,7 @@
   5.478        <title><command role="hg-ext-mq">qtop</command>&emdash;print the
   5.479  	name of the current patch</title>
   5.480  
   5.481 -      <para>The <command role="hg-ext-mq">qtop</command> prints the
   5.482 +      <para id="x_62b">The <command role="hg-ext-mq">qtop</command> prints the
   5.483  	name of the topmost currently applied patch.</para>
   5.484  
   5.485      </sect2>
   5.486 @@ -473,7 +473,7 @@
   5.487  	  role="hg-ext-mq">qunapplied</command>&emdash;print patches
   5.488  	not yet applied</title>
   5.489  
   5.490 -      <para>The <command role="hg-ext-mq">qunapplied</command> command
   5.491 +      <para id="x_62c">The <command role="hg-ext-mq">qunapplied</command> command
   5.492  	prints the names of patches from the <filename
   5.493  	  role="special">series</filename> file that are not yet
   5.494  	applied.  It prints them in order from the next patch that
   5.495 @@ -484,28 +484,28 @@
   5.496        <title><command role="hg-cmd">hg strip</command>&emdash;remove a
   5.497  	revision and descendants</title>
   5.498  
   5.499 -      <para>The <command role="hg-cmd">hg strip</command> command
   5.500 +      <para id="x_62d">The <command role="hg-cmd">hg strip</command> command
   5.501  	removes a revision, and all of its descendants, from the
   5.502  	repository.  It undoes the effects of the removed revisions
   5.503  	from the repository, and updates the working directory to the
   5.504  	first parent of the removed revision.</para>
   5.505  
   5.506 -      <para>The <command role="hg-cmd">hg strip</command> command
   5.507 +      <para id="x_62e">The <command role="hg-cmd">hg strip</command> command
   5.508  	saves a backup of the removed changesets in a bundle, so that
   5.509  	they can be reapplied if removed in error.</para>
   5.510  
   5.511 -      <para>Options:</para>
   5.512 -      <itemizedlist>
   5.513 -	<listitem><para><option role="hg-opt-strip">-b</option>: Save
   5.514 +      <para id="x_62f">Options:</para>
   5.515 +      <itemizedlist>
   5.516 +	<listitem><para id="x_630"><option role="hg-opt-strip">-b</option>: Save
   5.517  	    unrelated changesets that are intermixed with the stripped
   5.518  	    changesets in the backup bundle.</para>
   5.519  	</listitem>
   5.520 -	<listitem><para><option role="hg-opt-strip">-f</option>: If a
   5.521 +	<listitem><para id="x_631"><option role="hg-opt-strip">-f</option>: If a
   5.522  	    branch has multiple heads, remove all heads. XXX This
   5.523  	    should be renamed, and use <literal>-f</literal> to strip
   5.524  	    revs when there are pending changes.</para>
   5.525  	</listitem>
   5.526 -	<listitem><para><option role="hg-opt-strip">-n</option>: Do
   5.527 +	<listitem><para id="x_632"><option role="hg-opt-strip">-n</option>: Do
   5.528  	    not save a backup bundle.</para>
   5.529  	</listitem></itemizedlist>
   5.530  
   5.531 @@ -518,18 +518,18 @@
   5.532        <title>The <filename role="special">series</filename>
   5.533  	file</title>
   5.534  
   5.535 -      <para>The <filename role="special">series</filename> file
   5.536 +      <para id="x_633">The <filename role="special">series</filename> file
   5.537  	contains a list of the names of all patches that MQ can apply.
   5.538  	It is represented as a list of names, with one name saved per
   5.539  	line.  Leading and trailing white space in each line are
   5.540  	ignored.</para>
   5.541  
   5.542 -      <para>Lines may contain comments.  A comment begins with the
   5.543 +      <para id="x_634">Lines may contain comments.  A comment begins with the
   5.544  	<quote><literal>#</literal></quote> character, and extends to
   5.545  	the end of the line.  Empty lines, and lines that contain only
   5.546  	comments, are ignored.</para>
   5.547  
   5.548 -      <para>You will often need to edit the <filename
   5.549 +      <para id="x_635">You will often need to edit the <filename
   5.550  	  role="special">series</filename> file by hand, hence the
   5.551  	support for comments and empty lines noted above.  For
   5.552  	example, you can comment out a patch temporarily, and <command
   5.553 @@ -538,7 +538,7 @@
   5.554  	patches are applied by reordering their entries in the
   5.555  	<filename role="special">series</filename> file.</para>
   5.556  
   5.557 -      <para>Placing the <filename role="special">series</filename>
   5.558 +      <para id="x_636">Placing the <filename role="special">series</filename>
   5.559  	file under revision control is also supported; it is a good
   5.560  	idea to place all of the patches that it refers to under
   5.561  	revision control, as well.  If you create a patch directory
   5.562 @@ -551,7 +551,7 @@
   5.563        <title>The <filename role="special">status</filename>
   5.564  	file</title>
   5.565  
   5.566 -      <para>The <filename role="special">status</filename> file
   5.567 +      <para id="x_637">The <filename role="special">status</filename> file
   5.568  	contains the names and changeset hashes of all patches that MQ
   5.569  	currently has applied.  Unlike the <filename
   5.570  	  role="special">series</filename> file, this file is not
     6.1 --- a/en/appC-srcinstall.xml	Fri Mar 20 15:40:06 2009 +0800
     6.2 +++ b/en/appC-srcinstall.xml	Fri Mar 20 16:43:35 2009 +0800
     6.3 @@ -7,29 +7,29 @@
     6.4    <sect1 id="sec.srcinstall.unixlike">
     6.5      <title>On a Unix-like system</title>
     6.6  
     6.7 -    <para>If you are using a Unix-like system that has a sufficiently
     6.8 +    <para id="x_5e0">If you are using a Unix-like system that has a sufficiently
     6.9        recent version of Python (2.3 or newer) available, it is easy to
    6.10        install Mercurial from source.</para>
    6.11      <orderedlist>
    6.12 -      <listitem><para>Download a recent source tarball from <ulink
    6.13 +      <listitem><para id="x_5e1">Download a recent source tarball from <ulink
    6.14  	    url="http://www.selenic.com/mercurial/download">http://www.selenic.com/mercurial/download</ulink>.</para>
    6.15        </listitem>
    6.16 -      <listitem><para>Unpack the tarball:</para>
    6.17 +      <listitem><para id="x_5e2">Unpack the tarball:</para>
    6.18  	<programlisting>gzip -dc mercurial-MYVERSION.tar.gz | tar xf -</programlisting>
    6.19        </listitem>
    6.20 -      <listitem><para>Go into the source directory and run the
    6.21 +      <listitem><para id="x_5e3">Go into the source directory and run the
    6.22  	  installer script.  This will build Mercurial and install it
    6.23  	  in your home directory.</para>
    6.24  	<programlisting>cd mercurial-MYVERSION
    6.25  python setup.py install --force --home=$HOME</programlisting>
    6.26        </listitem>
    6.27      </orderedlist>
    6.28 -    <para>Once the install finishes, Mercurial will be in the
    6.29 +    <para id="x_5e4">Once the install finishes, Mercurial will be in the
    6.30        <literal>bin</literal> subdirectory of your home directory.
    6.31        Don't forget to make sure that this directory is present in your
    6.32        shell's search path.</para>
    6.33  
    6.34 -    <para>You will probably need to set the <envar>PYTHONPATH</envar>
    6.35 +    <para id="x_5e5">You will probably need to set the <envar>PYTHONPATH</envar>
    6.36        environment variable so that the Mercurial executable can find
    6.37        the rest of the Mercurial packages.  For example, on my laptop,
    6.38        I have set it to <literal>/home/bos/lib/python</literal>.  The
    6.39 @@ -43,14 +43,14 @@
    6.40    <sect1>
    6.41      <title>On Windows</title>
    6.42  
    6.43 -    <para>Building and installing Mercurial on Windows requires a
    6.44 +    <para id="x_5e6">Building and installing Mercurial on Windows requires a
    6.45        variety of tools, a fair amount of technical knowledge, and
    6.46        considerable patience.  I very much <emphasis>do not
    6.47  	recommend</emphasis> this route if you are a <quote>casual
    6.48  	user</quote>.  Unless you intend to hack on Mercurial, I
    6.49        strongly suggest that you use a binary package instead.</para>
    6.50  
    6.51 -    <para>If you are intent on building Mercurial from source on
    6.52 +    <para id="x_5e7">If you are intent on building Mercurial from source on
    6.53        Windows, follow the <quote>hard way</quote> directions on the
    6.54        Mercurial wiki at <ulink
    6.55  	url="http://www.selenic.com/mercurial/wiki/index.cgi/WindowsInstall">http://www.selenic.com/mercurial/wiki/index.cgi/WindowsInstall</ulink>, 
     7.1 --- a/en/appD-license.xml	Fri Mar 20 15:40:06 2009 +0800
     7.2 +++ b/en/appD-license.xml	Fri Mar 20 16:43:35 2009 +0800
     7.3 @@ -4,24 +4,24 @@
     7.4    <?dbhtml filename="open-publication-license.html"?>
     7.5    <title>Open Publication License</title>
     7.6  
     7.7 -  <para>Version 1.0, 8 June 1999</para>
     7.8 +  <para id="x_638">Version 1.0, 8 June 1999</para>
     7.9  
    7.10    <sect1>
    7.11      <title>Requirements on both unmodified and modified
    7.12        versions</title>
    7.13  
    7.14 -    <para>The Open Publication works may be reproduced and distributed
    7.15 +    <para id="x_639">The Open Publication works may be reproduced and distributed
    7.16        in whole or in part, in any medium physical or electronic,
    7.17        provided that the terms of this license are adhered to, and that
    7.18        this license or an incorporation of it by reference (with any
    7.19        options elected by the author(s) and/or publisher) is displayed
    7.20        in the reproduction.</para>
    7.21  
    7.22 -    <para>Proper form for an incorporation by reference is as
    7.23 +    <para id="x_63a">Proper form for an incorporation by reference is as
    7.24        follows:</para>
    7.25  
    7.26      <blockquote>
    7.27 -      <para>  Copyright (c) <emphasis>year</emphasis> by
    7.28 +      <para id="x_63b">  Copyright (c) <emphasis>year</emphasis> by
    7.29  	<emphasis>author's name or designee</emphasis>. This material
    7.30  	may be distributed only subject to the terms and conditions
    7.31  	set forth in the Open Publication License,
    7.32 @@ -30,14 +30,14 @@
    7.33  	  url="http://www.opencontent.org/openpub/">http://www.opencontent.org/openpub/</ulink>).</para>
    7.34      </blockquote>
    7.35  
    7.36 -    <para>The reference must be immediately followed with any options
    7.37 +    <para id="x_63c">The reference must be immediately followed with any options
    7.38        elected by the author(s) and/or publisher of the document (see
    7.39        section <xref linkend="sec.opl.options"/>).</para>
    7.40  
    7.41 -    <para>Commercial redistribution of Open Publication-licensed
    7.42 +    <para id="x_63d">Commercial redistribution of Open Publication-licensed
    7.43        material is permitted.</para>
    7.44  
    7.45 -    <para>Any publication in standard (paper) book form shall require
    7.46 +    <para id="x_63e">Any publication in standard (paper) book form shall require
    7.47        the citation of the original publisher and author. The publisher
    7.48        and author's names shall appear on all outer surfaces of the
    7.49        book. On all outer surfaces of the book the original publisher's
    7.50 @@ -48,30 +48,30 @@
    7.51    <sect1>
    7.52      <title>Copyright</title>
    7.53  
    7.54 -    <para>The copyright to each Open Publication is owned by its
    7.55 +    <para id="x_63f">The copyright to each Open Publication is owned by its
    7.56        author(s) or designee.</para>
    7.57  
    7.58    </sect1>
    7.59    <sect1>
    7.60      <title>Scope of license</title>
    7.61  
    7.62 -    <para>The following license terms apply to all Open Publication
    7.63 +    <para id="x_640">The following license terms apply to all Open Publication
    7.64        works, unless otherwise explicitly stated in the
    7.65        document.</para>
    7.66  
    7.67 -    <para>Mere aggregation of Open Publication works or a portion of
    7.68 +    <para id="x_641">Mere aggregation of Open Publication works or a portion of
    7.69        an Open Publication work with other works or programs on the
    7.70        same media shall not cause this license to apply to those other
    7.71        works. The aggregate work shall contain a notice specifying the
    7.72        inclusion of the Open Publication material and appropriate
    7.73        copyright notice.</para>
    7.74  
    7.75 -    <para><emphasis role="bold">Severability</emphasis>. If any part
    7.76 +    <para id="x_642"><emphasis role="bold">Severability</emphasis>. If any part
    7.77        of this license is found to be unenforceable in any
    7.78        jurisdiction, the remaining portions of the license remain in
    7.79        force.</para>
    7.80  
    7.81 -    <para><emphasis role="bold">No warranty</emphasis>. Open
    7.82 +    <para id="x_643"><emphasis role="bold">No warranty</emphasis>. Open
    7.83        Publication works are licensed and provided <quote>as is</quote>
    7.84        without warranty of any kind, express or implied, including, but
    7.85        not limited to, the implied warranties of merchantability and
    7.86 @@ -82,25 +82,25 @@
    7.87    <sect1>
    7.88      <title>Requirements on modified works</title>
    7.89  
    7.90 -    <para>All modified versions of documents covered by this license,
    7.91 +    <para id="x_644">All modified versions of documents covered by this license,
    7.92        including translations, anthologies, compilations and partial
    7.93        documents, must meet the following requirements:</para>
    7.94  
    7.95      <orderedlist>
    7.96 -      <listitem><para>The modified version must be labeled as
    7.97 +      <listitem><para id="x_645">The modified version must be labeled as
    7.98  	  such.</para>
    7.99        </listitem>
   7.100 -      <listitem><para>The person making the modifications must be
   7.101 +      <listitem><para id="x_646">The person making the modifications must be
   7.102  	  identified and the modifications dated.</para>
   7.103        </listitem>
   7.104 -      <listitem><para>Acknowledgement of the original author and
   7.105 +      <listitem><para id="x_647">Acknowledgement of the original author and
   7.106  	  publisher if applicable must be retained according to normal
   7.107  	  academic citation practices.</para>
   7.108        </listitem>
   7.109 -      <listitem><para>The location of the original unmodified document
   7.110 +      <listitem><para id="x_648">The location of the original unmodified document
   7.111  	  must be identified.</para>
   7.112        </listitem>
   7.113 -      <listitem><para>The original author's (or authors') name(s) may
   7.114 +      <listitem><para id="x_649">The original author's (or authors') name(s) may
   7.115  	  not be used to assert or imply endorsement of the resulting
   7.116  	  document without the original author's (or authors')
   7.117  	  permission.</para>
   7.118 @@ -110,23 +110,23 @@
   7.119    <sect1>
   7.120      <title>Good-practice recommendations</title>
   7.121  
   7.122 -    <para>In addition to the requirements of this license, it is
   7.123 +    <para id="x_64a">In addition to the requirements of this license, it is
   7.124        requested from and strongly recommended of redistributors
   7.125        that:</para>
   7.126  
   7.127      <orderedlist>
   7.128 -      <listitem><para>If you are distributing Open Publication works
   7.129 +      <listitem><para id="x_64b">If you are distributing Open Publication works
   7.130  	  on hardcopy or CD-ROM, you provide email notification to the
   7.131  	  authors of your intent to redistribute at least thirty days
   7.132  	  before your manuscript or media freeze, to give the authors
   7.133  	  time to provide updated documents. This notification should
   7.134  	  describe modifications, if any, made to the document.</para>
   7.135        </listitem>
   7.136 -      <listitem><para>All substantive modifications (including
   7.137 +      <listitem><para id="x_64c">All substantive modifications (including
   7.138  	  deletions) be either clearly marked up in the document or
   7.139  	  else described in an attachment to the document.</para>
   7.140        </listitem>
   7.141 -      <listitem><para>Finally, while it is not mandatory under this
   7.142 +      <listitem><para id="x_64d">Finally, while it is not mandatory under this
   7.143  	  license, it is considered good form to offer a free copy of
   7.144  	  any hardcopy and CD-ROM expression of an Open
   7.145  	  Publication-licensed work to its author(s).</para>
   7.146 @@ -136,7 +136,7 @@
   7.147    <sect1 id="sec.opl.options">
   7.148      <title>License options</title>
   7.149  
   7.150 -    <para>The author(s) and/or publisher of an Open
   7.151 +    <para id="x_64e">The author(s) and/or publisher of an Open
   7.152        Publication-licensed document may elect certain options by
   7.153        appending language to the reference to or copy of the license.
   7.154        These options are considered part of the license instance and
   7.155 @@ -144,25 +144,25 @@
   7.156        reference) in derived works.</para>
   7.157  
   7.158      <orderedlist>
   7.159 -      <listitem><para>To prohibit distribution of substantively
   7.160 +      <listitem><para id="x_64f">To prohibit distribution of substantively
   7.161  	  modified versions without the explicit permission of the
   7.162  	  author(s). <quote>Substantive modification</quote> is
   7.163  	  defined as a change to the semantic content of the document,
   7.164  	  and excludes mere changes in format or typographical
   7.165  	  corrections.</para>
   7.166        </listitem>
   7.167 -      <listitem><para>  To accomplish this, add the phrase
   7.168 +      <listitem><para id="x_650">  To accomplish this, add the phrase
   7.169  	  <quote>Distribution of substantively modified versions of
   7.170  	    this document is prohibited without the explicit
   7.171  	    permission of the copyright holder.</quote> to the license
   7.172  	  reference or copy.</para>
   7.173        </listitem>
   7.174 -      <listitem><para>To prohibit any publication of this work or
   7.175 +      <listitem><para id="x_651">To prohibit any publication of this work or
   7.176  	  derivative works in whole or in part in standard (paper)
   7.177  	  book form for commercial purposes is prohibited unless prior
   7.178  	  permission is obtained from the copyright holder.</para>
   7.179        </listitem>
   7.180 -      <listitem><para>To accomplish this, add the phrase
   7.181 +      <listitem><para id="x_652">To accomplish this, add the phrase
   7.182  	  <quote>Distribution of the work or derivative of the work in
   7.183  	    any standard (paper) book form is prohibited unless prior
   7.184  	    permission is obtained from the copyright holder.</quote>
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/en/autoid.py	Fri Mar 20 16:43:35 2009 +0800
     8.3 @@ -0,0 +1,47 @@
     8.4 +#!/usr/bin/env python
     8.5 +#
     8.6 +# Add unique ID attributes to para tags.  This script should only be
     8.7 +# run by one person, since otherwise it introduces the possibility of
     8.8 +# chaotic conflicts among tags.
     8.9 +
    8.10 +import glob, os, re, sys
    8.11 +
    8.12 +tagged = re.compile('<para[^>]* id="x_([0-9a-f]+)"[^>]*>', re.M)
    8.13 +untagged = re.compile('<para>')
    8.14 +
    8.15 +names = glob.glob('ch*.xml') + glob.glob('app*.xml')
    8.16 +
    8.17 +# First pass: find the highest-numbered paragraph ID.
    8.18 +
    8.19 +biggest_id = 0
    8.20 +seen = set()
    8.21 +errs = 0
    8.22 +
    8.23 +for name in names:
    8.24 +    for m in tagged.finditer(open(name).read()):
    8.25 +        i = int(m.group(1),16)
    8.26 +        if i in seen:
    8.27 +            print >> sys.stderr, '%s: duplication of ID %s' % (name, i)
    8.28 +            errs += 1
    8.29 +        seen.add(i)
    8.30 +        if i > biggest_id:
    8.31 +            biggest_id = i
    8.32 +
    8.33 +def retag(s):
    8.34 +    global biggest_id
    8.35 +    biggest_id += 1
    8.36 +    return '<para id="x_%x">' % biggest_id
    8.37 +
    8.38 +# Second pass: add IDs to paragraphs that currently lack them.
    8.39 +
    8.40 +for name in names:
    8.41 +    f = open(name).read()
    8.42 +    f1 = untagged.sub(retag, f)
    8.43 +    if f1 != f:
    8.44 +        tmpname = name + '.tmp'
    8.45 +        fp = open(tmpname, 'w')
    8.46 +        fp.write(f1)
    8.47 +        fp.close()
    8.48 +        os.rename(tmpname, name)
    8.49 +
    8.50 +sys.exit(errs)
     9.1 --- a/en/ch00-preface.xml	Fri Mar 20 15:40:06 2009 +0800
     9.2 +++ b/en/ch00-preface.xml	Fri Mar 20 16:43:35 2009 +0800
     9.3 @@ -1,45 +1,162 @@
     9.4  <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
     9.5  
     9.6  <preface id="chap.preface">
     9.7 +  <?dbhtml filename="preface.html"?>
     9.8    <title>Preface</title>
     9.9  
    9.10 -  <para>Distributed revision control is a relatively new territory,
    9.11 -    and has thus far grown due to people's willingness to strike out
    9.12 -    into ill-charted territory.</para>
    9.13 -
    9.14 -  <para>I am writing a book about distributed revision control because
    9.15 -    I believe that it is an important subject that deserves a field
    9.16 -    guide. I chose to write about Mercurial because it is the easiest
    9.17 -    tool to learn the terrain with, and yet it scales to the demands
    9.18 -    of real, challenging environments where many other revision
    9.19 -    control tools fail.</para>
    9.20 +  <sect1>
    9.21 +    <title>Why revision control? Why Mercurial?</title>
    9.22 +
    9.23 +    <para id="x_6d">Revision control is the process of managing multiple
    9.24 +      versions of a piece of information.  In its simplest form, this
    9.25 +      is something that many people do by hand: every time you modify
    9.26 +      a file, save it under a new name that contains a number, each
    9.27 +      one higher than the number of the preceding version.</para>
    9.28 +
    9.29 +    <para id="x_6e">Manually managing multiple versions of even a single file is
    9.30 +      an error-prone task, though, so software tools to help automate
    9.31 +      this process have long been available.  The earliest automated
    9.32 +      revision control tools were intended to help a single user to
    9.33 +      manage revisions of a single file.  Over the past few decades,
    9.34 +      the scope of revision control tools has expanded greatly; they
    9.35 +      now manage multiple files, and help multiple people to work
    9.36 +      together.  The best modern revision control tools have no
    9.37 +      problem coping with thousands of people working together on
    9.38 +      projects that consist of hundreds of thousands of files.</para>
    9.39 +
    9.40 +    <para id="x_6f">The arrival of distributed revision control is relatively
    9.41 +      recent, and so far this new field has grown due to people's
    9.42 +      willingness to explore ill-charted territory.</para>
    9.43 +
    9.44 +    <para id="x_70">I am writing a book about distributed revision control
    9.45 +      because I believe that it is an important subject that deserves
    9.46 +      a field guide. I chose to write about Mercurial because it is
    9.47 +      the easiest tool to learn the terrain with, and yet it scales to
    9.48 +      the demands of real, challenging environments where many other
    9.49 +      revision control tools buckle.</para>
    9.50 +
    9.51 +    <sect2>
    9.52 +      <title>Why use revision control?</title>
    9.53 +
    9.54 +      <para id="x_71">There are a number of reasons why you or your team might
    9.55 +	want to use an automated revision control tool for a
    9.56 +	project.</para>
    9.57 +
    9.58 +      <itemizedlist>
    9.59 +	<listitem><para id="x_72">It will track the history and evolution of
    9.60 +	    your project, so you don't have to.  For every change,
    9.61 +	    you'll have a log of <emphasis>who</emphasis> made it;
    9.62 +	    <emphasis>why</emphasis> they made it;
    9.63 +	    <emphasis>when</emphasis> they made it; and
    9.64 +	    <emphasis>what</emphasis> the change
    9.65 +	    was.</para></listitem>
    9.66 +	<listitem><para id="x_73">When you're working with other people,
    9.67 +	    revision control software makes it easier for you to
    9.68 +	    collaborate.  For example, when people more or less
    9.69 +	    simultaneously make potentially incompatible changes, the
    9.70 +	    software will help you to identify and resolve those
    9.71 +	    conflicts.</para></listitem>
    9.72 +	<listitem><para id="x_74">It can help you to recover from mistakes.  If
    9.73 +	    you make a change that later turns out to be in error, you
    9.74 +	    can revert to an earlier version of one or more files.  In
    9.75 +	    fact, a <emphasis>really</emphasis> good revision control
    9.76 +	    tool will even help you to efficiently figure out exactly
    9.77 +	    when a problem was introduced (see section <xref
    9.78 +	      linkend="sec.undo.bisect"/> for details).</para></listitem>
    9.79 +	<listitem><para id="x_75">It will help you to work simultaneously on,
    9.80 +	    and manage the drift between, multiple versions of your
    9.81 +	    project.</para></listitem>
    9.82 +      </itemizedlist>
    9.83 +
    9.84 +      <para id="x_76">Most of these reasons are equally valid---at least in
    9.85 +	theory---whether you're working on a project by yourself, or
    9.86 +	with a hundred other people.</para>
    9.87 +
    9.88 +      <para id="x_77">A key question about the practicality of revision control
    9.89 +	at these two different scales (<quote>lone hacker</quote> and
    9.90 +	<quote>huge team</quote>) is how its
    9.91 +	<emphasis>benefits</emphasis> compare to its
    9.92 +	<emphasis>costs</emphasis>.  A revision control tool that's
    9.93 +	difficult to understand or use is going to impose a high
    9.94 +	cost.</para>
    9.95 +
    9.96 +      <para id="x_78">A five-hundred-person project is likely to collapse under
    9.97 +	its own weight almost immediately without a revision control
    9.98 +	tool and process. In this case, the cost of using revision
    9.99 +	control might hardly seem worth considering, since
   9.100 +	<emphasis>without</emphasis> it, failure is almost
   9.101 +	guaranteed.</para>
   9.102 +
   9.103 +      <para id="x_79">On the other hand, a one-person <quote>quick hack</quote>
   9.104 +	might seem like a poor place to use a revision control tool,
   9.105 +	because surely the cost of using one must be close to the
   9.106 +	overall cost of the project.  Right?</para>
   9.107 +
   9.108 +      <para id="x_7a">Mercurial uniquely supports <emphasis>both</emphasis> of
   9.109 +	these scales of development.  You can learn the basics in just
   9.110 +	a few minutes, and due to its low overhead, you can apply
   9.111 +	revision control to the smallest of projects with ease.  Its
   9.112 +	simplicity means you won't have a lot of abstruse concepts or
   9.113 +	command sequences competing for mental space with whatever
   9.114 +	you're <emphasis>really</emphasis> trying to do.  At the same
   9.115 +	time, Mercurial's high performance and peer-to-peer nature let
   9.116 +	you scale painlessly to handle large projects.</para>
   9.117 +
   9.118 +      <para id="x_7b">No revision control tool can rescue a poorly run project,
   9.119 +	but a good choice of tools can make a huge difference to the
   9.120 +	fluidity with which you can work on a project.</para>
   9.121 +
   9.122 +    </sect2>
   9.123 +
   9.124 +    <sect2>
   9.125 +      <title>The many names of revision control</title>
   9.126 +
   9.127 +      <para id="x_7c">Revision control is a diverse field, so much so that it is
   9.128 +	referred to by many names and acronyms.  Here are a few of the
   9.129 +	more common variations you'll encounter:</para>
   9.130 +      <itemizedlist>
   9.131 +	<listitem><para id="x_7d">Revision control (RCS)</para></listitem>
   9.132 +	<listitem><para id="x_7e">Software configuration management (SCM), or
   9.133 +	    configuration management</para></listitem>
   9.134 +	<listitem><para id="x_7f">Source code management</para></listitem>
   9.135 +	<listitem><para id="x_80">Source code control, or source
   9.136 +	    control</para></listitem>
   9.137 +	<listitem><para id="x_81">Version control
   9.138 +	    (VCS)</para></listitem></itemizedlist>
   9.139 +      <para id="x_82">Some people claim that these terms actually have different
   9.140 +	meanings, but in practice they overlap so much that there's no
   9.141 +	agreed or even useful way to tease them apart.</para>
   9.142 +
   9.143 +    </sect2>
   9.144 +  </sect1>
   9.145  
   9.146    <sect1>
   9.147      <title>This book is a work in progress</title>
   9.148  
   9.149 -    <para>I am releasing this book while I am still writing it, in the
   9.150 -      hope that it will prove useful to others.  I also hope that
   9.151 -      readers will contribute as they see fit.</para>
   9.152 +    <para id="x_83">I am releasing this book while I am still writing it, in the
   9.153 +      hope that it will prove useful to others.  I am writing under an
   9.154 +      open license in the hope that you, my readers, will contribute
   9.155 +      feedback and perhaps content of your own.</para>
   9.156  
   9.157    </sect1>
   9.158    <sect1>
   9.159      <title>About the examples in this book</title>
   9.160  
   9.161 -    <para>This book takes an unusual approach to code samples.  Every
   9.162 +    <para id="x_84">This book takes an unusual approach to code samples.  Every
   9.163        example is <quote>live</quote>---each one is actually the result
   9.164        of a shell script that executes the Mercurial commands you see.
   9.165        Every time an image of the book is built from its sources, all
   9.166        the example scripts are automatically run, and their current
   9.167        results compared against their expected results.</para>
   9.168  
   9.169 -    <para>The advantage of this approach is that the examples are
   9.170 +    <para id="x_85">The advantage of this approach is that the examples are
   9.171        always accurate; they describe <emphasis>exactly</emphasis> the
   9.172        behaviour of the version of Mercurial that's mentioned at the
   9.173        front of the book.  If I update the version of Mercurial that
   9.174        I'm documenting, and the output of some command changes, the
   9.175        build fails.</para>
   9.176  
   9.177 -    <para>There is a small disadvantage to this approach, which is
   9.178 +    <para id="x_86">There is a small disadvantage to this approach, which is
   9.179        that the dates and times you'll see in examples tend to be
   9.180        <quote>squashed</quote> together in a way that they wouldn't be
   9.181        if the same commands were being typed by a human.  Where a human
   9.182 @@ -47,27 +164,586 @@
   9.183        resulting timestamps correspondingly spread out, my automated
   9.184        example scripts run many commands in one second.</para>
   9.185  
   9.186 -    <para>As an instance of this, several consecutive commits in an
   9.187 +    <para id="x_87">As an instance of this, several consecutive commits in an
   9.188        example can show up as having occurred during the same second.
   9.189        You can see this occur in the <literal
   9.190  	role="hg-ext">bisect</literal> example in section <xref
   9.191  	id="sec.undo.bisect"/>, for instance.</para>
   9.192  
   9.193 -    <para>So when you're reading examples, don't place too much weight
   9.194 +    <para id="x_88">So when you're reading examples, don't place too much weight
   9.195        on the dates or times you see in the output of commands.  But
   9.196        <emphasis>do</emphasis> be confident that the behaviour you're
   9.197        seeing is consistent and reproducible.</para>
   9.198  
   9.199    </sect1>
   9.200 -  <sect1>
   9.201 -    <title>Colophon---this book is Free</title>
   9.202 -
   9.203 -    <para>This book is licensed under the Open Publication License,
   9.204 +
   9.205 +  <sect1>
   9.206 +    <title>Trends in the field</title>
   9.207 +
   9.208 +    <para id="x_89">There has been an unmistakable trend in the development and
   9.209 +      use of revision control tools over the past four decades, as
   9.210 +      people have become familiar with the capabilities of their tools
   9.211 +      and constrained by their limitations.</para>
   9.212 +
   9.213 +    <para id="x_8a">The first generation began by managing single files on
   9.214 +      individual computers.  Although these tools represented a huge
   9.215 +      advance over ad-hoc manual revision control, their locking model
   9.216 +      and reliance on a single computer limited them to small,
   9.217 +      tightly-knit teams.</para>
   9.218 +
   9.219 +    <para id="x_8b">The second generation loosened these constraints by moving
   9.220 +      to network-centered architectures, and managing entire projects
   9.221 +      at a time.  As projects grew larger, they ran into new problems.
   9.222 +      With clients needing to talk to servers very frequently, server
   9.223 +      scaling became an issue for large projects.  An unreliable
   9.224 +      network connection could prevent remote users from being able to
   9.225 +      talk to the server at all.  As open source projects started
   9.226 +      making read-only access available anonymously to anyone, people
   9.227 +      without commit privileges found that they could not use the
   9.228 +      tools to interact with a project in a natural way, as they could
   9.229 +      not record their changes.</para>
   9.230 +
   9.231 +    <para id="x_8c">The current generation of revision control tools is
   9.232 +      peer-to-peer in nature.  All of these systems have dropped the
   9.233 +      dependency on a single central server, and allow people to
   9.234 +      distribute their revision control data to where it's actually
   9.235 +      needed.  Collaboration over the Internet has moved from
   9.236 +      constrained by technology to a matter of choice and consensus.
   9.237 +      Modern tools can operate offline indefinitely and autonomously,
   9.238 +      with a network connection only needed when syncing changes with
   9.239 +      another repository.</para>
   9.240 +
   9.241 +  </sect1>
   9.242 +  <sect1>
   9.243 +    <title>A few of the advantages of distributed revision
   9.244 +      control</title>
   9.245 +
   9.246 +    <para id="x_8d">Even though distributed revision control tools have for
   9.247 +      several years been as robust and usable as their
   9.248 +      previous-generation counterparts, people using older tools have
   9.249 +      not yet necessarily woken up to their advantages.  There are a
   9.250 +      number of ways in which distributed tools shine relative to
   9.251 +      centralised ones.</para>
   9.252 +
   9.253 +    <para id="x_8e">For an individual developer, distributed tools are almost
   9.254 +      always much faster than centralised tools.  This is for a simple
   9.255 +      reason: a centralised tool needs to talk over the network for
   9.256 +      many common operations, because most metadata is stored in a
   9.257 +      single copy on the central server.  A distributed tool stores
   9.258 +      all of its metadata locally.  All else being equal, talking over
   9.259 +      the network adds overhead to a centralised tool.  Don't
   9.260 +      underestimate the value of a snappy, responsive tool: you're
   9.261 +      going to spend a lot of time interacting with your revision
   9.262 +      control software.</para>
   9.263 +
   9.264 +    <para id="x_8f">Distributed tools are indifferent to the vagaries of your
   9.265 +      server infrastructure, again because they replicate metadata to
   9.266 +      so many locations.  If you use a centralised system and your
   9.267 +      server catches fire, you'd better hope that your backup media
   9.268 +      are reliable, and that your last backup was recent and actually
   9.269 +      worked.  With a distributed tool, you have many backups
   9.270 +      available on every contributor's computer.</para>
   9.271 +
   9.272 +    <para id="x_90">The reliability of your network will affect distributed
   9.273 +      tools far less than it will centralised tools.  You can't even
   9.274 +      use a centralised tool without a network connection, except for
   9.275 +      a few highly constrained commands.  With a distributed tool, if
   9.276 +      your network connection goes down while you're working, you may
   9.277 +      not even notice.  The only thing you won't be able to do is talk
   9.278 +      to repositories on other computers, something that is relatively
   9.279 +      rare compared with local operations.  If you have a far-flung
   9.280 +      team of collaborators, this may be significant.</para>
   9.281 +
   9.282 +    <sect2>
   9.283 +      <title>Advantages for open source projects</title>
   9.284 +
   9.285 +      <para id="x_91">If you take a shine to an open source project and decide
   9.286 +	that you would like to start hacking on it, and that project
   9.287 +	uses a distributed revision control tool, you are at once a
   9.288 +	peer with the people who consider themselves the
   9.289 +	<quote>core</quote> of that project.  If they publish their
   9.290 +	repositories, you can immediately copy their project history,
   9.291 +	start making changes, and record your work, using the same
   9.292 +	tools in the same ways as insiders.  By contrast, with a
   9.293 +	centralised tool, you must use the software in a <quote>read
   9.294 +	  only</quote> mode unless someone grants you permission to
   9.295 +	commit changes to their central server.  Until then, you won't
   9.296 +	be able to record changes, and your local modifications will
   9.297 +	be at risk of corruption any time you try to update your
   9.298 +	client's view of the repository.</para>
   9.299 +
   9.300 +      <sect3>
   9.301 +	<title>The forking non-problem</title>
   9.302 +
   9.303 +	<para id="x_92">It has been suggested that distributed revision control
   9.304 +	  tools pose some sort of risk to open source projects because
   9.305 +	  they make it easy to <quote>fork</quote> the development of
   9.306 +	  a project.  A fork happens when there are differences in
   9.307 +	  opinion or attitude between groups of developers that cause
   9.308 +	  them to decide that they can't work together any longer.
   9.309 +	  Each side takes a more or less complete copy of the
   9.310 +	  project's source code, and goes off in its own
   9.311 +	  direction.</para>
   9.312 +
   9.313 +	<para id="x_93">Sometimes the camps in a fork decide to reconcile their
   9.314 +	  differences. With a centralised revision control system, the
   9.315 +	  <emphasis>technical</emphasis> process of reconciliation is
   9.316 +	  painful, and has to be performed largely by hand.  You have
   9.317 +	  to decide whose revision history is going to
   9.318 +	  <quote>win</quote>, and graft the other team's changes into
   9.319 +	  the tree somehow. This usually loses some or all of one
   9.320 +	  side's revision history.</para>
   9.321 +
   9.322 +	<para id="x_94">What distributed tools do with respect to forking is
   9.323 +	  they make forking the <emphasis>only</emphasis> way to
   9.324 +	  develop a project.  Every single change that you make is
   9.325 +	  potentially a fork point.  The great strength of this
   9.326 +	  approach is that a distributed revision control tool has to
   9.327 +	  be really good at <emphasis>merging</emphasis> forks,
   9.328 +	  because forks are absolutely fundamental: they happen all
   9.329 +	  the time.</para>
   9.330 +
   9.331 +	<para id="x_95">If every piece of work that everybody does, all the
   9.332 +	  time, is framed in terms of forking and merging, then what
   9.333 +	  the open source world refers to as a <quote>fork</quote>
   9.334 +	  becomes <emphasis>purely</emphasis> a social issue.  If
   9.335 +	  anything, distributed tools <emphasis>lower</emphasis> the
   9.336 +	  likelihood of a fork:</para>
   9.337 +	<itemizedlist>
   9.338 +	  <listitem><para id="x_96">They eliminate the social distinction that
   9.339 +	      centralised tools impose: that between insiders (people
   9.340 +	      with commit access) and outsiders (people
   9.341 +	      without).</para></listitem>
   9.342 +	  <listitem><para id="x_97">They make it easier to reconcile after a
   9.343 +	      social fork, because all that's involved from the
   9.344 +	      perspective of the revision control software is just
   9.345 +	      another merge.</para></listitem></itemizedlist>
   9.346 +
   9.347 +	<para id="x_98">Some people resist distributed tools because they want
   9.348 +	  to retain tight control over their projects, and they
   9.349 +	  believe that centralised tools give them this control.
   9.350 +	  However, if you're of this belief, and you publish your CVS
   9.351 +	  or Subversion repositories publicly, there are plenty of
   9.352 +	  tools available that can pull out your entire project's
   9.353 +	  history (albeit slowly) and recreate it somewhere that you
   9.354 +	  don't control.  So while your control in this case is
   9.355 +	  illusory, you are forgoing the ability to fluidly
   9.356 +	  collaborate with whatever people feel compelled to mirror
   9.357 +	  and fork your history.</para>
   9.358 +
   9.359 +      </sect3>
   9.360 +    </sect2>
   9.361 +    <sect2>
   9.362 +      <title>Advantages for commercial projects</title>
   9.363 +
   9.364 +      <para id="x_99">Many commercial projects are undertaken by teams that are
   9.365 +	scattered across the globe.  Contributors who are far from a
   9.366 +	central server will see slower command execution and perhaps
   9.367 +	less reliability.  Commercial revision control systems attempt
   9.368 +	to ameliorate these problems with remote-site replication
   9.369 +	add-ons that are typically expensive to buy and cantankerous
   9.370 +	to administer.  A distributed system doesn't suffer from these
   9.371 +	problems in the first place.  Better yet, you can easily set
   9.372 +	up multiple authoritative servers, say one per site, so that
   9.373 +	there's no redundant communication between repositories over
   9.374 +	expensive long-haul network links.</para>
   9.375 +
   9.376 +      <para id="x_9a">Centralised revision control systems tend to have
   9.377 +	relatively low scalability.  It's not unusual for an expensive
   9.378 +	centralised system to fall over under the combined load of
   9.379 +	just a few dozen concurrent users.  Once again, the typical
   9.380 +	response tends to be an expensive and clunky replication
   9.381 +	facility.  Since the load on a central server---if you have
   9.382 +	one at all---is many times lower with a distributed tool
   9.383 +	(because all of the data is replicated everywhere), a single
   9.384 +	cheap server can handle the needs of a much larger team, and
   9.385 +	replication to balance load becomes a simple matter of
   9.386 +	scripting.</para>
   9.387 +
   9.388 +      <para id="x_9b">If you have an employee in the field, troubleshooting a
   9.389 +	problem at a customer's site, they'll benefit from distributed
   9.390 +	revision control. The tool will let them generate custom
   9.391 +	builds, try different fixes in isolation from each other, and
   9.392 +	search efficiently through history for the sources of bugs and
   9.393 +	regressions in the customer's environment, all without needing
   9.394 +	to connect to your company's network.</para>
   9.395 +
   9.396 +    </sect2>
   9.397 +  </sect1>
   9.398 +  <sect1>
   9.399 +    <title>Why choose Mercurial?</title>
   9.400 +
   9.401 +    <para id="x_9c">Mercurial has a unique set of properties that make it a
   9.402 +      particularly good choice as a revision control system.</para>
   9.403 +    <itemizedlist>
   9.404 +      <listitem><para id="x_9d">It is easy to learn and use.</para></listitem>
   9.405 +      <listitem><para id="x_9e">It is lightweight.</para></listitem>
   9.406 +      <listitem><para id="x_9f">It scales excellently.</para></listitem>
   9.407 +      <listitem><para id="x_a0">It is easy to
   9.408 +	  customise.</para></listitem></itemizedlist>
   9.409 +
   9.410 +    <para id="x_a1">If you are at all familiar with revision control systems,
   9.411 +      you should be able to get up and running with Mercurial in less
   9.412 +      than five minutes.  Even if not, it will take no more than a few
   9.413 +      minutes longer.  Mercurial's command and feature sets are
   9.414 +      generally uniform and consistent, so you can keep track of a few
   9.415 +      general rules instead of a host of exceptions.</para>
   9.416 +
   9.417 +    <para id="x_a2">On a small project, you can start working with Mercurial in
   9.418 +      moments. Creating new changes and branches; transferring changes
   9.419 +      around (whether locally or over a network); and history and
   9.420 +      status operations are all fast.  Mercurial attempts to stay
   9.421 +      nimble and largely out of your way by combining low cognitive
   9.422 +      overhead with blazingly fast operations.</para>
   9.423 +
   9.424 +    <para id="x_a3">The usefulness of Mercurial is not limited to small
   9.425 +      projects: it is used by projects with hundreds to thousands of
   9.426 +      contributors, each containing tens of thousands of files and
   9.427 +      hundreds of megabytes of source code.</para>
   9.428 +
   9.429 +    <para id="x_a4">If the core functionality of Mercurial is not enough for
   9.430 +      you, it's easy to build on.  Mercurial is well suited to
   9.431 +      scripting tasks, and its clean internals and implementation in
   9.432 +      Python make it easy to add features in the form of extensions.
   9.433 +      There are a number of popular and useful extensions already
   9.434 +      available, ranging from helping to identify bugs to improving
   9.435 +      performance.</para>
   9.436 +
   9.437 +  </sect1>
   9.438 +  <sect1>
   9.439 +    <title>Mercurial compared with other tools</title>
   9.440 +
   9.441 +    <para id="x_a5">Before you read on, please understand that this section
   9.442 +      necessarily reflects my own experiences, interests, and (dare I
   9.443 +      say it) biases.  I have used every one of the revision control
   9.444 +      tools listed below, in most cases for several years at a
   9.445 +      time.</para>
   9.446 +
   9.447 +
   9.448 +    <sect2>
   9.449 +      <title>Subversion</title>
   9.450 +
   9.451 +      <para id="x_a6">Subversion is a popular revision control tool, developed
   9.452 +	to replace CVS.  It has a centralised client/server
   9.453 +	architecture.</para>
   9.454 +
   9.455 +      <para id="x_a7">Subversion and Mercurial have similarly named commands for
   9.456 +	performing the same operations, so if you're familiar with
   9.457 +	one, it is easy to learn to use the other.  Both tools are
   9.458 +	portable to all popular operating systems.</para>
   9.459 +
   9.460 +      <para id="x_a8">Prior to version 1.5, Subversion had no useful support for
   9.461 +	merges. At the time of writing, its merge tracking capability
   9.462 +	is new, and known to be <ulink
   9.463 +	  url="http://svnbook.red-bean.com/nightly/en/svn.branchmerge.advanced.html#svn.branchmerge.advanced.finalword">complicated 
   9.464 +	  and buggy</ulink>.</para>
   9.465 +
   9.466 +      <para id="x_a9">Mercurial has a substantial performance advantage over
   9.467 +	Subversion on every revision control operation I have
   9.468 +	benchmarked.  I have measured its advantage as ranging from a
   9.469 +	factor of two to a factor of six when compared with Subversion
   9.470 +	1.4.3's <emphasis>ra_local</emphasis> file store, which is the
   9.471 +	fastest access method available.  In more realistic
   9.472 +	deployments involving a network-based store, Subversion will
   9.473 +	be at a substantially larger disadvantage.  Because many
   9.474 +	Subversion commands must talk to the server and Subversion
   9.475 +	does not have useful replication facilities, server capacity
   9.476 +	and network bandwidth become bottlenecks for modestly large
   9.477 +	projects.</para>
   9.478 +
   9.479 +      <para id="x_aa">Additionally, Subversion incurs substantial storage
   9.480 +	overhead to avoid network transactions for a few common
   9.481 +	operations, such as finding modified files
   9.482 +	(<literal>status</literal>) and displaying modifications
   9.483 +	against the current revision (<literal>diff</literal>).  As a
   9.484 +	result, a Subversion working copy is often the same size as,
   9.485 +	or larger than, a Mercurial repository and working directory,
   9.486 +	even though the Mercurial repository contains a complete
   9.487 +	history of the project.</para>
   9.488 +
   9.489 +      <para id="x_ab">Subversion is widely supported by third party tools.
   9.490 +	Mercurial currently lags considerably in this area.  This gap
   9.491 +	is closing, however, and indeed some of Mercurial's GUI tools
   9.492 +	now outshine their Subversion equivalents.  Like Mercurial,
   9.493 +	Subversion has an excellent user manual.</para>
   9.494 +
   9.495 +      <para id="x_ac">Because Subversion doesn't store revision history on the
   9.496 +	client, it is well suited to managing projects that deal with
   9.497 +	lots of large, opaque binary files.  If you check in fifty
   9.498 +	revisions to an incompressible 10MB file, Subversion's
   9.499 +	client-side space usage stays constant The space used by any
   9.500 +	distributed SCM will grow rapidly in proportion to the number
   9.501 +	of revisions, because the differences between each revision
   9.502 +	are large.</para>
   9.503 +
   9.504 +      <para id="x_ad">In addition, it's often difficult or, more usually,
   9.505 +	impossible to merge different versions of a binary file.
   9.506 +	Subversion's ability to let a user lock a file, so that they
   9.507 +	temporarily have the exclusive right to commit changes to it,
   9.508 +	can be a significant advantage to a project where binary files
   9.509 +	are widely used.</para>
   9.510 +
   9.511 +      <para id="x_ae">Mercurial can import revision history from a Subversion
   9.512 +	repository. It can also export revision history to a
   9.513 +	Subversion repository.  This makes it easy to <quote>test the
   9.514 +	  waters</quote> and use Mercurial and Subversion in parallel
   9.515 +	before deciding to switch.  History conversion is incremental,
   9.516 +	so you can perform an initial conversion, then small
   9.517 +	additional conversions afterwards to bring in new
   9.518 +	changes.</para>
   9.519 +
   9.520 +
   9.521 +    </sect2>
   9.522 +    <sect2>
   9.523 +      <title>Git</title>
   9.524 +
   9.525 +      <para id="x_af">Git is a distributed revision control tool that was
   9.526 +	developed for managing the Linux kernel source tree.  Like
   9.527 +	Mercurial, its early design was somewhat influenced by
   9.528 +	Monotone.</para>
   9.529 +
   9.530 +      <para id="x_b0">Git has a very large command set, with version 1.5.0
   9.531 +	providing 139 individual commands.  It has something of a
   9.532 +	reputation for being difficult to learn.  Compared to Git,
   9.533 +	Mercurial has a strong focus on simplicity.</para>
   9.534 +
   9.535 +      <para id="x_b1">In terms of performance, Git is extremely fast.  In
   9.536 +	several cases, it is faster than Mercurial, at least on Linux,
   9.537 +	while Mercurial performs better on other operations.  However,
   9.538 +	on Windows, the performance and general level of support that
   9.539 +	Git provides is, at the time of writing, far behind that of
   9.540 +	Mercurial.</para>
   9.541 +
   9.542 +      <para id="x_b2">While a Mercurial repository needs no maintenance, a Git
   9.543 +	repository requires frequent manual <quote>repacks</quote> of
   9.544 +	its metadata.  Without these, performance degrades, while
   9.545 +	space usage grows rapidly.  A server that contains many Git
   9.546 +	repositories that are not rigorously and frequently repacked
   9.547 +	will become heavily disk-bound during backups, and there have
   9.548 +	been instances of daily backups taking far longer than 24
   9.549 +	hours as a result.  A freshly packed Git repository is
   9.550 +	slightly smaller than a Mercurial repository, but an unpacked
   9.551 +	repository is several orders of magnitude larger.</para>
   9.552 +
   9.553 +      <para id="x_b3">The core of Git is written in C.  Many Git commands are
   9.554 +	implemented as shell or Perl scripts, and the quality of these
   9.555 +	scripts varies widely. I have encountered several instances
   9.556 +	where scripts charged along blindly in the presence of errors
   9.557 +	that should have been fatal.</para>
   9.558 +
   9.559 +      <para id="x_b4">Mercurial can import revision history from a Git
   9.560 +	repository.</para>
   9.561 +
   9.562 +
   9.563 +    </sect2>
   9.564 +    <sect2>
   9.565 +      <title>CVS</title>
   9.566 +
   9.567 +      <para id="x_b5">CVS is probably the most widely used revision control tool
   9.568 +	in the world.  Due to its age and internal untidiness, it has
   9.569 +	been only lightly maintained for many years.</para>
   9.570 +
   9.571 +      <para id="x_b6">It has a centralised client/server architecture.  It does
   9.572 +	not group related file changes into atomic commits, making it
   9.573 +	easy for people to <quote>break the build</quote>: one person
   9.574 +	can successfully commit part of a change and then be blocked
   9.575 +	by the need for a merge, causing other people to see only a
   9.576 +	portion of the work they intended to do.  This also affects
   9.577 +	how you work with project history.  If you want to see all of
   9.578 +	the modifications someone made as part of a task, you will
   9.579 +	need to manually inspect the descriptions and timestamps of
   9.580 +	the changes made to each file involved (if you even know what
   9.581 +	those files were).</para>
   9.582 +
   9.583 +      <para id="x_b7">CVS has a muddled notion of tags and branches that I will
   9.584 +	not attempt to even describe.  It does not support renaming of
   9.585 +	files or directories well, making it easy to corrupt a
   9.586 +	repository.  It has almost no internal consistency checking
   9.587 +	capabilities, so it is usually not even possible to tell
   9.588 +	whether or how a repository is corrupt.  I would not recommend
   9.589 +	CVS for any project, existing or new.</para>
   9.590 +
   9.591 +      <para id="x_b8">Mercurial can import CVS revision history.  However, there
   9.592 +	are a few caveats that apply; these are true of every other
   9.593 +	revision control tool's CVS importer, too.  Due to CVS's lack
   9.594 +	of atomic changes and unversioned filesystem hierarchy, it is
   9.595 +	not possible to reconstruct CVS history completely accurately;
   9.596 +	some guesswork is involved, and renames will usually not show
   9.597 +	up.  Because a lot of advanced CVS administration has to be
   9.598 +	done by hand and is hence error-prone, it's common for CVS
   9.599 +	importers to run into multiple problems with corrupted
   9.600 +	repositories (completely bogus revision timestamps and files
   9.601 +	that have remained locked for over a decade are just two of
   9.602 +	the less interesting problems I can recall from personal
   9.603 +	experience).</para>
   9.604 +
   9.605 +      <para id="x_b9">Mercurial can import revision history from a CVS
   9.606 +	repository.</para>
   9.607 +
   9.608 +
   9.609 +    </sect2>
   9.610 +    <sect2>
   9.611 +      <title>Commercial tools</title>
   9.612 +
   9.613 +      <para id="x_ba">Perforce has a centralised client/server architecture,
   9.614 +	with no client-side caching of any data.  Unlike modern
   9.615 +	revision control tools, Perforce requires that a user run a
   9.616 +	command to inform the server about every file they intend to
   9.617 +	edit.</para>
   9.618 +
   9.619 +      <para id="x_bb">The performance of Perforce is quite good for small teams,
   9.620 +	but it falls off rapidly as the number of users grows beyond a
   9.621 +	few dozen. Modestly large Perforce installations require the
   9.622 +	deployment of proxies to cope with the load their users
   9.623 +	generate.</para>
   9.624 +
   9.625 +
   9.626 +    </sect2>
   9.627 +    <sect2>
   9.628 +      <title>Choosing a revision control tool</title>
   9.629 +
   9.630 +      <para id="x_bc">With the exception of CVS, all of the tools listed above
   9.631 +	have unique strengths that suit them to particular styles of
   9.632 +	work.  There is no single revision control tool that is best
   9.633 +	in all situations.</para>
   9.634 +
   9.635 +      <para id="x_bd">As an example, Subversion is a good choice for working
   9.636 +	with frequently edited binary files, due to its centralised
   9.637 +	nature and support for file locking.</para>
   9.638 +
   9.639 +      <para id="x_be">I personally find Mercurial's properties of simplicity,
   9.640 +	performance, and good merge support to be a compelling
   9.641 +	combination that has served me well for several years.</para>
   9.642 +
   9.643 +
   9.644 +    </sect2>
   9.645 +  </sect1>
   9.646 +  <sect1>
   9.647 +    <title>Switching from another tool to Mercurial</title>
   9.648 +
   9.649 +    <para id="x_bf">Mercurial is bundled with an extension named <literal
   9.650 +	role="hg-ext">convert</literal>, which can incrementally
   9.651 +      import revision history from several other revision control
   9.652 +      tools.  By <quote>incremental</quote>, I mean that you can
   9.653 +      convert all of a project's history to date in one go, then rerun
   9.654 +      the conversion later to obtain new changes that happened after
   9.655 +      the initial conversion.</para>
   9.656 +
   9.657 +    <para id="x_c0">The revision control tools supported by <literal
   9.658 +	role="hg-ext">convert</literal> are as follows:</para>
   9.659 +    <itemizedlist>
   9.660 +      <listitem><para id="x_c1">Subversion</para></listitem>
   9.661 +      <listitem><para id="x_c2">CVS</para></listitem>
   9.662 +      <listitem><para id="x_c3">Git</para></listitem>
   9.663 +      <listitem><para id="x_c4">Darcs</para></listitem></itemizedlist>
   9.664 +
   9.665 +    <para id="x_c5">In addition, <literal role="hg-ext">convert</literal> can
   9.666 +      export changes from Mercurial to Subversion.  This makes it
   9.667 +      possible to try Subversion and Mercurial in parallel before
   9.668 +      committing to a switchover, without risking the loss of any
   9.669 +      work.</para>
   9.670 +
   9.671 +    <para id="x_c6">The <command role="hg-ext-convert">convert</command> command
   9.672 +      is easy to use.  Simply point it at the path or URL of the
   9.673 +      source repository, optionally give it the name of the
   9.674 +      destination repository, and it will start working.  After the
   9.675 +      initial conversion, just run the same command again to import
   9.676 +      new changes.</para>
   9.677 +  </sect1>
   9.678 +
   9.679 +  <sect1>
   9.680 +    <title>A short history of revision control</title>
   9.681 +
   9.682 +    <para id="x_c7">The best known of the old-time revision control tools is
   9.683 +      SCCS (Source Code Control System), which Marc Rochkind wrote at
   9.684 +      Bell Labs, in the early 1970s.  SCCS operated on individual
   9.685 +      files, and required every person working on a project to have
   9.686 +      access to a shared workspace on a single system.  Only one
   9.687 +      person could modify a file at any time; arbitration for access
   9.688 +      to files was via locks.  It was common for people to lock files,
   9.689 +      and later forget to unlock them, preventing anyone else from
   9.690 +      modifying those files without the help of an
   9.691 +      administrator.</para>
   9.692 +
   9.693 +    <para id="x_c8">Walter Tichy developed a free alternative to SCCS in the
   9.694 +      early 1980s; he called his program RCS (Revision Control System).
   9.695 +      Like SCCS, RCS required developers to work in a single shared
   9.696 +      workspace, and to lock files to prevent multiple people from
   9.697 +      modifying them simultaneously.</para>
   9.698 +
   9.699 +    <para id="x_c9">Later in the 1980s, Dick Grune used RCS as a building block
   9.700 +      for a set of shell scripts he initially called cmt, but then
   9.701 +      renamed to CVS (Concurrent Versions System).  The big innovation
   9.702 +      of CVS was that it let developers work simultaneously and
   9.703 +      somewhat independently in their own personal workspaces.  The
   9.704 +      personal workspaces prevented developers from stepping on each
   9.705 +      other's toes all the time, as was common with SCCS and RCS. Each
   9.706 +      developer had a copy of every project file, and could modify
   9.707 +      their copies independently.  They had to merge their edits prior
   9.708 +      to committing changes to the central repository.</para>
   9.709 +
   9.710 +    <para id="x_ca">Brian Berliner took Grune's original scripts and rewrote
   9.711 +      them in C, releasing in 1989 the code that has since developed
   9.712 +      into the modern version of CVS.  CVS subsequently acquired the
   9.713 +      ability to operate over a network connection, giving it a
   9.714 +      client/server architecture.  CVS's architecture is centralised;
   9.715 +      only the server has a copy of the history of the project. Client
   9.716 +      workspaces just contain copies of recent versions of the
   9.717 +      project's files, and a little metadata to tell them where the
   9.718 +      server is.  CVS has been enormously successful; it is probably
   9.719 +      the world's most widely used revision control system.</para>
   9.720 +
   9.721 +    <para id="x_cb">In the early 1990s, Sun Microsystems developed an early
   9.722 +      distributed revision control system, called TeamWare.  A
   9.723 +      TeamWare workspace contains a complete copy of the project's
   9.724 +      history.  TeamWare has no notion of a central repository.  (CVS
   9.725 +      relied upon RCS for its history storage; TeamWare used
   9.726 +      SCCS.)</para>
   9.727 +
   9.728 +    <para id="x_cc">As the 1990s progressed, awareness grew of a number of
   9.729 +      problems with CVS.  It records simultaneous changes to multiple
   9.730 +      files individually, instead of grouping them together as a
   9.731 +      single logically atomic operation.  It does not manage its file
   9.732 +      hierarchy well; it is easy to make a mess of a repository by
   9.733 +      renaming files and directories.  Worse, its source code is
   9.734 +      difficult to read and maintain, which made the <quote>pain
   9.735 +	level</quote> of fixing these architectural problems
   9.736 +      prohibitive.</para>
   9.737 +
   9.738 +    <para id="x_cd">In 2001, Jim Blandy and Karl Fogel, two developers who had
   9.739 +      worked on CVS, started a project to replace it with a tool that
   9.740 +      would have a better architecture and cleaner code.  The result,
   9.741 +      Subversion, does not stray from CVS's centralised client/server
   9.742 +      model, but it adds multi-file atomic commits, better namespace
   9.743 +      management, and a number of other features that make it a
   9.744 +      generally better tool than CVS. Since its initial release, it
   9.745 +      has rapidly grown in popularity.</para>
   9.746 +
   9.747 +    <para id="x_ce">More or less simultaneously, Graydon Hoare began working on
   9.748 +      an ambitious distributed revision control system that he named
   9.749 +      Monotone. While Monotone addresses many of CVS's design flaws
   9.750 +      and has a peer-to-peer architecture, it goes beyond earlier (and
   9.751 +      subsequent) revision control tools in a number of innovative
   9.752 +      ways.  It uses cryptographic hashes as identifiers, and has an
   9.753 +      integral notion of <quote>trust</quote> for code from different
   9.754 +      sources.</para>
   9.755 +
   9.756 +    <para id="x_cf">Mercurial began life in 2005.  While a few aspects of its
   9.757 +      design are influenced by Monotone, Mercurial focuses on ease of
   9.758 +      use, high performance, and scalability to very large
   9.759 +      projects.</para>
   9.760 +
   9.761 +  </sect1>
   9.762 +
   9.763 +  <sect1>
   9.764 +    <title>Colophon&emdash;this book is Free</title>
   9.765 +
   9.766 +    <para id="x_d0">This book is licensed under the Open Publication License,
   9.767        and is produced entirely using Free Software tools.  It is
   9.768        typeset with DocBook XML.  Illustrations are drawn and rendered with
   9.769        <ulink url="http://www.inkscape.org/">Inkscape</ulink>.</para>
   9.770  
   9.771 -    <para>The complete source code for this book is published as a
   9.772 +    <para id="x_d1">The complete source code for this book is published as a
   9.773        Mercurial repository, at <ulink
   9.774  	url="http://hg.serpentine.com/mercurial/book">http://hg.serpentine.com/mercurial/book</ulink>.</para>
   9.775  
    10.1 --- a/en/ch01-intro.xml	Fri Mar 20 15:40:06 2009 +0800
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,680 +0,0 @@
    10.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    10.5 -
    10.6 -<chapter id="chap.intro">
    10.7 -  <?dbhtml filename="introduction.html"?>
    10.8 -  <title>Introduction</title>
    10.9 -
   10.10 -  <sect1>
   10.11 -    <title>About revision control</title>
   10.12 -
   10.13 -    <para>Revision control is the process of managing multiple
   10.14 -      versions of a piece of information.  In its simplest form, this
   10.15 -      is something that many people do by hand: every time you modify
   10.16 -      a file, save it under a new name that contains a number, each
   10.17 -      one higher than the number of the preceding version.</para>
   10.18 -
   10.19 -    <para>Manually managing multiple versions of even a single file is
   10.20 -      an error-prone task, though, so software tools to help automate
   10.21 -      this process have long been available.  The earliest automated
   10.22 -      revision control tools were intended to help a single user to
   10.23 -      manage revisions of a single file.  Over the past few decades,
   10.24 -      the scope of revision control tools has expanded greatly; they
   10.25 -      now manage multiple files, and help multiple people to work
   10.26 -      together.  The best modern revision control tools have no
   10.27 -      problem coping with thousands of people working together on
   10.28 -      projects that consist of hundreds of thousands of files.</para>
   10.29 -
   10.30 -    <sect2>
   10.31 -      <title>Why use revision control?</title>
   10.32 -
   10.33 -      <para>There are a number of reasons why you or your team might
   10.34 -	want to use an automated revision control tool for a
   10.35 -	project.</para>
   10.36 -      <itemizedlist>
   10.37 -	<listitem><para>It will track the history and evolution of
   10.38 -	    your project, so you don't have to.  For every change,
   10.39 -	    you'll have a log of <emphasis>who</emphasis> made it;
   10.40 -	    <emphasis>why</emphasis> they made it;
   10.41 -	    <emphasis>when</emphasis> they made it; and
   10.42 -	    <emphasis>what</emphasis> the change
   10.43 -	    was.</para></listitem>
   10.44 -	<listitem><para>When you're working with other people,
   10.45 -	    revision control software makes it easier for you to
   10.46 -	    collaborate.  For example, when people more or less
   10.47 -	    simultaneously make potentially incompatible changes, the
   10.48 -	    software will help you to identify and resolve those
   10.49 -	    conflicts.</para></listitem>
   10.50 -	<listitem><para>It can help you to recover from mistakes.  If
   10.51 -	    you make a change that later turns out to be in error, you
   10.52 -	    can revert to an earlier version of one or more files.  In
   10.53 -	    fact, a <emphasis>really</emphasis> good revision control
   10.54 -	    tool will even help you to efficiently figure out exactly
   10.55 -	    when a problem was introduced (see section <xref
   10.56 -	      linkend="sec.undo.bisect"/> for details).</para></listitem>
   10.57 -	<listitem><para>It will help you to work simultaneously on,
   10.58 -	    and manage the drift between, multiple versions of your
   10.59 -	    project.</para></listitem></itemizedlist>
   10.60 -      <para>Most of these reasons are equally valid---at least in
   10.61 -	theory---whether you're working on a project by yourself, or
   10.62 -	with a hundred other people.</para>
   10.63 -
   10.64 -      <para>A key question about the practicality of revision control
   10.65 -	at these two different scales (<quote>lone hacker</quote> and
   10.66 -	<quote>huge team</quote>) is how its
   10.67 -	<emphasis>benefits</emphasis> compare to its
   10.68 -	<emphasis>costs</emphasis>.  A revision control tool that's
   10.69 -	difficult to understand or use is going to impose a high
   10.70 -	cost.</para>
   10.71 -
   10.72 -      <para>A five-hundred-person project is likely to collapse under
   10.73 -	its own weight almost immediately without a revision control
   10.74 -	tool and process. In this case, the cost of using revision
   10.75 -	control might hardly seem worth considering, since
   10.76 -	<emphasis>without</emphasis> it, failure is almost
   10.77 -	guaranteed.</para>
   10.78 -
   10.79 -      <para>On the other hand, a one-person <quote>quick hack</quote>
   10.80 -	might seem like a poor place to use a revision control tool,
   10.81 -	because surely the cost of using one must be close to the
   10.82 -	overall cost of the project.  Right?</para>
   10.83 -
   10.84 -      <para>Mercurial uniquely supports <emphasis>both</emphasis> of
   10.85 -	these scales of development.  You can learn the basics in just
   10.86 -	a few minutes, and due to its low overhead, you can apply
   10.87 -	revision control to the smallest of projects with ease.  Its
   10.88 -	simplicity means you won't have a lot of abstruse concepts or
   10.89 -	command sequences competing for mental space with whatever
   10.90 -	you're <emphasis>really</emphasis> trying to do.  At the same
   10.91 -	time, Mercurial's high performance and peer-to-peer nature let
   10.92 -	you scale painlessly to handle large projects.</para>
   10.93 -
   10.94 -      <para>No revision control tool can rescue a poorly run project,
   10.95 -	but a good choice of tools can make a huge difference to the
   10.96 -	fluidity with which you can work on a project.</para>
   10.97 -
   10.98 -    </sect2>
   10.99 -    <sect2>
  10.100 -      <title>The many names of revision control</title>
  10.101 -
  10.102 -      <para>Revision control is a diverse field, so much so that it
  10.103 -	doesn't actually have a single name or acronym.  Here are a
  10.104 -	few of the more common names and acronyms you'll
  10.105 -	encounter:</para>
  10.106 -      <itemizedlist>
  10.107 -	<listitem><para>Revision control (RCS)</para></listitem>
  10.108 -	<listitem><para>Software configuration management (SCM), or
  10.109 -	    configuration management</para></listitem>
  10.110 -	<listitem><para>Source code management</para></listitem>
  10.111 -	<listitem><para>Source code control, or source
  10.112 -	    control</para></listitem>
  10.113 -	<listitem><para>Version control
  10.114 -	    (VCS)</para></listitem></itemizedlist>
  10.115 -      <para>Some people claim that these terms actually have different
  10.116 -	meanings, but in practice they overlap so much that there's no
  10.117 -	agreed or even useful way to tease them apart.</para>
  10.118 -
  10.119 -    </sect2>
  10.120 -  </sect1>
  10.121 -  <sect1>
  10.122 -    <title>A short history of revision control</title>
  10.123 -
  10.124 -    <para>The best known of the old-time revision control tools is
  10.125 -      SCCS (Source Code Control System), which Marc Rochkind wrote at
  10.126 -      Bell Labs, in the early 1970s.  SCCS operated on individual
  10.127 -      files, and required every person working on a project to have
  10.128 -      access to a shared workspace on a single system.  Only one
  10.129 -      person could modify a file at any time; arbitration for access
  10.130 -      to files was via locks.  It was common for people to lock files,
  10.131 -      and later forget to unlock them, preventing anyone else from
  10.132 -      modifying those files without the help of an
  10.133 -      administrator.</para>
  10.134 -
  10.135 -    <para>Walter Tichy developed a free alternative to SCCS in the
  10.136 -      early 1980s; he called his program RCS (Revision Control System).
  10.137 -      Like SCCS, RCS required developers to work in a single shared
  10.138 -      workspace, and to lock files to prevent multiple people from
  10.139 -      modifying them simultaneously.</para>
  10.140 -
  10.141 -    <para>Later in the 1980s, Dick Grune used RCS as a building block
  10.142 -      for a set of shell scripts he initially called cmt, but then
  10.143 -      renamed to CVS (Concurrent Versions System).  The big innovation
  10.144 -      of CVS was that it let developers work simultaneously and
  10.145 -      somewhat independently in their own personal workspaces.  The
  10.146 -      personal workspaces prevented developers from stepping on each
  10.147 -      other's toes all the time, as was common with SCCS and RCS. Each
  10.148 -      developer had a copy of every project file, and could modify
  10.149 -      their copies independently.  They had to merge their edits prior
  10.150 -      to committing changes to the central repository.</para>
  10.151 -
  10.152 -    <para>Brian Berliner took Grune's original scripts and rewrote
  10.153 -      them in C, releasing in 1989 the code that has since developed
  10.154 -      into the modern version of CVS.  CVS subsequently acquired the
  10.155 -      ability to operate over a network connection, giving it a
  10.156 -      client/server architecture.  CVS's architecture is centralised;
  10.157 -      only the server has a copy of the history of the project. Client
  10.158 -      workspaces just contain copies of recent versions of the
  10.159 -      project's files, and a little metadata to tell them where the
  10.160 -      server is.  CVS has been enormously successful; it is probably
  10.161 -      the world's most widely used revision control system.</para>
  10.162 -
  10.163 -    <para>In the early 1990s, Sun Microsystems developed an early
  10.164 -      distributed revision control system, called TeamWare.  A
  10.165 -      TeamWare workspace contains a complete copy of the project's
  10.166 -      history.  TeamWare has no notion of a central repository.  (CVS
  10.167 -      relied upon RCS for its history storage; TeamWare used
  10.168 -      SCCS.)</para>
  10.169 -
  10.170 -    <para>As the 1990s progressed, awareness grew of a number of
  10.171 -      problems with CVS.  It records simultaneous changes to multiple
  10.172 -      files individually, instead of grouping them together as a
  10.173 -      single logically atomic operation.  It does not manage its file
  10.174 -      hierarchy well; it is easy to make a mess of a repository by
  10.175 -      renaming files and directories.  Worse, its source code is
  10.176 -      difficult to read and maintain, which made the <quote>pain
  10.177 -	level</quote> of fixing these architectural problems
  10.178 -      prohibitive.</para>
  10.179 -
  10.180 -    <para>In 2001, Jim Blandy and Karl Fogel, two developers who had
  10.181 -      worked on CVS, started a project to replace it with a tool that
  10.182 -      would have a better architecture and cleaner code.  The result,
  10.183 -      Subversion, does not stray from CVS's centralised client/server
  10.184 -      model, but it adds multi-file atomic commits, better namespace
  10.185 -      management, and a number of other features that make it a
  10.186 -      generally better tool than CVS. Since its initial release, it
  10.187 -      has rapidly grown in popularity.</para>
  10.188 -
  10.189 -    <para>More or less simultaneously, Graydon Hoare began working on
  10.190 -      an ambitious distributed revision control system that he named
  10.191 -      Monotone. While Monotone addresses many of CVS's design flaws
  10.192 -      and has a peer-to-peer architecture, it goes beyond earlier (and
  10.193 -      subsequent) revision control tools in a number of innovative
  10.194 -      ways.  It uses cryptographic hashes as identifiers, and has an
  10.195 -      integral notion of <quote>trust</quote> for code from different
  10.196 -      sources.</para>
  10.197 -
  10.198 -    <para>Mercurial began life in 2005.  While a few aspects of its
  10.199 -      design are influenced by Monotone, Mercurial focuses on ease of
  10.200 -      use, high performance, and scalability to very large
  10.201 -      projects.</para>
  10.202 -
  10.203 -  </sect1>
  10.204 -  <sect1>
  10.205 -    <title>Trends in revision control</title>
  10.206 -
  10.207 -    <para>There has been an unmistakable trend in the development and
  10.208 -      use of revision control tools over the past four decades, as
  10.209 -      people have become familiar with the capabilities of their tools
  10.210 -      and constrained by their limitations.</para>
  10.211 -
  10.212 -    <para>The first generation began by managing single files on
  10.213 -      individual computers.  Although these tools represented a huge
  10.214 -      advance over ad-hoc manual revision control, their locking model
  10.215 -      and reliance on a single computer limited them to small,
  10.216 -      tightly-knit teams.</para>
  10.217 -
  10.218 -    <para>The second generation loosened these constraints by moving
  10.219 -      to network-centered architectures, and managing entire projects
  10.220 -      at a time.  As projects grew larger, they ran into new problems.
  10.221 -      With clients needing to talk to servers very frequently, server
  10.222 -      scaling became an issue for large projects.  An unreliable
  10.223 -      network connection could prevent remote users from being able to
  10.224 -      talk to the server at all.  As open source projects started
  10.225 -      making read-only access available anonymously to anyone, people
  10.226 -      without commit privileges found that they could not use the
  10.227 -      tools to interact with a project in a natural way, as they could
  10.228 -      not record their changes.</para>
  10.229 -
  10.230 -    <para>The current generation of revision control tools is
  10.231 -      peer-to-peer in nature.  All of these systems have dropped the
  10.232 -      dependency on a single central server, and allow people to
  10.233 -      distribute their revision control data to where it's actually
  10.234 -      needed.  Collaboration over the Internet has moved from
  10.235 -      constrained by technology to a matter of choice and consensus.
  10.236 -      Modern tools can operate offline indefinitely and autonomously,
  10.237 -      with a network connection only needed when syncing changes with
  10.238 -      another repository.</para>
  10.239 -
  10.240 -  </sect1>
  10.241 -  <sect1>
  10.242 -    <title>A few of the advantages of distributed revision
  10.243 -      control</title>
  10.244 -
  10.245 -    <para>Even though distributed revision control tools have for
  10.246 -      several years been as robust and usable as their
  10.247 -      previous-generation counterparts, people using older tools have
  10.248 -      not yet necessarily woken up to their advantages.  There are a
  10.249 -      number of ways in which distributed tools shine relative to
  10.250 -      centralised ones.</para>
  10.251 -
  10.252 -    <para>For an individual developer, distributed tools are almost
  10.253 -      always much faster than centralised tools.  This is for a simple
  10.254 -      reason: a centralised tool needs to talk over the network for
  10.255 -      many common operations, because most metadata is stored in a
  10.256 -      single copy on the central server.  A distributed tool stores
  10.257 -      all of its metadata locally.  All else being equal, talking over
  10.258 -      the network adds overhead to a centralised tool.  Don't
  10.259 -      underestimate the value of a snappy, responsive tool: you're
  10.260 -      going to spend a lot of time interacting with your revision
  10.261 -      control software.</para>
  10.262 -
  10.263 -    <para>Distributed tools are indifferent to the vagaries of your
  10.264 -      server infrastructure, again because they replicate metadata to
  10.265 -      so many locations.  If you use a centralised system and your
  10.266 -      server catches fire, you'd better hope that your backup media
  10.267 -      are reliable, and that your last backup was recent and actually
  10.268 -      worked.  With a distributed tool, you have many backups
  10.269 -      available on every contributor's computer.</para>
  10.270 -
  10.271 -    <para>The reliability of your network will affect distributed
  10.272 -      tools far less than it will centralised tools.  You can't even
  10.273 -      use a centralised tool without a network connection, except for
  10.274 -      a few highly constrained commands.  With a distributed tool, if
  10.275 -      your network connection goes down while you're working, you may
  10.276 -      not even notice.  The only thing you won't be able to do is talk
  10.277 -      to repositories on other computers, something that is relatively
  10.278 -      rare compared with local operations.  If you have a far-flung
  10.279 -      team of collaborators, this may be significant.</para>
  10.280 -
  10.281 -    <sect2>
  10.282 -      <title>Advantages for open source projects</title>
  10.283 -
  10.284 -      <para>If you take a shine to an open source project and decide
  10.285 -	that you would like to start hacking on it, and that project
  10.286 -	uses a distributed revision control tool, you are at once a
  10.287 -	peer with the people who consider themselves the
  10.288 -	<quote>core</quote> of that project.  If they publish their
  10.289 -	repositories, you can immediately copy their project history,
  10.290 -	start making changes, and record your work, using the same
  10.291 -	tools in the same ways as insiders.  By contrast, with a
  10.292 -	centralised tool, you must use the software in a <quote>read
  10.293 -	  only</quote> mode unless someone grants you permission to
  10.294 -	commit changes to their central server.  Until then, you won't
  10.295 -	be able to record changes, and your local modifications will
  10.296 -	be at risk of corruption any time you try to update your
  10.297 -	client's view of the repository.</para>
  10.298 -
  10.299 -      <sect3>
  10.300 -	<title>The forking non-problem</title>
  10.301 -
  10.302 -	<para>It has been suggested that distributed revision control
  10.303 -	  tools pose some sort of risk to open source projects because
  10.304 -	  they make it easy to <quote>fork</quote> the development of
  10.305 -	  a project.  A fork happens when there are differences in
  10.306 -	  opinion or attitude between groups of developers that cause
  10.307 -	  them to decide that they can't work together any longer.
  10.308 -	  Each side takes a more or less complete copy of the
  10.309 -	  project's source code, and goes off in its own
  10.310 -	  direction.</para>
  10.311 -
  10.312 -	<para>Sometimes the camps in a fork decide to reconcile their
  10.313 -	  differences. With a centralised revision control system, the
  10.314 -	  <emphasis>technical</emphasis> process of reconciliation is
  10.315 -	  painful, and has to be performed largely by hand.  You have
  10.316 -	  to decide whose revision history is going to
  10.317 -	  <quote>win</quote>, and graft the other team's changes into
  10.318 -	  the tree somehow. This usually loses some or all of one
  10.319 -	  side's revision history.</para>
  10.320 -
  10.321 -	<para>What distributed tools do with respect to forking is
  10.322 -	  they make forking the <emphasis>only</emphasis> way to
  10.323 -	  develop a project.  Every single change that you make is
  10.324 -	  potentially a fork point.  The great strength of this
  10.325 -	  approach is that a distributed revision control tool has to
  10.326 -	  be really good at <emphasis>merging</emphasis> forks,
  10.327 -	  because forks are absolutely fundamental: they happen all
  10.328 -	  the time.</para>
  10.329 -
  10.330 -	<para>If every piece of work that everybody does, all the
  10.331 -	  time, is framed in terms of forking and merging, then what
  10.332 -	  the open source world refers to as a <quote>fork</quote>
  10.333 -	  becomes <emphasis>purely</emphasis> a social issue.  If
  10.334 -	  anything, distributed tools <emphasis>lower</emphasis> the
  10.335 -	  likelihood of a fork:</para>
  10.336 -	<itemizedlist>
  10.337 -	  <listitem><para>They eliminate the social distinction that
  10.338 -	      centralised tools impose: that between insiders (people
  10.339 -	      with commit access) and outsiders (people
  10.340 -	      without).</para></listitem>
  10.341 -	  <listitem><para>They make it easier to reconcile after a
  10.342 -	      social fork, because all that's involved from the
  10.343 -	      perspective of the revision control software is just
  10.344 -	      another merge.</para></listitem></itemizedlist>
  10.345 -
  10.346 -	<para>Some people resist distributed tools because they want
  10.347 -	  to retain tight control over their projects, and they
  10.348 -	  believe that centralised tools give them this control.
  10.349 -	  However, if you're of this belief, and you publish your CVS
  10.350 -	  or Subversion repositories publicly, there are plenty of
  10.351 -	  tools available that can pull out your entire project's
  10.352 -	  history (albeit slowly) and recreate it somewhere that you
  10.353 -	  don't control.  So while your control in this case is
  10.354 -	  illusory, you are forgoing the ability to fluidly
  10.355 -	  collaborate with whatever people feel compelled to mirror
  10.356 -	  and fork your history.</para>
  10.357 -
  10.358 -      </sect3>
  10.359 -    </sect2>
  10.360 -    <sect2>
  10.361 -      <title>Advantages for commercial projects</title>
  10.362 -
  10.363 -      <para>Many commercial projects are undertaken by teams that are
  10.364 -	scattered across the globe.  Contributors who are far from a
  10.365 -	central server will see slower command execution and perhaps
  10.366 -	less reliability.  Commercial revision control systems attempt
  10.367 -	to ameliorate these problems with remote-site replication
  10.368 -	add-ons that are typically expensive to buy and cantankerous
  10.369 -	to administer.  A distributed system doesn't suffer from these
  10.370 -	problems in the first place.  Better yet, you can easily set
  10.371 -	up multiple authoritative servers, say one per site, so that
  10.372 -	there's no redundant communication between repositories over
  10.373 -	expensive long-haul network links.</para>
  10.374 -
  10.375 -      <para>Centralised revision control systems tend to have
  10.376 -	relatively low scalability.  It's not unusual for an expensive
  10.377 -	centralised system to fall over under the combined load of
  10.378 -	just a few dozen concurrent users.  Once again, the typical
  10.379 -	response tends to be an expensive and clunky replication
  10.380 -	facility.  Since the load on a central server---if you have
  10.381 -	one at all---is many times lower with a distributed tool
  10.382 -	(because all of the data is replicated everywhere), a single
  10.383 -	cheap server can handle the needs of a much larger team, and
  10.384 -	replication to balance load becomes a simple matter of
  10.385 -	scripting.</para>
  10.386 -
  10.387 -      <para>If you have an employee in the field, troubleshooting a
  10.388 -	problem at a customer's site, they'll benefit from distributed
  10.389 -	revision control. The tool will let them generate custom
  10.390 -	builds, try different fixes in isolation from each other, and
  10.391 -	search efficiently through history for the sources of bugs and
  10.392 -	regressions in the customer's environment, all without needing
  10.393 -	to connect to your company's network.</para>
  10.394 -
  10.395 -    </sect2>
  10.396 -  </sect1>
  10.397 -  <sect1>
  10.398 -    <title>Why choose Mercurial?</title>
  10.399 -
  10.400 -    <para>Mercurial has a unique set of properties that make it a
  10.401 -      particularly good choice as a revision control system.</para>
  10.402 -    <itemizedlist>
  10.403 -      <listitem><para>It is easy to learn and use.</para></listitem>
  10.404 -      <listitem><para>It is lightweight.</para></listitem>
  10.405 -      <listitem><para>It scales excellently.</para></listitem>
  10.406 -      <listitem><para>It is easy to
  10.407 -	  customise.</para></listitem></itemizedlist>
  10.408 -
  10.409 -    <para>If you are at all familiar with revision control systems,
  10.410 -      you should be able to get up and running with Mercurial in less
  10.411 -      than five minutes.  Even if not, it will take no more than a few
  10.412 -      minutes longer.  Mercurial's command and feature sets are
  10.413 -      generally uniform and consistent, so you can keep track of a few
  10.414 -      general rules instead of a host of exceptions.</para>
  10.415 -
  10.416 -    <para>On a small project, you can start working with Mercurial in
  10.417 -      moments. Creating new changes and branches; transferring changes
  10.418 -      around (whether locally or over a network); and history and
  10.419 -      status operations are all fast.  Mercurial attempts to stay
  10.420 -      nimble and largely out of your way by combining low cognitive
  10.421 -      overhead with blazingly fast operations.</para>
  10.422 -
  10.423 -    <para>The usefulness of Mercurial is not limited to small
  10.424 -      projects: it is used by projects with hundreds to thousands of
  10.425 -      contributors, each containing tens of thousands of files and
  10.426 -      hundreds of megabytes of source code.</para>
  10.427 -
  10.428 -    <para>If the core functionality of Mercurial is not enough for
  10.429 -      you, it's easy to build on.  Mercurial is well suited to
  10.430 -      scripting tasks, and its clean internals and implementation in
  10.431 -      Python make it easy to add features in the form of extensions.
  10.432 -      There are a number of popular and useful extensions already
  10.433 -      available, ranging from helping to identify bugs to improving
  10.434 -      performance.</para>
  10.435 -
  10.436 -  </sect1>
  10.437 -  <sect1>
  10.438 -    <title>Mercurial compared with other tools</title>
  10.439 -
  10.440 -    <para>Before you read on, please understand that this section
  10.441 -      necessarily reflects my own experiences, interests, and (dare I
  10.442 -      say it) biases.  I have used every one of the revision control
  10.443 -      tools listed below, in most cases for several years at a
  10.444 -      time.</para>
  10.445 -
  10.446 -
  10.447 -    <sect2>
  10.448 -      <title>Subversion</title>
  10.449 -
  10.450 -      <para>Subversion is a popular revision control tool, developed
  10.451 -	to replace CVS.  It has a centralised client/server
  10.452 -	architecture.</para>
  10.453 -
  10.454 -      <para>Subversion and Mercurial have similarly named commands for
  10.455 -	performing the same operations, so if you're familiar with
  10.456 -	one, it is easy to learn to use the other.  Both tools are
  10.457 -	portable to all popular operating systems.</para>
  10.458 -
  10.459 -      <para>Prior to version 1.5, Subversion had no useful support for
  10.460 -	merges. At the time of writing, its merge tracking capability
  10.461 -	is new, and known to be <ulink
  10.462 -	  url="http://svnbook.red-bean.com/nightly/en/svn.branchmerge.advanced.html#svn.branchmerge.advanced.finalword">complicated 
  10.463 -	  and buggy</ulink>.</para>
  10.464 -
  10.465 -      <para>Mercurial has a substantial performance advantage over
  10.466 -	Subversion on every revision control operation I have
  10.467 -	benchmarked.  I have measured its advantage as ranging from a
  10.468 -	factor of two to a factor of six when compared with Subversion
  10.469 -	1.4.3's <emphasis>ra_local</emphasis> file store, which is the
  10.470 -	fastest access method available.  In more realistic
  10.471 -	deployments involving a network-based store, Subversion will
  10.472 -	be at a substantially larger disadvantage.  Because many
  10.473 -	Subversion commands must talk to the server and Subversion
  10.474 -	does not have useful replication facilities, server capacity
  10.475 -	and network bandwidth become bottlenecks for modestly large
  10.476 -	projects.</para>
  10.477 -
  10.478 -      <para>Additionally, Subversion incurs substantial storage
  10.479 -	overhead to avoid network transactions for a few common
  10.480 -	operations, such as finding modified files
  10.481 -	(<literal>status</literal>) and displaying modifications
  10.482 -	against the current revision (<literal>diff</literal>).  As a
  10.483 -	result, a Subversion working copy is often the same size as,
  10.484 -	or larger than, a Mercurial repository and working directory,
  10.485 -	even though the Mercurial repository contains a complete
  10.486 -	history of the project.</para>
  10.487 -
  10.488 -      <para>Subversion is widely supported by third party tools.
  10.489 -	Mercurial currently lags considerably in this area.  This gap
  10.490 -	is closing, however, and indeed some of Mercurial's GUI tools
  10.491 -	now outshine their Subversion equivalents.  Like Mercurial,
  10.492 -	Subversion has an excellent user manual.</para>
  10.493 -
  10.494 -      <para>Because Subversion doesn't store revision history on the
  10.495 -	client, it is well suited to managing projects that deal with
  10.496 -	lots of large, opaque binary files.  If you check in fifty
  10.497 -	revisions to an incompressible 10MB file, Subversion's
  10.498 -	client-side space usage stays constant The space used by any
  10.499 -	distributed SCM will grow rapidly in proportion to the number
  10.500 -	of revisions, because the differences between each revision
  10.501 -	are large.</para>
  10.502 -
  10.503 -      <para>In addition, it's often difficult or, more usually,
  10.504 -	impossible to merge different versions of a binary file.
  10.505 -	Subversion's ability to let a user lock a file, so that they
  10.506 -	temporarily have the exclusive right to commit changes to it,
  10.507 -	can be a significant advantage to a project where binary files
  10.508 -	are widely used.</para>
  10.509 -
  10.510 -      <para>Mercurial can import revision history from a Subversion
  10.511 -	repository. It can also export revision history to a
  10.512 -	Subversion repository.  This makes it easy to <quote>test the
  10.513 -	  waters</quote> and use Mercurial and Subversion in parallel
  10.514 -	before deciding to switch.  History conversion is incremental,
  10.515 -	so you can perform an initial conversion, then small
  10.516 -	additional conversions afterwards to bring in new
  10.517 -	changes.</para>
  10.518 -
  10.519 -
  10.520 -    </sect2>
  10.521 -    <sect2>
  10.522 -      <title>Git</title>
  10.523 -
  10.524 -      <para>Git is a distributed revision control tool that was
  10.525 -	developed for managing the Linux kernel source tree.  Like
  10.526 -	Mercurial, its early design was somewhat influenced by
  10.527 -	Monotone.</para>
  10.528 -
  10.529 -      <para>Git has a very large command set, with version 1.5.0
  10.530 -	providing 139 individual commands.  It has something of a
  10.531 -	reputation for being difficult to learn.  Compared to Git,
  10.532 -	Mercurial has a strong focus on simplicity.</para>
  10.533 -
  10.534 -      <para>In terms of performance, Git is extremely fast.  In
  10.535 -	several cases, it is faster than Mercurial, at least on Linux,
  10.536 -	while Mercurial performs better on other operations.  However,
  10.537 -	on Windows, the performance and general level of support that
  10.538 -	Git provides is, at the time of writing, far behind that of
  10.539 -	Mercurial.</para>
  10.540 -
  10.541 -      <para>While a Mercurial repository needs no maintenance, a Git
  10.542 -	repository requires frequent manual <quote>repacks</quote> of
  10.543 -	its metadata.  Without these, performance degrades, while
  10.544 -	space usage grows rapidly.  A server that contains many Git
  10.545 -	repositories that are not rigorously and frequently repacked
  10.546 -	will become heavily disk-bound during backups, and there have
  10.547 -	been instances of daily backups taking far longer than 24
  10.548 -	hours as a result.  A freshly packed Git repository is
  10.549 -	slightly smaller than a Mercurial repository, but an unpacked
  10.550 -	repository is several orders of magnitude larger.</para>
  10.551 -
  10.552 -      <para>The core of Git is written in C.  Many Git commands are
  10.553 -	implemented as shell or Perl scripts, and the quality of these
  10.554 -	scripts varies widely. I have encountered several instances
  10.555 -	where scripts charged along blindly in the presence of errors
  10.556 -	that should have been fatal.</para>
  10.557 -
  10.558 -      <para>Mercurial can import revision history from a Git
  10.559 -	repository.</para>
  10.560 -
  10.561 -
  10.562 -    </sect2>
  10.563 -    <sect2>
  10.564 -      <title>CVS</title>
  10.565 -
  10.566 -      <para>CVS is probably the most widely used revision control tool
  10.567 -	in the world.  Due to its age and internal untidiness, it has
  10.568 -	been only lightly maintained for many years.</para>
  10.569 -
  10.570 -      <para>It has a centralised client/server architecture.  It does
  10.571 -	not group related file changes into atomic commits, making it
  10.572 -	easy for people to <quote>break the build</quote>: one person
  10.573 -	can successfully commit part of a change and then be blocked
  10.574 -	by the need for a merge, causing other people to see only a
  10.575 -	portion of the work they intended to do.  This also affects
  10.576 -	how you work with project history.  If you want to see all of
  10.577 -	the modifications someone made as part of a task, you will
  10.578 -	need to manually inspect the descriptions and timestamps of
  10.579 -	the changes made to each file involved (if you even know what
  10.580 -	those files were).</para>
  10.581 -
  10.582 -      <para>CVS has a muddled notion of tags and branches that I will
  10.583 -	not attempt to even describe.  It does not support renaming of
  10.584 -	files or directories well, making it easy to corrupt a
  10.585 -	repository.  It has almost no internal consistency checking
  10.586 -	capabilities, so it is usually not even possible to tell
  10.587 -	whether or how a repository is corrupt.  I would not recommend
  10.588 -	CVS for any project, existing or new.</para>
  10.589 -
  10.590 -      <para>Mercurial can import CVS revision history.  However, there
  10.591 -	are a few caveats that apply; these are true of every other
  10.592 -	revision control tool's CVS importer, too.  Due to CVS's lack
  10.593 -	of atomic changes and unversioned filesystem hierarchy, it is
  10.594 -	not possible to reconstruct CVS history completely accurately;
  10.595 -	some guesswork is involved, and renames will usually not show
  10.596 -	up.  Because a lot of advanced CVS administration has to be
  10.597 -	done by hand and is hence error-prone, it's common for CVS
  10.598 -	importers to run into multiple problems with corrupted
  10.599 -	repositories (completely bogus revision timestamps and files
  10.600 -	that have remained locked for over a decade are just two of
  10.601 -	the less interesting problems I can recall from personal
  10.602 -	experience).</para>
  10.603 -
  10.604 -      <para>Mercurial can import revision history from a CVS
  10.605 -	repository.</para>
  10.606 -
  10.607 -
  10.608 -    </sect2>
  10.609 -    <sect2>
  10.610 -      <title>Commercial tools</title>
  10.611 -
  10.612 -      <para>Perforce has a centralised client/server architecture,
  10.613 -	with no client-side caching of any data.  Unlike modern
  10.614 -	revision control tools, Perforce requires that a user run a
  10.615 -	command to inform the server about every file they intend to
  10.616 -	edit.</para>
  10.617 -
  10.618 -      <para>The performance of Perforce is quite good for small teams,
  10.619 -	but it falls off rapidly as the number of users grows beyond a
  10.620 -	few dozen. Modestly large Perforce installations require the
  10.621 -	deployment of proxies to cope with the load their users
  10.622 -	generate.</para>
  10.623 -
  10.624 -
  10.625 -    </sect2>
  10.626 -    <sect2>
  10.627 -      <title>Choosing a revision control tool</title>
  10.628 -
  10.629 -      <para>With the exception of CVS, all of the tools listed above
  10.630 -	have unique strengths that suit them to particular styles of
  10.631 -	work.  There is no single revision control tool that is best
  10.632 -	in all situations.</para>
  10.633 -
  10.634 -      <para>As an example, Subversion is a good choice for working
  10.635 -	with frequently edited binary files, due to its centralised
  10.636 -	nature and support for file locking.</para>
  10.637 -
  10.638 -      <para>I personally find Mercurial's properties of simplicity,
  10.639 -	performance, and good merge support to be a compelling
  10.640 -	combination that has served me well for several years.</para>
  10.641 -
  10.642 -
  10.643 -    </sect2>
  10.644 -  </sect1>
  10.645 -  <sect1>
  10.646 -    <title>Switching from another tool to Mercurial</title>
  10.647 -
  10.648 -    <para>Mercurial is bundled with an extension named <literal
  10.649 -	role="hg-ext">convert</literal>, which can incrementally
  10.650 -      import revision history from several other revision control
  10.651 -      tools.  By <quote>incremental</quote>, I mean that you can
  10.652 -      convert all of a project's history to date in one go, then rerun
  10.653 -      the conversion later to obtain new changes that happened after
  10.654 -      the initial conversion.</para>
  10.655 -
  10.656 -    <para>The revision control tools supported by <literal
  10.657 -	role="hg-ext">convert</literal> are as follows:</para>
  10.658 -    <itemizedlist>
  10.659 -      <listitem><para>Subversion</para></listitem>
  10.660 -      <listitem><para>CVS</para></listitem>
  10.661 -      <listitem><para>Git</para></listitem>
  10.662 -      <listitem><para>Darcs</para></listitem></itemizedlist>
  10.663 -
  10.664 -    <para>In addition, <literal role="hg-ext">convert</literal> can
  10.665 -      export changes from Mercurial to Subversion.  This makes it
  10.666 -      possible to try Subversion and Mercurial in parallel before
  10.667 -      committing to a switchover, without risking the loss of any
  10.668 -      work.</para>
  10.669 -
  10.670 -    <para>The <command role="hg-ext-conver">convert</command> command
  10.671 -      is easy to use.  Simply point it at the path or URL of the
  10.672 -      source repository, optionally give it the name of the
  10.673 -      destination repository, and it will start working.  After the
  10.674 -      initial conversion, just run the same command again to import
  10.675 -      new changes.</para>
  10.676 -  </sect1>
  10.677 -</chapter>
  10.678 -
  10.679 -<!--
  10.680 -local variables: 
  10.681 -sgml-parent-document: ("00book.xml" "book" "chapter")
  10.682 -end:
  10.683 --->
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/en/ch01-tour-basic.xml	Fri Mar 20 16:43:35 2009 +0800
    11.3 @@ -0,0 +1,862 @@
    11.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    11.5 +
    11.6 +<chapter id="chap.tour-basic">
    11.7 +  <?dbhtml filename="a-tour-of-mercurial-the-basics.html"?>
    11.8 +  <title>A tour of Mercurial: the basics</title>
    11.9 +
   11.10 +  <sect1 id="sec.tour.install">
   11.11 +    <title>Installing Mercurial on your system</title>
   11.12 +
   11.13 +    <para>Prebuilt binary packages of Mercurial are available for
   11.14 +      every popular operating system.  These make it easy to start
   11.15 +      using Mercurial on your computer immediately.</para>
   11.16 +
   11.17 +    <sect2>
   11.18 +      <title>Linux</title>
   11.19 +
   11.20 +      <para>Because each Linux distribution has its own packaging
   11.21 +	tools, policies, and rate of development, it's difficult to
   11.22 +	give a comprehensive set of instructions on how to install
   11.23 +	Mercurial binaries.  The version of Mercurial that you will
   11.24 +	end up with can vary depending on how active the person is who
   11.25 +	maintains the package for your distribution.</para>
   11.26 +
   11.27 +      <para>To keep things simple, I will focus on installing
   11.28 +	Mercurial from the command line under the most popular Linux
   11.29 +	distributions.  Most of these distributions provide graphical
   11.30 +	package managers that will let you install Mercurial with a
   11.31 +	single click; the package name to look for is
   11.32 +	<literal>mercurial</literal>.</para>
   11.33 +
   11.34 +      <itemizedlist>
   11.35 +	<listitem><para>Debian:</para>
   11.36 +	  <programlisting>apt-get install mercurial</programlisting></listitem>
   11.37 +	<listitem><para>Fedora Core:</para>
   11.38 +	  <programlisting>yum install mercurial</programlisting></listitem>
   11.39 +	<listitem><para>Gentoo:</para>
   11.40 +	  <programlisting>emerge mercurial</programlisting></listitem>
   11.41 +	<listitem><para>OpenSUSE:</para>
   11.42 +	  <programlisting>yum install mercurial</programlisting></listitem>
   11.43 +	<listitem><para>Ubuntu: Ubuntu's Mercurial package is based on
   11.44 +	    Debian's.  To install it, run the following
   11.45 +	    command.</para>
   11.46 +	  <programlisting>apt-get install mercurial</programlisting></listitem>
   11.47 +      </itemizedlist>
   11.48 +
   11.49 +    </sect2>
   11.50 +    <sect2>
   11.51 +      <title>Solaris</title>
   11.52 +
   11.53 +      <para>SunFreeWare, at <ulink
   11.54 +	  url="http://www.sunfreeware.com">http://www.sunfreeware.com</ulink>, 
   11.55 +	is a good source for a large number of pre-built Solaris
   11.56 +	packages for 32 and 64 bit Intel and Sparc architectures,
   11.57 +	including current versions of Mercurial.</para>
   11.58 +
   11.59 +    </sect2>
   11.60 +    <sect2>
   11.61 +      <title>Mac OS X</title>
   11.62 +
   11.63 +      <para>Lee Cantey publishes an installer of Mercurial for Mac OS
   11.64 +	X at <ulink
   11.65 +	  url="http://mercurial.berkwood.com">http://mercurial.berkwood.com</ulink>. 
   11.66 +	This package works on both Intel- and Power-based Macs. Before
   11.67 +	you can use it, you must install a compatible version of
   11.68 +	Universal MacPython <citation>web:macpython</citation>. This
   11.69 +	is easy to do; simply follow the instructions on Lee's
   11.70 +	site.</para>
   11.71 +
   11.72 +      <para>It's also possible to install Mercurial using Fink or
   11.73 +	MacPorts, two popular free package managers for Mac OS X.  If
   11.74 +	you have Fink, use <command>sudo apt-get install
   11.75 +	  mercurial-py25</command>.  If MacPorts, <command>sudo port
   11.76 +	  install mercurial</command>.</para>
   11.77 +
   11.78 +    </sect2>
   11.79 +    <sect2>
   11.80 +      <title>Windows</title>
   11.81 +
   11.82 +      <para>Lee Cantey publishes an installer of Mercurial for Windows
   11.83 +	at <ulink
   11.84 +	  url="http://mercurial.berkwood.com">http://mercurial.berkwood.com</ulink>. 
   11.85 +	This package has no external dependencies; it <quote>just
   11.86 +	  works</quote>.</para>
   11.87 +
   11.88 +      <note>
   11.89 +	<para>  The Windows version of Mercurial does not
   11.90 +	  automatically convert line endings between Windows and Unix
   11.91 +	  styles.  If you want to share work with Unix users, you must
   11.92 +	  do a little additional configuration work. XXX Flesh this
   11.93 +	  out.</para>
   11.94 +      </note>
   11.95 +
   11.96 +    </sect2>
   11.97 +  </sect1>
   11.98 +  <sect1>
   11.99 +    <title>Getting started</title>
  11.100 +
  11.101 +    <para>To begin, we'll use the <command role="hg-cmd">hg
  11.102 +	version</command> command to find out whether Mercurial is
  11.103 +      actually installed properly.  The actual version information
  11.104 +      that it prints isn't so important; it's whether it prints
  11.105 +      anything at all that we care about.</para>
  11.106 +
  11.107 +    &interaction.tour.version;
  11.108 +
  11.109 +    <sect2>
  11.110 +      <title>Built-in help</title>
  11.111 +
  11.112 +      <para>Mercurial provides a built-in help system.  This is
  11.113 +	  invaluable for those times when you find yourself stuck
  11.114 +	  trying to remember how to run a command.  If you are
  11.115 +	  completely stuck, simply run <command role="hg-cmd">hg
  11.116 +	    help</command>; it will print a brief list of commands,
  11.117 +	  along with a description of what each does.  If you ask for
  11.118 +	  help on a specific command (as below), it prints more
  11.119 +	  detailed information.</para>
  11.120 +
  11.121 +	&interaction.tour.help;
  11.122 +
  11.123 +	<para>For a more impressive level of detail (which you won't
  11.124 +	  usually need) run <command role="hg-cmd">hg help <option
  11.125 +	      role="hg-opt-global">-v</option></command>.  The <option
  11.126 +	    role="hg-opt-global">-v</option> option is short for
  11.127 +	  <option role="hg-opt-global">--verbose</option>, and tells
  11.128 +	  Mercurial to print more information than it usually
  11.129 +	  would.</para>
  11.130 +
  11.131 +    </sect2>
  11.132 +  </sect1>
  11.133 +  <sect1>
  11.134 +    <title>Working with a repository</title>
  11.135 +
  11.136 +    <para>In Mercurial, everything happens inside a
  11.137 +      <emphasis>repository</emphasis>.  The repository for a project
  11.138 +      contains all of the files that <quote>belong to</quote> that
  11.139 +      project, along with a historical record of the project's
  11.140 +      files.</para>
  11.141 +
  11.142 +    <para>There's nothing particularly magical about a repository; it
  11.143 +      is simply a directory tree in your filesystem that Mercurial
  11.144 +      treats as special. You can rename or delete a repository any
  11.145 +      time you like, using either the command line or your file
  11.146 +      browser.</para>
  11.147 +
  11.148 +    <sect2>
  11.149 +      <title>Making a local copy of a repository</title>
  11.150 +
  11.151 +      <para><emphasis>Copying</emphasis> a repository is just a little
  11.152 +	bit special.  While you could use a normal file copying
  11.153 +	command to make a copy of a repository, it's best to use a
  11.154 +	built-in command that Mercurial provides.  This command is
  11.155 +	called <command role="hg-cmd">hg clone</command>, because it
  11.156 +	creates an identical copy of an existing repository.</para>
  11.157 +
  11.158 +      &interaction.tour.clone;
  11.159 +
  11.160 +      <para>If our clone succeeded, we should now have a local
  11.161 +	directory called <filename class="directory">hello</filename>.
  11.162 +	This directory will contain some files.</para>
  11.163 +
  11.164 +      &interaction.tour.ls;
  11.165 +
  11.166 +      <para>These files have the same contents and history in our
  11.167 +	repository as they do in the repository we cloned.</para>
  11.168 +
  11.169 +      <para>Every Mercurial repository is complete, self-contained,
  11.170 +	and independent.  It contains its own private copy of a
  11.171 +	project's files and history.  A cloned repository remembers
  11.172 +	the location of the repository it was cloned from, but it does
  11.173 +	not communicate with that repository, or any other, unless you
  11.174 +	tell it to.</para>
  11.175 +
  11.176 +      <para>What this means for now is that we're free to experiment
  11.177 +	with our repository, safe in the knowledge that it's a private
  11.178 +	<quote>sandbox</quote> that won't affect anyone else.</para>
  11.179 +
  11.180 +    </sect2>
  11.181 +    <sect2>
  11.182 +      <title>What's in a repository?</title>
  11.183 +
  11.184 +      <para>When we take a more detailed look inside a repository, we
  11.185 +	can see that it contains a directory named <filename
  11.186 +	  class="directory">.hg</filename>.  This is where Mercurial
  11.187 +	keeps all of its metadata for the repository.</para>
  11.188 +
  11.189 +      &interaction.tour.ls-a;
  11.190 +
  11.191 +      <para>The contents of the <filename
  11.192 +	  class="directory">.hg</filename> directory and its
  11.193 +	subdirectories are private to Mercurial.  Every other file and
  11.194 +	directory in the repository is yours to do with as you
  11.195 +	please.</para>
  11.196 +
  11.197 +      <para>To introduce a little terminology, the <filename
  11.198 +	  class="directory">.hg</filename> directory is the
  11.199 +	<quote>real</quote> repository, and all of the files and
  11.200 +	directories that coexist with it are said to live in the
  11.201 +	<emphasis>working directory</emphasis>.  An easy way to
  11.202 +	remember the distinction is that the
  11.203 +	<emphasis>repository</emphasis> contains the
  11.204 +	<emphasis>history</emphasis> of your project, while the
  11.205 +	<emphasis>working directory</emphasis> contains a
  11.206 +	<emphasis>snapshot</emphasis> of your project at a particular
  11.207 +	point in history.</para>
  11.208 +
  11.209 +    </sect2>
  11.210 +  </sect1>
  11.211 +  <sect1>
  11.212 +    <title>A tour through history</title>
  11.213 +
  11.214 +    <para>One of the first things we might want to do with a new,
  11.215 +      unfamiliar repository is understand its history.  The <command
  11.216 +	role="hg-cmd">hg log</command> command gives us a view of
  11.217 +      history.</para>
  11.218 +
  11.219 +    &interaction.tour.log;
  11.220 +
  11.221 +    <para>By default, this command prints a brief paragraph of output
  11.222 +      for each change to the project that was recorded.  In Mercurial
  11.223 +      terminology, we call each of these recorded events a
  11.224 +      <emphasis>changeset</emphasis>, because it can contain a record
  11.225 +      of changes to several files.</para>
  11.226 +
  11.227 +    <para>The fields in a record of output from <command
  11.228 +	role="hg-cmd">hg log</command> are as follows.</para>
  11.229 +    <itemizedlist>
  11.230 +      <listitem><para><literal>changeset</literal>: This field has the
  11.231 +	  format of a number, followed by a colon, followed by a
  11.232 +	  hexadecimal string.  These are
  11.233 +	  <emphasis>identifiers</emphasis> for the changeset.  There
  11.234 +	  are two identifiers because the number is shorter and easier
  11.235 +	  to type than the hex string.</para></listitem>
  11.236 +      <listitem><para><literal>user</literal>: The identity of the
  11.237 +	  person who created the changeset.  This is a free-form
  11.238 +	  field, but it most often contains a person's name and email
  11.239 +	  address.</para></listitem>
  11.240 +      <listitem><para><literal>date</literal>: The date and time on
  11.241 +	  which the changeset was created, and the timezone in which
  11.242 +	  it was created.  (The date and time are local to that
  11.243 +	  timezone; they display what time and date it was for the
  11.244 +	  person who created the changeset.)</para></listitem>
  11.245 +      <listitem><para><literal>summary</literal>: The first line of
  11.246 +	  the text message that the creator of the changeset entered
  11.247 +	  to describe the changeset.</para></listitem></itemizedlist>
  11.248 +    <para>The default output printed by <command role="hg-cmd">hg
  11.249 +	log</command> is purely a summary; it is missing a lot of
  11.250 +      detail.</para>
  11.251 +
  11.252 +    <para>Figure <xref endterm="fig.tour-basic.history.caption"
  11.253 +        linkend="fig.tour-basic.history"/> provides a
  11.254 +      graphical representation of the history of the <filename
  11.255 +	class="directory">hello</filename> repository, to make it a
  11.256 +      little easier to see which direction history is
  11.257 +      <quote>flowing</quote> in.  We'll be returning to this figure
  11.258 +      several times in this chapter and the chapter that
  11.259 +      follows.</para>
  11.260 +
  11.261 +    <informalfigure id="fig.tour-basic.history">
  11.262 +      <mediaobject>
  11.263 +	<imageobject><imagedata fileref="images/tour-history.png"/></imageobject>
  11.264 +	<textobject><phrase>XXX add text</phrase></textobject>
  11.265 +	<caption><para id="fig.tour-basic.history.caption">Graphical history of
  11.266 +	    the <filename class="directory">hello</filename> repository</para>
  11.267 +	</caption>
  11.268 +      </mediaobject>
  11.269 +    </informalfigure>
  11.270 +
  11.271 +    <sect2>
  11.272 +      <title>Changesets, revisions, and talking to other
  11.273 +	people</title>
  11.274 +
  11.275 +      <para>As English is a notoriously sloppy language, and computer
  11.276 +	science has a hallowed history of terminological confusion
  11.277 +	(why use one term when four will do?), revision control has a
  11.278 +	variety of words and phrases that mean the same thing.  If you
  11.279 +	are talking about Mercurial history with other people, you
  11.280 +	will find that the word <quote>changeset</quote> is often
  11.281 +	compressed to <quote>change</quote> or (when written)
  11.282 +	<quote>cset</quote>, and sometimes a changeset is referred to
  11.283 +	as a <quote>revision</quote> or a <quote>rev</quote>.</para>
  11.284 +
  11.285 +      <para>While it doesn't matter what <emphasis>word</emphasis> you
  11.286 +	use to refer to the concept of <quote>a changeset</quote>, the
  11.287 +	<emphasis>identifier</emphasis> that you use to refer to
  11.288 +	<quote>a <emphasis>specific</emphasis> changeset</quote> is of
  11.289 +	great importance. Recall that the <literal>changeset</literal>
  11.290 +	field in the output from <command role="hg-cmd">hg
  11.291 +	  log</command> identifies a changeset using both a number and
  11.292 +	a hexadecimal string.</para>
  11.293 +      <itemizedlist>
  11.294 +	<listitem><para>The revision number is <emphasis>only valid in
  11.295 +	      that repository</emphasis>,</para></listitem>
  11.296 +	<listitem><para>while the hex string is the
  11.297 +	    <emphasis>permanent, unchanging identifier</emphasis> that
  11.298 +	    will always identify that exact changeset in
  11.299 +	    <emphasis>every</emphasis> copy of the
  11.300 +	    repository.</para></listitem></itemizedlist>
  11.301 +      <para>This distinction is important.  If you send someone an
  11.302 +	email talking about <quote>revision 33</quote>, there's a high
  11.303 +	likelihood that their revision 33 will <emphasis>not be the
  11.304 +	  same</emphasis> as yours.  The reason for this is that a
  11.305 +	revision number depends on the order in which changes arrived
  11.306 +	in a repository, and there is no guarantee that the same
  11.307 +	changes will happen in the same order in different
  11.308 +	repositories. Three changes $a,b,c$ can easily appear in one
  11.309 +	repository as $0,1,2$, while in another as $1,0,2$.</para>
  11.310 +
  11.311 +      <para>Mercurial uses revision numbers purely as a convenient
  11.312 +	shorthand.  If you need to discuss a changeset with someone,
  11.313 +	or make a record of a changeset for some other reason (for
  11.314 +	example, in a bug report), use the hexadecimal
  11.315 +	identifier.</para>
  11.316 +
  11.317 +    </sect2>
  11.318 +    <sect2>
  11.319 +      <title>Viewing specific revisions</title>
  11.320 +
  11.321 +      <para>To narrow the output of <command role="hg-cmd">hg
  11.322 +	  log</command> down to a single revision, use the <option
  11.323 +	  role="hg-opt-log">-r</option> (or <option
  11.324 +	  role="hg-opt-log">--rev</option>) option.  You can use
  11.325 +	either a revision number or a long-form changeset identifier,
  11.326 +	and you can provide as many revisions as you want.</para>
  11.327 +
  11.328 +      &interaction.tour.log-r;
  11.329 +
  11.330 +      <para>If you want to see the history of several revisions
  11.331 +	without having to list each one, you can use <emphasis>range
  11.332 +	  notation</emphasis>; this lets you express the idea <quote>I
  11.333 +	  want all revisions between <literal>abc</literal> and
  11.334 +	  <literal>def</literal>, inclusive</quote>.</para>
  11.335 +      
  11.336 +	&interaction.tour.log.range;
  11.337 +
  11.338 +      <para>Mercurial also honours the order in which you specify
  11.339 +	revisions, so <command role="hg-cmd">hg log -r 2:4</command>
  11.340 +	prints 2, 3, and 4. while <command role="hg-cmd">hg log -r
  11.341 +	  4:2</command> prints 4, 3, and 2.</para>
  11.342 +
  11.343 +    </sect2>
  11.344 +    <sect2>
  11.345 +      <title>More detailed information</title>
  11.346 +
  11.347 +      <para>While the summary information printed by <command
  11.348 +	  role="hg-cmd">hg log</command> is useful if you already know
  11.349 +	what you're looking for, you may need to see a complete
  11.350 +	description of the change, or a list of the files changed, if
  11.351 +	you're trying to decide whether a changeset is the one you're
  11.352 +	looking for. The <command role="hg-cmd">hg log</command>
  11.353 +	command's <option role="hg-opt-global">-v</option> (or <option
  11.354 +	  role="hg-opt-global">--verbose</option>) option gives you
  11.355 +	this extra detail.</para>
  11.356 +
  11.357 +      &interaction.tour.log-v;
  11.358 +
  11.359 +      <para>If you want to see both the description and content of a
  11.360 +	change, add the <option role="hg-opt-log">-p</option> (or
  11.361 +	<option role="hg-opt-log">--patch</option>) option.  This
  11.362 +	displays the content of a change as a <emphasis>unified
  11.363 +	  diff</emphasis> (if you've never seen a unified diff before,
  11.364 +	see section <xref linkend="sec.mq.patch"/> for an
  11.365 +	overview).</para>
  11.366 +
  11.367 +      &interaction.tour.log-vp;
  11.368 +
  11.369 +    </sect2>
  11.370 +  </sect1>
  11.371 +  <sect1>
  11.372 +    <title>All about command options</title>
  11.373 +
  11.374 +    <para>Let's take a brief break from exploring Mercurial commands
  11.375 +      to discuss a pattern in the way that they work; you may find
  11.376 +      this useful to keep in mind as we continue our tour.</para>
  11.377 +
  11.378 +    <para>Mercurial has a consistent and straightforward approach to
  11.379 +      dealing with the options that you can pass to commands.  It
  11.380 +      follows the conventions for options that are common to modern
  11.381 +      Linux and Unix systems.</para>
  11.382 +    <itemizedlist>
  11.383 +      <listitem><para>Every option has a long name.  For example, as
  11.384 +	  we've already seen, the <command role="hg-cmd">hg
  11.385 +	    log</command> command accepts a <option
  11.386 +	    role="hg-opt-log">--rev</option> option.</para></listitem>
  11.387 +      <listitem><para>Most options have short names, too.  Instead of
  11.388 +	  <option role="hg-opt-log">--rev</option>, we can use <option
  11.389 +	    role="hg-opt-log">-r</option>.  (The reason that some
  11.390 +	  options don't have short names is that the options in
  11.391 +	  question are rarely used.)</para></listitem>
  11.392 +      <listitem><para>Long options start with two dashes (e.g. <option
  11.393 +	    role="hg-opt-log">--rev</option>), while short options
  11.394 +	  start with one (e.g. <option
  11.395 +	    role="hg-opt-log">-r</option>).</para></listitem>
  11.396 +      <listitem><para>Option naming and usage is consistent across
  11.397 +	  commands.  For example, every command that lets you specify
  11.398 +	  a changeset ID or revision number accepts both <option
  11.399 +	    role="hg-opt-log">-r</option> and <option
  11.400 +	    role="hg-opt-log">--rev</option>
  11.401 +	  arguments.</para></listitem></itemizedlist>
  11.402 +    <para>In the examples throughout this book, I use short options
  11.403 +      instead of long.  This just reflects my own preference, so don't
  11.404 +      read anything significant into it.</para>
  11.405 +
  11.406 +    <para>Most commands that print output of some kind will print more
  11.407 +      output when passed a <option role="hg-opt-global">-v</option>
  11.408 +      (or <option role="hg-opt-global">--verbose</option>) option, and
  11.409 +      less when passed <option role="hg-opt-global">-q</option> (or
  11.410 +      <option role="hg-opt-global">--quiet</option>).</para>
  11.411 +
  11.412 +  </sect1>
  11.413 +  <sect1>
  11.414 +    <title>Making and reviewing changes</title>
  11.415 +
  11.416 +    <para>Now that we have a grasp of viewing history in Mercurial,
  11.417 +      let's take a look at making some changes and examining
  11.418 +      them.</para>
  11.419 +
  11.420 +    <para>The first thing we'll do is isolate our experiment in a
  11.421 +      repository of its own.  We use the <command role="hg-cmd">hg
  11.422 +	clone</command> command, but we don't need to clone a copy of
  11.423 +      the remote repository.  Since we already have a copy of it
  11.424 +      locally, we can just clone that instead.  This is much faster
  11.425 +      than cloning over the network, and cloning a local repository
  11.426 +      uses less disk space in most cases, too.</para>
  11.427 +
  11.428 +    &interaction.tour.reclone;
  11.429 +
  11.430 +    <para>As an aside, it's often good practice to keep a
  11.431 +      <quote>pristine</quote> copy of a remote repository around,
  11.432 +      which you can then make temporary clones of to create sandboxes
  11.433 +      for each task you want to work on.  This lets you work on
  11.434 +      multiple tasks in parallel, each isolated from the others until
  11.435 +      it's complete and you're ready to integrate it back.  Because
  11.436 +      local clones are so cheap, there's almost no overhead to cloning
  11.437 +      and destroying repositories whenever you want.</para>
  11.438 +
  11.439 +    <para>In our <filename class="directory">my-hello</filename>
  11.440 +      repository, we have a file <filename>hello.c</filename> that
  11.441 +      contains the classic <quote>hello, world</quote> program. Let's
  11.442 +      use the ancient and venerable <command>sed</command> command to
  11.443 +      edit this file so that it prints a second line of output.  (I'm
  11.444 +      only using <command>sed</command> to do this because it's easy
  11.445 +      to write a scripted example this way.  Since you're not under
  11.446 +      the same constraint, you probably won't want to use
  11.447 +      <command>sed</command>; simply use your preferred text editor to
  11.448 +      do the same thing.)</para>
  11.449 +
  11.450 +    &interaction.tour.sed;
  11.451 +
  11.452 +    <para>Mercurial's <command role="hg-cmd">hg status</command>
  11.453 +      command will tell us what Mercurial knows about the files in the
  11.454 +      repository.</para>
  11.455 +
  11.456 +    &interaction.tour.status;
  11.457 +
  11.458 +    <para>The <command role="hg-cmd">hg status</command> command
  11.459 +      prints no output for some files, but a line starting with
  11.460 +      <quote><literal>M</literal></quote> for
  11.461 +      <filename>hello.c</filename>.  Unless you tell it to, <command
  11.462 +	role="hg-cmd">hg status</command> will not print any output
  11.463 +      for files that have not been modified.</para>
  11.464 +
  11.465 +    <para>The <quote><literal>M</literal></quote> indicates that
  11.466 +      Mercurial has noticed that we modified
  11.467 +      <filename>hello.c</filename>.  We didn't need to
  11.468 +      <emphasis>inform</emphasis> Mercurial that we were going to
  11.469 +      modify the file before we started, or that we had modified the
  11.470 +      file after we were done; it was able to figure this out
  11.471 +      itself.</para>
  11.472 +
  11.473 +    <para>It's a little bit helpful to know that we've modified
  11.474 +      <filename>hello.c</filename>, but we might prefer to know
  11.475 +      exactly <emphasis>what</emphasis> changes we've made to it.  To
  11.476 +      do this, we use the <command role="hg-cmd">hg diff</command>
  11.477 +      command.</para>
  11.478 +
  11.479 +    &interaction.tour.diff;
  11.480 +
  11.481 +  </sect1>
  11.482 +  <sect1>
  11.483 +    <title>Recording changes in a new changeset</title>
  11.484 +
  11.485 +    <para>We can modify files, build and test our changes, and use
  11.486 +      <command role="hg-cmd">hg status</command> and <command
  11.487 +	role="hg-cmd">hg diff</command> to review our changes, until
  11.488 +      we're satisfied with what we've done and arrive at a natural
  11.489 +      stopping point where we want to record our work in a new
  11.490 +      changeset.</para>
  11.491 +
  11.492 +    <para>The <command role="hg-cmd">hg commit</command> command lets
  11.493 +      us create a new changeset; we'll usually refer to this as
  11.494 +      <quote>making a commit</quote> or
  11.495 +      <quote>committing</quote>.</para>
  11.496 +
  11.497 +    <sect2>
  11.498 +      <title>Setting up a username</title>
  11.499 +
  11.500 +      <para>When you try to run <command role="hg-cmd">hg
  11.501 +	  commit</command> for the first time, it is not guaranteed to
  11.502 +	succeed.  Mercurial records your name and address with each
  11.503 +	change that you commit, so that you and others will later be
  11.504 +	able to tell who made each change.  Mercurial tries to
  11.505 +	automatically figure out a sensible username to commit the
  11.506 +	change with.  It will attempt each of the following methods,
  11.507 +	in order:</para>
  11.508 +      <orderedlist>
  11.509 +	<listitem><para>If you specify a <option
  11.510 +	      role="hg-opt-commit">-u</option> option to the <command
  11.511 +	      role="hg-cmd">hg commit</command> command on the command
  11.512 +	    line, followed by a username, this is always given the
  11.513 +	    highest precedence.</para></listitem>
  11.514 +	<listitem><para>If you have set the <envar>HGUSER</envar>
  11.515 +	    environment variable, this is checked
  11.516 +	    next.</para></listitem>
  11.517 +	<listitem><para>If you create a file in your home directory
  11.518 +	    called <filename role="special">.hgrc</filename>, with a
  11.519 +	    <envar role="rc-item-ui">username</envar> entry, that will
  11.520 +	    be used next.  To see what the contents of this file
  11.521 +	    should look like, refer to section <xref
  11.522 +	      linkend="sec.tour-basic.username"/>
  11.523 +	    below.</para></listitem>
  11.524 +	<listitem><para>If you have set the <envar>EMAIL</envar>
  11.525 +	    environment variable, this will be used
  11.526 +	    next.</para></listitem>
  11.527 +	<listitem><para>Mercurial will query your system to find out
  11.528 +	    your local user name and host name, and construct a
  11.529 +	    username from these components. Since this often results
  11.530 +	    in a username that is not very useful, it will print a
  11.531 +	    warning if it has to do
  11.532 +	    this.</para></listitem>
  11.533 +      </orderedlist>
  11.534 +      <para>If all of these mechanisms fail, Mercurial will
  11.535 +	  fail, printing an error message.  In this case, it will not
  11.536 +	  let you commit until you set up a
  11.537 +	  username.</para>
  11.538 +      <para>You should think of the <envar>HGUSER</envar> environment
  11.539 +	variable and the <option role="hg-opt-commit">-u</option>
  11.540 +	option to the <command role="hg-cmd">hg commit</command>
  11.541 +	command as ways to <emphasis>override</emphasis> Mercurial's
  11.542 +	default selection of username.  For normal use, the simplest
  11.543 +	and most robust way to set a username for yourself is by
  11.544 +	creating a <filename role="special">.hgrc</filename> file; see
  11.545 +	below for details.</para>
  11.546 +      <sect3 id="sec.tour-basic.username">
  11.547 +	<title>Creating a Mercurial configuration file</title>
  11.548 +
  11.549 +	<para>To set a user name, use your favourite editor
  11.550 +	    to create a file called <filename
  11.551 +	      role="special">.hgrc</filename> in your home directory.
  11.552 +	    Mercurial will use this file to look up your personalised
  11.553 +	    configuration settings.  The initial contents of your
  11.554 +	    <filename role="special">.hgrc</filename> should look like
  11.555 +	    this.</para>
  11.556 +	<programlisting># This is a Mercurial configuration file.
  11.557 +[ui]
  11.558 +username = Firstname Lastname
  11.559 +&lt;email.address@domain.net&gt;</programlisting>
  11.560 +
  11.561 +	<para>The <quote><literal>[ui]</literal></quote> line begins a
  11.562 +	  <emphasis>section</emphasis> of the config file, so you can
  11.563 +	  read the <quote><literal>username = ...</literal></quote>
  11.564 +	  line as meaning <quote>set the value of the
  11.565 +	    <literal>username</literal> item in the
  11.566 +	    <literal>ui</literal> section</quote>. A section continues
  11.567 +	  until a new section begins, or the end of the file.
  11.568 +	  Mercurial ignores empty lines and treats any text from
  11.569 +	  <quote><literal>#</literal></quote> to the end of a line as
  11.570 +	  a comment.</para>
  11.571 +      </sect3>
  11.572 +
  11.573 +      <sect3>
  11.574 +	<title>Choosing a user name</title>
  11.575 +
  11.576 +	<para>You can use any text you like as the value of
  11.577 +	    the <literal>username</literal> config item, since this
  11.578 +	    information is for reading by other people, but for
  11.579 +	    interpreting by Mercurial.  The convention that most
  11.580 +	    people follow is to use their name and email address, as
  11.581 +	    in the example above.</para>
  11.582 +	<note>
  11.583 +	  <para>Mercurial's built-in web server obfuscates
  11.584 +	      email addresses, to make it more difficult for the email
  11.585 +	      harvesting tools that spammers use. This reduces the
  11.586 +	      likelihood that you'll start receiving more junk email
  11.587 +	      if you publish a Mercurial repository on the
  11.588 +	      web.</para></note>
  11.589 +
  11.590 +      </sect3>
  11.591 +    </sect2>
  11.592 +    <sect2>
  11.593 +      <title>Writing a commit message</title>
  11.594 +
  11.595 +      <para>When we commit a change, Mercurial drops us into
  11.596 +	  a text editor, to enter a message that will describe the
  11.597 +	  modifications we've made in this changeset.  This is called
  11.598 +	  the <emphasis>commit message</emphasis>.  It will be a
  11.599 +	  record for readers of what we did and why, and it will be
  11.600 +	  printed by <command role="hg-cmd">hg log</command> after
  11.601 +	  we've finished committing.</para>
  11.602 +
  11.603 +       &interaction.tour.commit;
  11.604 +
  11.605 +      <para>The editor that the <command role="hg-cmd">hg
  11.606 +	    commit</command> command drops us into will contain an
  11.607 +	  empty line, followed by a number of lines starting with
  11.608 +	  <quote><literal>HG:</literal></quote>.</para>
  11.609 +
  11.610 +    <programlisting>XXX fix this XXX</programlisting>
  11.611 +
  11.612 +      <para>Mercurial ignores the lines that start with
  11.613 +	  <quote><literal>HG:</literal></quote>; it uses them only to
  11.614 +	  tell us which files it's recording changes to.  Modifying or
  11.615 +	  deleting these lines has no effect.</para>
  11.616 +    </sect2>
  11.617 +    <sect2>
  11.618 +      <title>Writing a good commit message</title>
  11.619 +
  11.620 +      <para>Since <command role="hg-cmd">hg log</command>
  11.621 +	  only prints the first line of a commit message by default,
  11.622 +	  it's best to write a commit message whose first line stands
  11.623 +	  alone.  Here's a real example of a commit message that
  11.624 +	  <emphasis>doesn't</emphasis> follow this guideline, and
  11.625 +	  hence has a summary that is not
  11.626 +	  readable.</para>
  11.627 +
  11.628 +      <programlisting>
  11.629 +changeset:   73:584af0e231be
  11.630 +user:        Censored Person &lt;censored.person@example.org&gt;
  11.631 +date:        Tue Sep 26 21:37:07 2006 -0700
  11.632 +summary:     include buildmeister/commondefs. Add exports.</programlisting>
  11.633 +
  11.634 +      <para>As far as the remainder of the contents of the
  11.635 +	  commit message are concerned, there are no hard-and-fast
  11.636 +	  rules.  Mercurial itself doesn't interpret or care about the
  11.637 +	  contents of the commit message, though your project may have
  11.638 +	  policies that dictate a certain kind of
  11.639 +	  formatting.</para>
  11.640 +      <para>My personal preference is for short, but
  11.641 +	  informative, commit messages that tell me something that I
  11.642 +	  can't figure out with a quick glance at the output of
  11.643 +	  <command role="hg-cmd">hg log
  11.644 +	    --patch</command>.</para>
  11.645 +    </sect2>
  11.646 +    <sect2>
  11.647 +      <title>Aborting a commit</title>
  11.648 +
  11.649 +      <para>If you decide that you don't want to commit
  11.650 +	  while in the middle of editing a commit message, simply exit
  11.651 +	  from your editor without saving the file that it's editing.
  11.652 +	  This will cause nothing to happen to either the repository
  11.653 +	  or the working directory.</para>
  11.654 +      <para>If we run the <command role="hg-cmd">hg
  11.655 +	    commit</command> command without any arguments, it records
  11.656 +	  all of the changes we've made, as reported by <command
  11.657 +	    role="hg-cmd">hg status</command> and <command
  11.658 +	    role="hg-cmd">hg diff</command>.</para>
  11.659 +    </sect2>
  11.660 +    <sect2>
  11.661 +      <title>Admiring our new handiwork</title>
  11.662 +
  11.663 +      <para>Once we've finished the commit, we can use the
  11.664 +	  <command role="hg-cmd">hg tip</command> command to display
  11.665 +	  the changeset we just created.  This command produces output
  11.666 +	  that is identical to <command role="hg-cmd">hg
  11.667 +	    log</command>, but it only displays the newest revision in
  11.668 +	  the repository.</para>
  11.669 +
  11.670 +      &interaction.tour.tip;
  11.671 +
  11.672 +      <para>We refer to
  11.673 +	  the newest revision in the repository as the tip revision,
  11.674 +	  or simply the tip.</para>
  11.675 +    </sect2>
  11.676 +  </sect1>
  11.677 +
  11.678 +  <sect1>
  11.679 +    <title>Sharing changes</title>
  11.680 +
  11.681 +    <para>We mentioned earlier that repositories in
  11.682 +	Mercurial are self-contained.  This means that the changeset
  11.683 +	we just created exists only in our <filename
  11.684 +	  class="directory">my-hello</filename> repository.  Let's
  11.685 +	look at a few ways that we can propagate this change into
  11.686 +	other repositories.</para>
  11.687 +
  11.688 +    <sect2 id="sec.tour.pull">
  11.689 +      <title>Pulling changes from another repository</title>
  11.690 +      <para>To get started, let's clone our original
  11.691 +	  <filename class="directory">hello</filename> repository,
  11.692 +	  which does not contain the change we just committed.  We'll
  11.693 +	  call our temporary repository <filename
  11.694 +	    class="directory">hello-pull</filename>.</para>
  11.695 +
  11.696 +      &interaction.tour.clone-pull;
  11.697 +
  11.698 +      <para>We'll use the <command role="hg-cmd">hg
  11.699 +	    pull</command> command to bring changes from <filename
  11.700 +	    class="directory">my-hello</filename> into <filename
  11.701 +	    class="directory">hello-pull</filename>.  However, blindly
  11.702 +	  pulling unknown changes into a repository is a somewhat
  11.703 +	  scary prospect.  Mercurial provides the <command
  11.704 +	    role="hg-cmd">hg incoming</command> command to tell us
  11.705 +	  what changes the <command role="hg-cmd">hg pull</command>
  11.706 +	  command <emphasis>would</emphasis> pull into the repository,
  11.707 +	  without actually pulling the changes in.</para>
  11.708 +
  11.709 +      &interaction.tour.incoming;
  11.710 +
  11.711 +      <para>(Of course, someone could
  11.712 +	  cause more changesets to appear in the repository that we
  11.713 +	  ran <command role="hg-cmd">hg incoming</command> in, before
  11.714 +	  we get a chance to <command role="hg-cmd">hg pull</command>
  11.715 +	  the changes, so that we could end up pulling changes that we
  11.716 +	  didn't expect.)</para>
  11.717 +
  11.718 +      <para>Bringing changes into a repository is a simple
  11.719 +	  matter of running the <command role="hg-cmd">hg
  11.720 +	    pull</command> command, and telling it which repository to
  11.721 +	  pull from.</para>
  11.722 +
  11.723 +      &interaction.tour.pull;
  11.724 +
  11.725 +      <para>As you can see
  11.726 +	  from the before-and-after output of <command
  11.727 +	    role="hg-cmd">hg tip</command>, we have successfully
  11.728 +	  pulled changes into our repository.  There remains one step
  11.729 +	  before we can see these changes in the working
  11.730 +	  directory.</para>
  11.731 +    </sect2>
  11.732 +    <sect2>
  11.733 +      <title>Updating the working directory</title>
  11.734 +
  11.735 +      <para>We have so far glossed over the relationship between a
  11.736 +	repository and its working directory.  The <command
  11.737 +	  role="hg-cmd">hg pull</command> command that we ran in
  11.738 +	section <xref linkend="sec.tour.pull"/> brought changes
  11.739 +	into the repository, but if we check, there's no sign of those
  11.740 +	changes in the working directory.  This is because <command
  11.741 +	  role="hg-cmd">hg pull</command> does not (by default) touch
  11.742 +	the working directory.  Instead, we use the <command
  11.743 +	  role="hg-cmd">hg update</command> command to do this.</para>
  11.744 +
  11.745 +      &interaction.tour.update;
  11.746 +
  11.747 +      <para>It might seem a bit strange that <command role="hg-cmd">hg
  11.748 +	  pull</command> doesn't update the working directory
  11.749 +	automatically.  There's actually a good reason for this: you
  11.750 +	can use <command role="hg-cmd">hg update</command> to update
  11.751 +	the working directory to the state it was in at <emphasis>any
  11.752 +	  revision</emphasis> in the history of the repository.  If
  11.753 +	you had the working directory updated to an old revision---to
  11.754 +	hunt down the origin of a bug, say---and ran a <command
  11.755 +	  role="hg-cmd">hg pull</command> which automatically updated
  11.756 +	the working directory to a new revision, you might not be
  11.757 +	terribly happy.</para>
  11.758 +      <para>However, since pull-then-update is such a common thing to
  11.759 +	do, Mercurial lets you combine the two by passing the <option
  11.760 +	  role="hg-opt-pull">-u</option> option to <command
  11.761 +	  role="hg-cmd">hg pull</command>.</para>
  11.762 +
  11.763 +      <para>If you look back at the output of <command
  11.764 +	  role="hg-cmd">hg pull</command> in section <xref
  11.765 +	    linkend="sec.tour.pull"/> when we ran it without <option
  11.766 +	  role="hg-opt-pull">-u</option>, you can see that it printed
  11.767 +	a helpful reminder that we'd have to take an explicit step to
  11.768 +	update the working directory:</para>
  11.769 +
  11.770 +      <!-- &interaction.xxx.fixme; -->
  11.771 +
  11.772 +      <para>To find out what revision the working directory is at, use
  11.773 +	the <command role="hg-cmd">hg parents</command>
  11.774 +	command.</para>
  11.775 +
  11.776 +      &interaction.tour.parents;
  11.777 +
  11.778 +      <para>If you look back at figure <xref
  11.779 +	   endterm="fig.tour-basic.history.caption" 
  11.780 +	   linkend="fig.tour-basic.history"/>,
  11.781 +	you'll see arrows connecting each changeset.  The node that
  11.782 +	the arrow leads <emphasis>from</emphasis> in each case is a
  11.783 +	parent, and the node that the arrow leads
  11.784 +	<emphasis>to</emphasis> is its child.  The working directory
  11.785 +	has a parent in just the same way; this is the changeset that
  11.786 +	the working directory currently contains.</para>
  11.787 +
  11.788 +      <para>To update the working directory to a particular revision,
  11.789 +
  11.790 +	give a revision number or changeset ID to the <command
  11.791 +	  role="hg-cmd">hg update</command> command.</para>
  11.792 +
  11.793 +      &interaction.tour.older;
  11.794 +
  11.795 +      <para>If you omit an explicit revision, <command
  11.796 +	  role="hg-cmd">hg update</command> will update to the tip
  11.797 +	revision, as shown by the second call to <command
  11.798 +	  role="hg-cmd">hg update</command> in the example
  11.799 +	above.</para>
  11.800 +    </sect2>
  11.801 +
  11.802 +    <sect2>
  11.803 +      <title>Pushing changes to another repository</title>
  11.804 +
  11.805 +      <para>Mercurial lets us push changes to another
  11.806 +	  repository, from the repository we're currently visiting.
  11.807 +	  As with the example of <command role="hg-cmd">hg
  11.808 +	    pull</command> above, we'll create a temporary repository
  11.809 +	  to push our changes into.</para>
  11.810 +
  11.811 +      &interaction.tour.clone-push;
  11.812 +
  11.813 +      <para>The <command role="hg-cmd">hg outgoing</command> command
  11.814 +	  tells us what changes would be pushed into another
  11.815 +	  repository.</para>
  11.816 +
  11.817 +      &interaction.tour.outgoing;
  11.818 +
  11.819 +      <para>And the
  11.820 +	  <command role="hg-cmd">hg push</command> command does the
  11.821 +	  actual push.</para>
  11.822 +
  11.823 +      &interaction.tour.push;
  11.824 +
  11.825 +      <para>As with
  11.826 +	  <command role="hg-cmd">hg pull</command>, the <command
  11.827 +	    role="hg-cmd">hg push</command> command does not update
  11.828 +	  the working directory in the repository that it's pushing
  11.829 +	  changes into. (Unlike <command role="hg-cmd">hg
  11.830 +	    pull</command>, <command role="hg-cmd">hg push</command>
  11.831 +	  does not provide a <literal>-u</literal> option that updates
  11.832 +	  the other repository's working directory.)</para>
  11.833 +
  11.834 +      <para>What happens if we try to pull or push changes
  11.835 +	  and the receiving repository already has those changes?
  11.836 +	  Nothing too exciting.</para>
  11.837 +
  11.838 +      &interaction.tour.push.nothing;
  11.839 +    </sect2>
  11.840 +    <sect2>
  11.841 +      <title>Sharing changes over a network</title>
  11.842 +
  11.843 +      <para>The commands we have covered in the previous few
  11.844 +	  sections are not limited to working with local repositories.
  11.845 +	  Each works in exactly the same fashion over a network
  11.846 +	  connection; simply pass in a URL instead of a local
  11.847 +	  path.</para>
  11.848 +	
  11.849 +      &interaction.tour.outgoing.net;
  11.850 +
  11.851 +      <para>In this example, we
  11.852 +	  can see what changes we could push to the remote repository,
  11.853 +	  but the repository is understandably not set up to let
  11.854 +	  anonymous users push to it.</para>
  11.855 +
  11.856 +      &interaction.tour.push.net;
  11.857 +    </sect2>
  11.858 +  </sect1>
  11.859 +</chapter>
  11.860 +
  11.861 +<!--
  11.862 +local variables: 
  11.863 +sgml-parent-document: ("00book.xml" "book" "chapter")
  11.864 +end:
  11.865 +-->
    12.1 --- a/en/ch02-tour-basic.xml	Fri Mar 20 15:40:06 2009 +0800
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,862 +0,0 @@
    12.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    12.5 -
    12.6 -<chapter id="chap.tour-basic">
    12.7 -  <?dbhtml filename="a-tour-of-mercurial-the-basics.html"?>
    12.8 -  <title>A tour of Mercurial: the basics</title>
    12.9 -
   12.10 -  <sect1 id="sec.tour.install">
   12.11 -    <title>Installing Mercurial on your system</title>
   12.12 -
   12.13 -    <para>Prebuilt binary packages of Mercurial are available for
   12.14 -      every popular operating system.  These make it easy to start
   12.15 -      using Mercurial on your computer immediately.</para>
   12.16 -
   12.17 -    <sect2>
   12.18 -      <title>Linux</title>
   12.19 -
   12.20 -      <para>Because each Linux distribution has its own packaging
   12.21 -	tools, policies, and rate of development, it's difficult to
   12.22 -	give a comprehensive set of instructions on how to install
   12.23 -	Mercurial binaries.  The version of Mercurial that you will
   12.24 -	end up with can vary depending on how active the person is who
   12.25 -	maintains the package for your distribution.</para>
   12.26 -
   12.27 -      <para>To keep things simple, I will focus on installing
   12.28 -	Mercurial from the command line under the most popular Linux
   12.29 -	distributions.  Most of these distributions provide graphical
   12.30 -	package managers that will let you install Mercurial with a
   12.31 -	single click; the package name to look for is
   12.32 -	<literal>mercurial</literal>.</para>
   12.33 -
   12.34 -      <itemizedlist>
   12.35 -	<listitem><para>Debian:</para>
   12.36 -	  <programlisting>apt-get install mercurial</programlisting></listitem>
   12.37 -	<listitem><para>Fedora Core:</para>
   12.38 -	  <programlisting>yum install mercurial</programlisting></listitem>
   12.39 -	<listitem><para>Gentoo:</para>
   12.40 -	  <programlisting>emerge mercurial</programlisting></listitem>
   12.41 -	<listitem><para>OpenSUSE:</para>
   12.42 -	  <programlisting>yum install mercurial</programlisting></listitem>
   12.43 -	<listitem><para>Ubuntu: Ubuntu's Mercurial package is based on
   12.44 -	    Debian's.  To install it, run the following
   12.45 -	    command.</para>
   12.46 -	  <programlisting>apt-get install mercurial</programlisting></listitem>
   12.47 -      </itemizedlist>
   12.48 -
   12.49 -    </sect2>
   12.50 -    <sect2>
   12.51 -      <title>Solaris</title>
   12.52 -
   12.53 -      <para>SunFreeWare, at <ulink
   12.54 -	  url="http://www.sunfreeware.com">http://www.sunfreeware.com</ulink>, 
   12.55 -	is a good source for a large number of pre-built Solaris
   12.56 -	packages for 32 and 64 bit Intel and Sparc architectures,
   12.57 -	including current versions of Mercurial.</para>
   12.58 -
   12.59 -    </sect2>
   12.60 -    <sect2>
   12.61 -      <title>Mac OS X</title>
   12.62 -
   12.63 -      <para>Lee Cantey publishes an installer of Mercurial for Mac OS
   12.64 -	X at <ulink
   12.65 -	  url="http://mercurial.berkwood.com">http://mercurial.berkwood.com</ulink>. 
   12.66 -	This package works on both Intel- and Power-based Macs. Before
   12.67 -	you can use it, you must install a compatible version of
   12.68 -	Universal MacPython <citation>web:macpython</citation>. This
   12.69 -	is easy to do; simply follow the instructions on Lee's
   12.70 -	site.</para>
   12.71 -
   12.72 -      <para>It's also possible to install Mercurial using Fink or
   12.73 -	MacPorts, two popular free package managers for Mac OS X.  If
   12.74 -	you have Fink, use <command>sudo apt-get install
   12.75 -	  mercurial-py25</command>.  If MacPorts, <command>sudo port
   12.76 -	  install mercurial</command>.</para>
   12.77 -
   12.78 -    </sect2>
   12.79 -    <sect2>
   12.80 -      <title>Windows</title>
   12.81 -
   12.82 -      <para>Lee Cantey publishes an installer of Mercurial for Windows
   12.83 -	at <ulink
   12.84 -	  url="http://mercurial.berkwood.com">http://mercurial.berkwood.com</ulink>. 
   12.85 -	This package has no external dependencies; it <quote>just
   12.86 -	  works</quote>.</para>
   12.87 -
   12.88 -      <note>
   12.89 -	<para>  The Windows version of Mercurial does not
   12.90 -	  automatically convert line endings between Windows and Unix
   12.91 -	  styles.  If you want to share work with Unix users, you must
   12.92 -	  do a little additional configuration work. XXX Flesh this
   12.93 -	  out.</para>
   12.94 -      </note>
   12.95 -
   12.96 -    </sect2>
   12.97 -  </sect1>
   12.98 -  <sect1>
   12.99 -    <title>Getting started</title>
  12.100 -
  12.101 -    <para>To begin, we'll use the <command role="hg-cmd">hg
  12.102 -	version</command> command to find out whether Mercurial is
  12.103 -      actually installed properly.  The actual version information
  12.104 -      that it prints isn't so important; it's whether it prints
  12.105 -      anything at all that we care about.</para>
  12.106 -
  12.107 -    &interaction.tour.version;
  12.108 -
  12.109 -    <sect2>
  12.110 -      <title>Built-in help</title>
  12.111 -
  12.112 -      <para>Mercurial provides a built-in help system.  This is
  12.113 -	  invaluable for those times when you find yourself stuck
  12.114 -	  trying to remember how to run a command.  If you are
  12.115 -	  completely stuck, simply run <command role="hg-cmd">hg
  12.116 -	    help</command>; it will print a brief list of commands,
  12.117 -	  along with a description of what each does.  If you ask for
  12.118 -	  help on a specific command (as below), it prints more
  12.119 -	  detailed information.</para>
  12.120 -
  12.121 -	&interaction.tour.help;
  12.122 -
  12.123 -	<para>For a more impressive level of detail (which you won't
  12.124 -	  usually need) run <command role="hg-cmd">hg help <option
  12.125 -	      role="hg-opt-global">-v</option></command>.  The <option
  12.126 -	    role="hg-opt-global">-v</option> option is short for
  12.127 -	  <option role="hg-opt-global">--verbose</option>, and tells
  12.128 -	  Mercurial to print more information than it usually
  12.129 -	  would.</para>
  12.130 -
  12.131 -    </sect2>
  12.132 -  </sect1>
  12.133 -  <sect1>
  12.134 -    <title>Working with a repository</title>
  12.135 -
  12.136 -    <para>In Mercurial, everything happens inside a
  12.137 -      <emphasis>repository</emphasis>.  The repository for a project
  12.138 -      contains all of the files that <quote>belong to</quote> that
  12.139 -      project, along with a historical record of the project's
  12.140 -      files.</para>
  12.141 -
  12.142 -    <para>There's nothing particularly magical about a repository; it
  12.143 -      is simply a directory tree in your filesystem that Mercurial
  12.144 -      treats as special. You can rename or delete a repository any
  12.145 -      time you like, using either the command line or your file
  12.146 -      browser.</para>
  12.147 -
  12.148 -    <sect2>
  12.149 -      <title>Making a local copy of a repository</title>
  12.150 -
  12.151 -      <para><emphasis>Copying</emphasis> a repository is just a little
  12.152 -	bit special.  While you could use a normal file copying
  12.153 -	command to make a copy of a repository, it's best to use a
  12.154 -	built-in command that Mercurial provides.  This command is
  12.155 -	called <command role="hg-cmd">hg clone</command>, because it
  12.156 -	creates an identical copy of an existing repository.</para>
  12.157 -
  12.158 -      &interaction.tour.clone;
  12.159 -
  12.160 -      <para>If our clone succeeded, we should now have a local
  12.161 -	directory called <filename class="directory">hello</filename>.
  12.162 -	This directory will contain some files.</para>
  12.163 -
  12.164 -      &interaction.tour.ls;
  12.165 -
  12.166 -      <para>These files have the same contents and history in our
  12.167 -	repository as they do in the repository we cloned.</para>
  12.168 -
  12.169 -      <para>Every Mercurial repository is complete, self-contained,
  12.170 -	and independent.  It contains its own private copy of a
  12.171 -	project's files and history.  A cloned repository remembers
  12.172 -	the location of the repository it was cloned from, but it does
  12.173 -	not communicate with that repository, or any other, unless you
  12.174 -	tell it to.</para>
  12.175 -
  12.176 -      <para>What this means for now is that we're free to experiment
  12.177 -	with our repository, safe in the knowledge that it's a private
  12.178 -	<quote>sandbox</quote> that won't affect anyone else.</para>
  12.179 -
  12.180 -    </sect2>
  12.181 -    <sect2>
  12.182 -      <title>What's in a repository?</title>
  12.183 -
  12.184 -      <para>When we take a more detailed look inside a repository, we
  12.185 -	can see that it contains a directory named <filename
  12.186 -	  class="directory">.hg</filename>.  This is where Mercurial
  12.187 -	keeps all of its metadata for the repository.</para>
  12.188 -
  12.189 -      &interaction.tour.ls-a;
  12.190 -
  12.191 -      <para>The contents of the <filename
  12.192 -	  class="directory">.hg</filename> directory and its
  12.193 -	subdirectories are private to Mercurial.  Every other file and
  12.194 -	directory in the repository is yours to do with as you
  12.195 -	please.</para>
  12.196 -
  12.197 -      <para>To introduce a little terminology, the <filename
  12.198 -	  class="directory">.hg</filename> directory is the
  12.199 -	<quote>real</quote> repository, and all of the files and
  12.200 -	directories that coexist with it are said to live in the
  12.201 -	<emphasis>working directory</emphasis>.  An easy way to
  12.202 -	remember the distinction is that the
  12.203 -	<emphasis>repository</emphasis> contains the
  12.204 -	<emphasis>history</emphasis> of your project, while the
  12.205 -	<emphasis>working directory</emphasis> contains a
  12.206 -	<emphasis>snapshot</emphasis> of your project at a particular
  12.207 -	point in history.</para>
  12.208 -
  12.209 -    </sect2>
  12.210 -  </sect1>
  12.211 -  <sect1>
  12.212 -    <title>A tour through history</title>
  12.213 -
  12.214 -    <para>One of the first things we might want to do with a new,
  12.215 -      unfamiliar repository is understand its history.  The <command
  12.216 -	role="hg-cmd">hg log</command> command gives us a view of
  12.217 -      history.</para>
  12.218 -
  12.219 -    &interaction.tour.log;
  12.220 -
  12.221 -    <para>By default, this command prints a brief paragraph of output
  12.222 -      for each change to the project that was recorded.  In Mercurial
  12.223 -      terminology, we call each of these recorded events a
  12.224 -      <emphasis>changeset</emphasis>, because it can contain a record
  12.225 -      of changes to several files.</para>
  12.226 -
  12.227 -    <para>The fields in a record of output from <command
  12.228 -	role="hg-cmd">hg log</command> are as follows.</para>
  12.229 -    <itemizedlist>
  12.230 -      <listitem><para><literal>changeset</literal>: This field has the
  12.231 -	  format of a number, followed by a colon, followed by a
  12.232 -	  hexadecimal string.  These are
  12.233 -	  <emphasis>identifiers</emphasis> for the changeset.  There
  12.234 -	  are two identifiers because the number is shorter and easier
  12.235 -	  to type than the hex string.</para></listitem>
  12.236 -      <listitem><para><literal>user</literal>: The identity of the
  12.237 -	  person who created the changeset.  This is a free-form
  12.238 -	  field, but it most often contains a person's name and email
  12.239 -	  address.</para></listitem>
  12.240 -      <listitem><para><literal>date</literal>: The date and time on
  12.241 -	  which the changeset was created, and the timezone in which
  12.242 -	  it was created.  (The date and time are local to that
  12.243 -	  timezone; they display what time and date it was for the
  12.244 -	  person who created the changeset.)</para></listitem>
  12.245 -      <listitem><para><literal>summary</literal>: The first line of
  12.246 -	  the text message that the creator of the changeset entered
  12.247 -	  to describe the changeset.</para></listitem></itemizedlist>
  12.248 -    <para>The default output printed by <command role="hg-cmd">hg
  12.249 -	log</command> is purely a summary; it is missing a lot of
  12.250 -      detail.</para>
  12.251 -
  12.252 -    <para>Figure <xref endterm="fig.tour-basic.history.caption"
  12.253 -        linkend="fig.tour-basic.history"/> provides a
  12.254 -      graphical representation of the history of the <filename
  12.255 -	class="directory">hello</filename> repository, to make it a
  12.256 -      little easier to see which direction history is
  12.257 -      <quote>flowing</quote> in.  We'll be returning to this figure
  12.258 -      several times in this chapter and the chapter that
  12.259 -      follows.</para>
  12.260 -
  12.261 -    <informalfigure id="fig.tour-basic.history">
  12.262 -      <mediaobject>
  12.263 -	<imageobject><imagedata fileref="images/tour-history.png"/></imageobject>
  12.264 -	<textobject><phrase>XXX add text</phrase></textobject>
  12.265 -	<caption><para id="fig.tour-basic.history.caption">Graphical history of
  12.266 -	    the <filename class="directory">hello</filename> repository</para>
  12.267 -	</caption>
  12.268 -      </mediaobject>
  12.269 -    </informalfigure>
  12.270 -
  12.271 -    <sect2>
  12.272 -      <title>Changesets, revisions, and talking to other
  12.273 -	people</title>
  12.274 -
  12.275 -      <para>As English is a notoriously sloppy language, and computer
  12.276 -	science has a hallowed history of terminological confusion
  12.277 -	(why use one term when four will do?), revision control has a
  12.278 -	variety of words and phrases that mean the same thing.  If you
  12.279 -	are talking about Mercurial history with other people, you
  12.280 -	will find that the word <quote>changeset</quote> is often
  12.281 -	compressed to <quote>change</quote> or (when written)
  12.282 -	<quote>cset</quote>, and sometimes a changeset is referred to
  12.283 -	as a <quote>revision</quote> or a <quote>rev</quote>.</para>
  12.284 -
  12.285 -      <para>While it doesn't matter what <emphasis>word</emphasis> you
  12.286 -	use to refer to the concept of <quote>a changeset</quote>, the
  12.287 -	<emphasis>identifier</emphasis> that you use to refer to
  12.288 -	<quote>a <emphasis>specific</emphasis> changeset</quote> is of
  12.289 -	great importance. Recall that the <literal>changeset</literal>
  12.290 -	field in the output from <command role="hg-cmd">hg
  12.291 -	  log</command> identifies a changeset using both a number and
  12.292 -	a hexadecimal string.</para>
  12.293 -      <itemizedlist>
  12.294 -	<listitem><para>The revision number is <emphasis>only valid in
  12.295 -	      that repository</emphasis>,</para></listitem>
  12.296 -	<listitem><para>while the hex string is the
  12.297 -	    <emphasis>permanent, unchanging identifier</emphasis> that
  12.298 -	    will always identify that exact changeset in
  12.299 -	    <emphasis>every</emphasis> copy of the
  12.300 -	    repository.</para></listitem></itemizedlist>
  12.301 -      <para>This distinction is important.  If you send someone an
  12.302 -	email talking about <quote>revision 33</quote>, there's a high
  12.303 -	likelihood that their revision 33 will <emphasis>not be the
  12.304 -	  same</emphasis> as yours.  The reason for this is that a
  12.305 -	revision number depends on the order in which changes arrived
  12.306 -	in a repository, and there is no guarantee that the same
  12.307 -	changes will happen in the same order in different
  12.308 -	repositories. Three changes $a,b,c$ can easily appear in one
  12.309 -	repository as $0,1,2$, while in another as $1,0,2$.</para>
  12.310 -
  12.311 -      <para>Mercurial uses revision numbers purely as a convenient
  12.312 -	shorthand.  If you need to discuss a changeset with someone,
  12.313 -	or make a record of a changeset for some other reason (for
  12.314 -	example, in a bug report), use the hexadecimal
  12.315 -	identifier.</para>
  12.316 -
  12.317 -    </sect2>
  12.318 -    <sect2>
  12.319 -      <title>Viewing specific revisions</title>
  12.320 -
  12.321 -      <para>To narrow the output of <command role="hg-cmd">hg
  12.322 -	  log</command> down to a single revision, use the <option
  12.323 -	  role="hg-opt-log">-r</option> (or <option
  12.324 -	  role="hg-opt-log">--rev</option>) option.  You can use
  12.325 -	either a revision number or a long-form changeset identifier,
  12.326 -	and you can provide as many revisions as you want.</para>
  12.327 -
  12.328 -      &interaction.tour.log-r;
  12.329 -
  12.330 -      <para>If you want to see the history of several revisions
  12.331 -	without having to list each one, you can use <emphasis>range
  12.332 -	  notation</emphasis>; this lets you express the idea <quote>I
  12.333 -	  want all revisions between <literal>abc</literal> and
  12.334 -	  <literal>def</literal>, inclusive</quote>.</para>
  12.335 -      
  12.336 -	&interaction.tour.log.range;
  12.337 -
  12.338 -      <para>Mercurial also honours the order in which you specify
  12.339 -	revisions, so <command role="hg-cmd">hg log -r 2:4</command>
  12.340 -	prints 2, 3, and 4. while <command role="hg-cmd">hg log -r
  12.341 -	  4:2</command> prints 4, 3, and 2.</para>
  12.342 -
  12.343 -    </sect2>
  12.344 -    <sect2>
  12.345 -      <title>More detailed information</title>
  12.346 -
  12.347 -      <para>While the summary information printed by <command
  12.348 -	  role="hg-cmd">hg log</command> is useful if you already know
  12.349 -	what you're looking for, you may need to see a complete
  12.350 -	description of the change, or a list of the files changed, if
  12.351 -	you're trying to decide whether a changeset is the one you're
  12.352 -	looking for. The <command role="hg-cmd">hg log</command>
  12.353 -	command's <option role="hg-opt-global">-v</option> (or <option
  12.354 -	  role="hg-opt-global">--verbose</option>) option gives you
  12.355 -	this extra detail.</para>
  12.356 -
  12.357 -      &interaction.tour.log-v;
  12.358 -
  12.359 -      <para>If you want to see both the description and content of a
  12.360 -	change, add the <option role="hg-opt-log">-p</option> (or
  12.361 -	<option role="hg-opt-log">--patch</option>) option.  This
  12.362 -	displays the content of a change as a <emphasis>unified
  12.363 -	  diff</emphasis> (if you've never seen a unified diff before,
  12.364 -	see section <xref linkend="sec.mq.patch"/> for an
  12.365 -	overview).</para>
  12.366 -
  12.367 -      &interaction.tour.log-vp;
  12.368 -
  12.369 -    </sect2>
  12.370 -  </sect1>
  12.371 -  <sect1>
  12.372 -    <title>All about command options</title>
  12.373 -
  12.374 -    <para>Let's take a brief break from exploring Mercurial commands
  12.375 -      to discuss a pattern in the way that they work; you may find
  12.376 -      this useful to keep in mind as we continue our tour.</para>
  12.377 -
  12.378 -    <para>Mercurial has a consistent and straightforward approach to
  12.379 -      dealing with the options that you can pass to commands.  It
  12.380 -      follows the conventions for options that are common to modern
  12.381 -      Linux and Unix systems.</para>
  12.382 -    <itemizedlist>
  12.383 -      <listitem><para>Every option has a long name.  For example, as
  12.384 -	  we've already seen, the <command role="hg-cmd">hg
  12.385 -	    log</command> command accepts a <option
  12.386 -	    role="hg-opt-log">--rev</option> option.</para></listitem>
  12.387 -      <listitem><para>Most options have short names, too.  Instead of
  12.388 -	  <option role="hg-opt-log">--rev</option>, we can use <option
  12.389 -	    role="hg-opt-log">-r</option>.  (The reason that some
  12.390 -	  options don't have short names is that the options in
  12.391 -	  question are rarely used.)</para></listitem>
  12.392 -      <listitem><para>Long options start with two dashes (e.g. <option
  12.393 -	    role="hg-opt-log">--rev</option>), while short options
  12.394 -	  start with one (e.g. <option
  12.395 -	    role="hg-opt-log">-r</option>).</para></listitem>
  12.396 -      <listitem><para>Option naming and usage is consistent across
  12.397 -	  commands.  For example, every command that lets you specify
  12.398 -	  a changeset ID or revision number accepts both <option
  12.399 -	    role="hg-opt-log">-r</option> and <option
  12.400 -	    role="hg-opt-log">--rev</option>
  12.401 -	  arguments.</para></listitem></itemizedlist>
  12.402 -    <para>In the examples throughout this book, I use short options
  12.403 -      instead of long.  This just reflects my own preference, so don't
  12.404 -      read anything significant into it.</para>
  12.405 -
  12.406 -    <para>Most commands that print output of some kind will print more
  12.407 -      output when passed a <option role="hg-opt-global">-v</option>
  12.408 -      (or <option role="hg-opt-global">--verbose</option>) option, and
  12.409 -      less when passed <option role="hg-opt-global">-q</option> (or
  12.410 -      <option role="hg-opt-global">--quiet</option>).</para>
  12.411 -
  12.412 -  </sect1>
  12.413 -  <sect1>
  12.414 -    <title>Making and reviewing changes</title>
  12.415 -
  12.416 -    <para>Now that we have a grasp of viewing history in Mercurial,
  12.417 -      let's take a look at making some changes and examining
  12.418 -      them.</para>
  12.419 -
  12.420 -    <para>The first thing we'll do is isolate our experiment in a
  12.421 -      repository of its own.  We use the <command role="hg-cmd">hg
  12.422 -	clone</command> command, but we don't need to clone a copy of
  12.423 -      the remote repository.  Since we already have a copy of it
  12.424 -      locally, we can just clone that instead.  This is much faster
  12.425 -      than cloning over the network, and cloning a local repository
  12.426 -      uses less disk space in most cases, too.</para>
  12.427 -
  12.428 -    &interaction.tour.reclone;
  12.429 -
  12.430 -    <para>As an aside, it's often good practice to keep a
  12.431 -      <quote>pristine</quote> copy of a remote repository around,
  12.432 -      which you can then make temporary clones of to create sandboxes
  12.433 -      for each task you want to work on.  This lets you work on
  12.434 -      multiple tasks in parallel, each isolated from the others until
  12.435 -      it's complete and you're ready to integrate it back.  Because
  12.436 -      local clones are so cheap, there's almost no overhead to cloning
  12.437 -      and destroying repositories whenever you want.</para>
  12.438 -
  12.439 -    <para>In our <filename class="directory">my-hello</filename>
  12.440 -      repository, we have a file <filename>hello.c</filename> that
  12.441 -      contains the classic <quote>hello, world</quote> program. Let's
  12.442 -      use the ancient and venerable <command>sed</command> command to
  12.443 -      edit this file so that it prints a second line of output.  (I'm
  12.444 -      only using <command>sed</command> to do this because it's easy
  12.445 -      to write a scripted example this way.  Since you're not under
  12.446 -      the same constraint, you probably won't want to use
  12.447 -      <command>sed</command>; simply use your preferred text editor to
  12.448 -      do the same thing.)</para>
  12.449 -
  12.450 -    &interaction.tour.sed;
  12.451 -
  12.452 -    <para>Mercurial's <command role="hg-cmd">hg status</command>
  12.453 -      command will tell us what Mercurial knows about the files in the
  12.454 -      repository.</para>
  12.455 -
  12.456 -    &interaction.tour.status;
  12.457 -
  12.458 -    <para>The <command role="hg-cmd">hg status</command> command
  12.459 -      prints no output for some files, but a line starting with
  12.460 -      <quote><literal>M</literal></quote> for
  12.461 -      <filename>hello.c</filename>.  Unless you tell it to, <command
  12.462 -	role="hg-cmd">hg status</command> will not print any output
  12.463 -      for files that have not been modified.</para>
  12.464 -
  12.465 -    <para>The <quote><literal>M</literal></quote> indicates that
  12.466 -      Mercurial has noticed that we modified
  12.467 -      <filename>hello.c</filename>.  We didn't need to
  12.468 -      <emphasis>inform</emphasis> Mercurial that we were going to
  12.469 -      modify the file before we started, or that we had modified the
  12.470 -      file after we were done; it was able to figure this out
  12.471 -      itself.</para>
  12.472 -
  12.473 -    <para>It's a little bit helpful to know that we've modified
  12.474 -      <filename>hello.c</filename>, but we might prefer to know
  12.475 -      exactly <emphasis>what</emphasis> changes we've made to it.  To
  12.476 -      do this, we use the <command role="hg-cmd">hg diff</command>
  12.477 -      command.</para>
  12.478 -
  12.479 -    &interaction.tour.diff;
  12.480 -
  12.481 -  </sect1>
  12.482 -  <sect1>
  12.483 -    <title>Recording changes in a new changeset</title>
  12.484 -
  12.485 -    <para>We can modify files, build and test our changes, and use
  12.486 -      <command role="hg-cmd">hg status</command> and <command
  12.487 -	role="hg-cmd">hg diff</command> to review our changes, until
  12.488 -      we're satisfied with what we've done and arrive at a natural
  12.489 -      stopping point where we want to record our work in a new
  12.490 -      changeset.</para>
  12.491 -
  12.492 -    <para>The <command role="hg-cmd">hg commit</command> command lets
  12.493 -      us create a new changeset; we'll usually refer to this as
  12.494 -      <quote>making a commit</quote> or
  12.495 -      <quote>committing</quote>.</para>
  12.496 -
  12.497 -    <sect2>
  12.498 -      <title>Setting up a username</title>
  12.499 -
  12.500 -      <para>When you try to run <command role="hg-cmd">hg
  12.501 -	  commit</command> for the first time, it is not guaranteed to
  12.502 -	succeed.  Mercurial records your name and address with each
  12.503 -	change that you commit, so that you and others will later be
  12.504 -	able to tell who made each change.  Mercurial tries to
  12.505 -	automatically figure out a sensible username to commit the
  12.506 -	change with.  It will attempt each of the following methods,
  12.507 -	in order:</para>
  12.508 -      <orderedlist>
  12.509 -	<listitem><para>If you specify a <option
  12.510 -	      role="hg-opt-commit">-u</option> option to the <command
  12.511 -	      role="hg-cmd">hg commit</command> command on the command
  12.512 -	    line, followed by a username, this is always given the
  12.513 -	    highest precedence.</para></listitem>
  12.514 -	<listitem><para>If you have set the <envar>HGUSER</envar>
  12.515 -	    environment variable, this is checked
  12.516 -	    next.</para></listitem>
  12.517 -	<listitem><para>If you create a file in your home directory
  12.518 -	    called <filename role="special">.hgrc</filename>, with a
  12.519 -	    <envar role="rc-item-ui">username</envar> entry, that will
  12.520 -	    be used next.  To see what the contents of this file
  12.521 -	    should look like, refer to section <xref
  12.522 -	      linkend="sec.tour-basic.username"/>
  12.523 -	    below.</para></listitem>
  12.524 -	<listitem><para>If you have set the <envar>EMAIL</envar>
  12.525 -	    environment variable, this will be used
  12.526 -	    next.</para></listitem>
  12.527 -	<listitem><para>Mercurial will query your system to find out
  12.528 -	    your local user name and host name, and construct a
  12.529 -	    username from these components. Since this often results
  12.530 -	    in a username that is not very useful, it will print a
  12.531 -	    warning if it has to do
  12.532 -	    this.</para></listitem>
  12.533 -      </orderedlist>
  12.534 -      <para>If all of these mechanisms fail, Mercurial will
  12.535 -	  fail, printing an error message.  In this case, it will not
  12.536 -	  let you commit until you set up a
  12.537 -	  username.</para>
  12.538 -      <para>You should think of the <envar>HGUSER</envar> environment
  12.539 -	variable and the <option role="hg-opt-commit">-u</option>
  12.540 -	option to the <command role="hg-cmd">hg commit</command>
  12.541 -	command as ways to <emphasis>override</emphasis> Mercurial's
  12.542 -	default selection of username.  For normal use, the simplest
  12.543 -	and most robust way to set a username for yourself is by
  12.544 -	creating a <filename role="special">.hgrc</filename> file; see
  12.545 -	below for details.</para>
  12.546 -      <sect3 id="sec.tour-basic.username">
  12.547 -	<title>Creating a Mercurial configuration file</title>
  12.548 -
  12.549 -	<para>To set a user name, use your favourite editor
  12.550 -	    to create a file called <filename
  12.551 -	      role="special">.hgrc</filename> in your home directory.
  12.552 -	    Mercurial will use this file to look up your personalised
  12.553 -	    configuration settings.  The initial contents of your
  12.554 -	    <filename role="special">.hgrc</filename> should look like
  12.555 -	    this.</para>
  12.556 -	<programlisting># This is a Mercurial configuration file.
  12.557 -[ui]
  12.558 -username = Firstname Lastname
  12.559 -&lt;email.address@domain.net&gt;</programlisting>
  12.560 -
  12.561 -	<para>The <quote><literal>[ui]</literal></quote> line begins a
  12.562 -	  <emphasis>section</emphasis> of the config file, so you can
  12.563 -	  read the <quote><literal>username = ...</literal></quote>
  12.564 -	  line as meaning <quote>set the value of the
  12.565 -	    <literal>username</literal> item in the
  12.566 -	    <literal>ui</literal> section</quote>. A section continues
  12.567 -	  until a new section begins, or the end of the file.
  12.568 -	  Mercurial ignores empty lines and treats any text from
  12.569 -	  <quote><literal>#</literal></quote> to the end of a line as
  12.570 -	  a comment.</para>
  12.571 -      </sect3>
  12.572 -
  12.573 -      <sect3>
  12.574 -	<title>Choosing a user name</title>
  12.575 -
  12.576 -	<para>You can use any text you like as the value of
  12.577 -	    the <literal>username</literal> config item, since this
  12.578 -	    information is for reading by other people, but for
  12.579 -	    interpreting by Mercurial.  The convention that most
  12.580 -	    people follow is to use their name and email address, as
  12.581 -	    in the example above.</para>
  12.582 -	<note>
  12.583 -	  <para>Mercurial's built-in web server obfuscates
  12.584 -	      email addresses, to make it more difficult for the email
  12.585 -	      harvesting tools that spammers use. This reduces the
  12.586 -	      likelihood that you'll start receiving more junk email
  12.587 -	      if you publish a Mercurial repository on the
  12.588 -	      web.</para></note>
  12.589 -
  12.590 -      </sect3>
  12.591 -    </sect2>
  12.592 -    <sect2>
  12.593 -      <title>Writing a commit message</title>
  12.594 -
  12.595 -      <para>When we commit a change, Mercurial drops us into
  12.596 -	  a text editor, to enter a message that will describe the
  12.597 -	  modifications we've made in this changeset.  This is called
  12.598 -	  the <emphasis>commit message</emphasis>.  It will be a
  12.599 -	  record for readers of what we did and why, and it will be
  12.600 -	  printed by <command role="hg-cmd">hg log</command> after
  12.601 -	  we've finished committing.</para>
  12.602 -
  12.603 -       &interaction.tour.commit;
  12.604 -
  12.605 -      <para>The editor that the <command role="hg-cmd">hg
  12.606 -	    commit</command> command drops us into will contain an
  12.607 -	  empty line, followed by a number of lines starting with
  12.608 -	  <quote><literal>HG:</literal></quote>.</para>
  12.609 -
  12.610 -    <programlisting>XXX fix this XXX</programlisting>
  12.611 -
  12.612 -      <para>Mercurial ignores the lines that start with
  12.613 -	  <quote><literal>HG:</literal></quote>; it uses them only to
  12.614 -	  tell us which files it's recording changes to.  Modifying or
  12.615 -	  deleting these lines has no effect.</para>
  12.616 -    </sect2>
  12.617 -    <sect2>
  12.618 -      <title>Writing a good commit message</title>
  12.619 -
  12.620 -      <para>Since <command role="hg-cmd">hg log</command>
  12.621 -	  only prints the first line of a commit message by default,
  12.622 -	  it's best to write a commit message whose first line stands
  12.623 -	  alone.  Here's a real example of a commit message that
  12.624 -	  <emphasis>doesn't</emphasis> follow this guideline, and
  12.625 -	  hence has a summary that is not
  12.626 -	  readable.</para>
  12.627 -
  12.628 -      <programlisting>
  12.629 -changeset:   73:584af0e231be
  12.630 -user:        Censored Person &lt;censored.person@example.org&gt;
  12.631 -date:        Tue Sep 26 21:37:07 2006 -0700
  12.632 -summary:     include buildmeister/commondefs. Add exports.</programlisting>
  12.633 -
  12.634 -      <para>As far as the remainder of the contents of the
  12.635 -	  commit message are concerned, there are no hard-and-fast
  12.636 -	  rules.  Mercurial itself doesn't interpret or care about the
  12.637 -	  contents of the commit message, though your project may have
  12.638 -	  policies that dictate a certain kind of
  12.639 -	  formatting.</para>
  12.640 -      <para>My personal preference is for short, but
  12.641 -	  informative, commit messages that tell me something that I
  12.642 -	  can't figure out with a quick glance at the output of
  12.643 -	  <command role="hg-cmd">hg log
  12.644 -	    --patch</command>.</para>
  12.645 -    </sect2>
  12.646 -    <sect2>
  12.647 -      <title>Aborting a commit</title>
  12.648 -
  12.649 -      <para>If you decide that you don't want to commit
  12.650 -	  while in the middle of editing a commit message, simply exit
  12.651 -	  from your editor without saving the file that it's editing.
  12.652 -	  This will cause nothing to happen to either the repository
  12.653 -	  or the working directory.</para>
  12.654 -      <para>If we run the <command role="hg-cmd">hg
  12.655 -	    commit</command> command without any arguments, it records
  12.656 -	  all of the changes we've made, as reported by <command
  12.657 -	    role="hg-cmd">hg status</command> and <command
  12.658 -	    role="hg-cmd">hg diff</command>.</para>
  12.659 -    </sect2>
  12.660 -    <sect2>
  12.661 -      <title>Admiring our new handiwork</title>
  12.662 -
  12.663 -      <para>Once we've finished the commit, we can use the
  12.664 -	  <command role="hg-cmd">hg tip</command> command to display
  12.665 -	  the changeset we just created.  This command produces output
  12.666 -	  that is identical to <command role="hg-cmd">hg
  12.667 -	    log</command>, but it only displays the newest revision in
  12.668 -	  the repository.</para>
  12.669 -
  12.670 -      &interaction.tour.tip;
  12.671 -
  12.672 -      <para>We refer to
  12.673 -	  the newest revision in the repository as the tip revision,
  12.674 -	  or simply the tip.</para>
  12.675 -    </sect2>
  12.676 -  </sect1>
  12.677 -
  12.678 -  <sect1>
  12.679 -    <title>Sharing changes</title>
  12.680 -
  12.681 -    <para>We mentioned earlier that repositories in
  12.682 -	Mercurial are self-contained.  This means that the changeset
  12.683 -	we just created exists only in our <filename
  12.684 -	  class="directory">my-hello</filename> repository.  Let's
  12.685 -	look at a few ways that we can propagate this change into
  12.686 -	other repositories.</para>
  12.687 -
  12.688 -    <sect2 id="sec.tour.pull">
  12.689 -      <title>Pulling changes from another repository</title>
  12.690 -      <para>To get started, let's clone our original
  12.691 -	  <filename class="directory">hello</filename> repository,
  12.692 -	  which does not contain the change we just committed.  We'll
  12.693 -	  call our temporary repository <filename
  12.694 -	    class="directory">hello-pull</filename>.</para>
  12.695 -
  12.696 -      &interaction.tour.clone-pull;
  12.697 -
  12.698 -      <para>We'll use the <command role="hg-cmd">hg
  12.699 -	    pull</command> command to bring changes from <filename
  12.700 -	    class="directory">my-hello</filename> into <filename
  12.701 -	    class="directory">hello-pull</filename>.  However, blindly
  12.702 -	  pulling unknown changes into a repository is a somewhat
  12.703 -	  scary prospect.  Mercurial provides the <command
  12.704 -	    role="hg-cmd">hg incoming</command> command to tell us
  12.705 -	  what changes the <command role="hg-cmd">hg pull</command>
  12.706 -	  command <emphasis>would</emphasis> pull into the repository,
  12.707 -	  without actually pulling the changes in.</para>
  12.708 -
  12.709 -      &interaction.tour.incoming;
  12.710 -
  12.711 -      <para>(Of course, someone could
  12.712 -	  cause more changesets to appear in the repository that we
  12.713 -	  ran <command role="hg-cmd">hg incoming</command> in, before
  12.714 -	  we get a chance to <command role="hg-cmd">hg pull</command>
  12.715 -	  the changes, so that we could end up pulling changes that we
  12.716 -	  didn't expect.)</para>
  12.717 -
  12.718 -      <para>Bringing changes into a repository is a simple
  12.719 -	  matter of running the <command role="hg-cmd">hg
  12.720 -	    pull</command> command, and telling it which repository to
  12.721 -	  pull from.</para>
  12.722 -
  12.723 -      &interaction.tour.pull;
  12.724 -
  12.725 -      <para>As you can see
  12.726 -	  from the before-and-after output of <command
  12.727 -	    role="hg-cmd">hg tip</command>, we have successfully
  12.728 -	  pulled changes into our repository.  There remains one step
  12.729 -	  before we can see these changes in the working
  12.730 -	  directory.</para>
  12.731 -    </sect2>
  12.732 -    <sect2>
  12.733 -      <title>Updating the working directory</title>
  12.734 -
  12.735 -      <para>We have so far glossed over the relationship between a
  12.736 -	repository and its working directory.  The <command
  12.737 -	  role="hg-cmd">hg pull</command> command that we ran in
  12.738 -	section <xref linkend="sec.tour.pull"/> brought changes
  12.739 -	into the repository, but if we check, there's no sign of those
  12.740 -	changes in the working directory.  This is because <command
  12.741 -	  role="hg-cmd">hg pull</command> does not (by default) touch
  12.742 -	the working directory.  Instead, we use the <command
  12.743 -	  role="hg-cmd">hg update</command> command to do this.</para>
  12.744 -
  12.745 -      &interaction.tour.update;
  12.746 -
  12.747 -      <para>It might seem a bit strange that <command role="hg-cmd">hg
  12.748 -	  pull</command> doesn't update the working directory
  12.749 -	automatically.  There's actually a good reason for this: you
  12.750 -	can use <command role="hg-cmd">hg update</command> to update
  12.751 -	the working directory to the state it was in at <emphasis>any
  12.752 -	  revision</emphasis> in the history of the repository.  If
  12.753 -	you had the working directory updated to an old revision---to
  12.754 -	hunt down the origin of a bug, say---and ran a <command
  12.755 -	  role="hg-cmd">hg pull</command> which automatically updated
  12.756 -	the working directory to a new revision, you might not be
  12.757 -	terribly happy.</para>
  12.758 -      <para>However, since pull-then-update is such a common thing to
  12.759 -	do, Mercurial lets you combine the two by passing the <option
  12.760 -	  role="hg-opt-pull">-u</option> option to <command
  12.761 -	  role="hg-cmd">hg pull</command>.</para>
  12.762 -
  12.763 -      <para>If you look back at the output of <command
  12.764 -	  role="hg-cmd">hg pull</command> in section <xref
  12.765 -	    linkend="sec.tour.pull"/> when we ran it without <option
  12.766 -	  role="hg-opt-pull">-u</option>, you can see that it printed
  12.767 -	a helpful reminder that we'd have to take an explicit step to
  12.768 -	update the working directory:</para>
  12.769 -
  12.770 -      <!-- &interaction.xxx.fixme; -->
  12.771 -
  12.772 -      <para>To find out what revision the working directory is at, use
  12.773 -	the <command role="hg-cmd">hg parents</command>
  12.774 -	command.</para>
  12.775 -
  12.776 -      &interaction.tour.parents;
  12.777 -
  12.778 -      <para>If you look back at figure <xref
  12.779 -	   endterm="fig.tour-basic.history.caption" 
  12.780 -	   linkend="fig.tour-basic.history"/>,
  12.781 -	you'll see arrows connecting each changeset.  The node that
  12.782 -	the arrow leads <emphasis>from</emphasis> in each case is a
  12.783 -	parent, and the node that the arrow leads
  12.784 -	<emphasis>to</emphasis> is its child.  The working directory
  12.785 -	has a parent in just the same way; this is the changeset that
  12.786 -	the working directory currently contains.</para>
  12.787 -
  12.788 -      <para>To update the working directory to a particular revision,
  12.789 -
  12.790 -	give a revision number or changeset ID to the <command
  12.791 -	  role="hg-cmd">hg update</command> command.</para>
  12.792 -
  12.793 -      &interaction.tour.older;
  12.794 -
  12.795 -      <para>If you omit an explicit revision, <command
  12.796 -	  role="hg-cmd">hg update</command> will update to the tip
  12.797 -	revision, as shown by the second call to <command
  12.798 -	  role="hg-cmd">hg update</command> in the example
  12.799 -	above.</para>
  12.800 -    </sect2>
  12.801 -
  12.802 -    <sect2>
  12.803 -      <title>Pushing changes to another repository</title>
  12.804 -
  12.805 -      <para>Mercurial lets us push changes to another
  12.806 -	  repository, from the repository we're currently visiting.
  12.807 -	  As with the example of <command role="hg-cmd">hg
  12.808 -	    pull</command> above, we'll create a temporary repository
  12.809 -	  to push our changes into.</para>
  12.810 -
  12.811 -      &interaction.tour.clone-push;
  12.812 -
  12.813 -      <para>The <command role="hg-cmd">hg outgoing</command> command
  12.814 -	  tells us what changes would be pushed into another
  12.815 -	  repository.</para>
  12.816 -
  12.817 -      &interaction.tour.outgoing;
  12.818 -
  12.819 -      <para>And the
  12.820 -	  <command role="hg-cmd">hg push</command> command does the
  12.821 -	  actual push.</para>
  12.822 -
  12.823 -      &interaction.tour.push;
  12.824 -
  12.825 -      <para>As with
  12.826 -	  <command role="hg-cmd">hg pull</command>, the <command
  12.827 -	    role="hg-cmd">hg push</command> command does not update
  12.828 -	  the working directory in the repository that it's pushing
  12.829 -	  changes into. (Unlike <command role="hg-cmd">hg
  12.830 -	    pull</command>, <command role="hg-cmd">hg push</command>
  12.831 -	  does not provide a <literal>-u</literal> option that updates
  12.832 -	  the other repository's working directory.)</para>
  12.833 -
  12.834 -      <para>What happens if we try to pull or push changes
  12.835 -	  and the receiving repository already has those changes?
  12.836 -	  Nothing too exciting.</para>
  12.837 -
  12.838 -      &interaction.tour.push.nothing;
  12.839 -    </sect2>
  12.840 -    <sect2>
  12.841 -      <title>Sharing changes over a network</title>
  12.842 -
  12.843 -      <para>The commands we have covered in the previous few
  12.844 -	  sections are not limited to working with local repositories.
  12.845 -	  Each works in exactly the same fashion over a network
  12.846 -	  connection; simply pass in a URL instead of a local
  12.847 -	  path.</para>
  12.848 -	
  12.849 -      &interaction.tour.outgoing.net;
  12.850 -
  12.851 -      <para>In this example, we
  12.852 -	  can see what changes we could push to the remote repository,
  12.853 -	  but the repository is understandably not set up to let
  12.854 -	  anonymous users push to it.</para>
  12.855 -
  12.856 -      &interaction.tour.push.net;
  12.857 -    </sect2>
  12.858 -  </sect1>
  12.859 -</chapter>
  12.860 -
  12.861 -<!--
  12.862 -local variables: 
  12.863 -sgml-parent-document: ("00book.xml" "book" "chapter")
  12.864 -end:
  12.865 --->
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/en/ch02-tour-merge.xml	Fri Mar 20 16:43:35 2009 +0800
    13.3 @@ -0,0 +1,401 @@
    13.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    13.5 +
    13.6 +<chapter id="chap.tour-merge">
    13.7 +  <?dbhtml filename="a-tour-of-mercurial-merging-work.html"?>
    13.8 +  <title>A tour of Mercurial: merging work</title>
    13.9 +
   13.10 +  <para>We've now covered cloning a repository, making changes in a
   13.11 +    repository, and pulling or pushing changes from one repository
   13.12 +    into another.  Our next step is <emphasis>merging</emphasis>
   13.13 +    changes from separate repositories.</para>
   13.14 +
   13.15 +  <sect1>
   13.16 +    <title>Merging streams of work</title>
   13.17 +
   13.18 +    <para>Merging is a fundamental part of working with a distributed
   13.19 +      revision control tool.</para>
   13.20 +    <itemizedlist>
   13.21 +      <listitem><para>Alice and Bob each have a personal copy of a
   13.22 +	  repository for a project they're collaborating on.  Alice
   13.23 +	  fixes a bug in her repository; Bob adds a new feature in
   13.24 +	  his.  They want the shared repository to contain both the
   13.25 +	  bug fix and the new feature.</para>
   13.26 +      </listitem>
   13.27 +      <listitem><para>I frequently work on several different tasks for
   13.28 +	  a single project at once, each safely isolated in its own
   13.29 +	  repository. Working this way means that I often need to
   13.30 +	  merge one piece of my own work with another.</para>
   13.31 +      </listitem></itemizedlist>
   13.32 +
   13.33 +    <para>Because merging is such a common thing to need to do,
   13.34 +      Mercurial makes it easy.  Let's walk through the process.  We'll
   13.35 +      begin by cloning yet another repository (see how often they
   13.36 +      spring up?) and making a change in it.</para>
   13.37 +
   13.38 +    &interaction.tour.merge.clone;
   13.39 +
   13.40 +    <para>We should now have two copies of
   13.41 +      <filename>hello.c</filename> with different contents.  The
   13.42 +      histories of the two repositories have also diverged, as
   13.43 +      illustrated in figure <xref endterm="fig.tour-merge.sep-repos.caption"
   13.44 +	linkend="fig.tour-merge.sep-repos"/>.</para>
   13.45 +
   13.46 +    &interaction.tour.merge.cat;
   13.47 +
   13.48 +    <informalfigure id="fig.tour-merge.sep-repos">
   13.49 +      <mediaobject>
   13.50 +	<imageobject><imagedata fileref="images/tour-merge-sep-repos.png"/></imageobject>
   13.51 +	<textobject><phrase>XXX add text</phrase></textobject>
   13.52 +	<caption><para id="fig.tour-merge.sep-repos.caption">Divergent recent
   13.53 +	  histories of the <filename
   13.54 +	      class="directory">my-hello</filename> and <filename
   13.55 +	      class="directory">my-new-hello</filename>
   13.56 +	    repositories</para></caption>
   13.57 +      </mediaobject>
   13.58 +    </informalfigure>
   13.59 +
   13.60 +    <para>We already know that pulling changes from our <filename
   13.61 +	class="directory">my-hello</filename> repository will have no
   13.62 +      effect on the working directory.</para>
   13.63 +
   13.64 +    &interaction.tour.merge.pull;
   13.65 +
   13.66 +    <para>However, the <command role="hg-cmd">hg pull</command>
   13.67 +      command says something about <quote>heads</quote>.</para>
   13.68 +
   13.69 +    <sect2>
   13.70 +      <title>Head changesets</title>
   13.71 +
   13.72 +      <para>A head is a change that has no descendants, or children,
   13.73 +	as they're also known.  The tip revision is thus a head,
   13.74 +	because the newest revision in a repository doesn't have any
   13.75 +	children, but a repository can contain more than one
   13.76 +	head.</para>
   13.77 +
   13.78 +      <informalfigure id="fig.tour-merge.pull">
   13.79 +	<mediaobject>
   13.80 +	  <imageobject><imagedata fileref="images/tour-merge-pull.png"/></imageobject>
   13.81 +	  <textobject><phrase>XXX add text</phrase></textobject>
   13.82 +	  <caption><para id="fig.tour-merge.pull.caption">Repository contents after
   13.83 +	    pulling from <filename class="directory">my-hello</filename> into
   13.84 +	    <filename class="directory">my-new-hello</filename></para></caption>
   13.85 +	</mediaobject>
   13.86 +      </informalfigure>
   13.87 +
   13.88 +      <para>In figure <xref endterm="fig.tour-merge.pull.caption"
   13.89 +        linkend="fig.tour-merge.pull"/>, you can
   13.90 +	see the effect of the pull from <filename
   13.91 +	  class="directory">my-hello</filename> into <filename
   13.92 +	  class="directory">my-new-hello</filename>.  The history that
   13.93 +	was already present in <filename
   13.94 +	  class="directory">my-new-hello</filename> is untouched, but
   13.95 +	a new revision has been added.  By referring to figure <xref
   13.96 +	  endterm="fig.tour-merge.sep-repos.caption" 
   13.97 +	  linkend="fig.tour-merge.sep-repos"/>, we can see that the
   13.98 +	<emphasis>changeset ID</emphasis> remains the same in the new
   13.99 +	repository, but the <emphasis>revision number</emphasis> has
  13.100 +	changed.  (This, incidentally, is a fine example of why it's
  13.101 +	not safe to use revision numbers when discussing changesets.)
  13.102 +	We can view the heads in a repository using the <command
  13.103 +	  role="hg-cmd">hg heads</command> command.</para>
  13.104 +
  13.105 +      &interaction.tour.merge.heads;
  13.106 +
  13.107 +    </sect2>
  13.108 +    <sect2>
  13.109 +      <title>Performing the merge</title>
  13.110 +
  13.111 +      <para>What happens if we try to use the normal <command
  13.112 +	  role="hg-cmd">hg update</command> command to update to the
  13.113 +	new tip?</para>
  13.114 +
  13.115 +      &interaction.tour.merge.update;
  13.116 +
  13.117 +      <para>Mercurial is telling us that the <command role="hg-cmd">hg
  13.118 +	  update</command> command won't do a merge; it won't update
  13.119 +	the working directory when it thinks we might be wanting to do
  13.120 +	a merge, unless we force it to do so.  Instead, we use the
  13.121 +	<command role="hg-cmd">hg merge</command> command to merge the
  13.122 +	two heads.</para>
  13.123 +
  13.124 +      &interaction.tour.merge.merge;
  13.125 +
  13.126 +      <informalfigure id="fig.tour-merge.merge">
  13.127 +	<mediaobject>
  13.128 +	  <imageobject><imagedata fileref="images/tour-merge-merge.png"/></imageobject>
  13.129 +	  <textobject><phrase>XXX add text</phrase></textobject>
  13.130 +	  <caption><para id="fig.tour-merge.merge.caption">Working directory and
  13.131 +	      repository during merge, and following commit</para></caption>
  13.132 +	</mediaobject>
  13.133 +      </informalfigure>
  13.134 +
  13.135 +      <para>This updates the working directory so that it contains
  13.136 +	changes from <emphasis>both</emphasis> heads, which is
  13.137 +	reflected in both the output of <command role="hg-cmd">hg
  13.138 +	  parents</command> and the contents of
  13.139 +	<filename>hello.c</filename>.</para>
  13.140 +
  13.141 +      &interaction.tour.merge.parents;
  13.142 +
  13.143 +    </sect2>
  13.144 +    <sect2>
  13.145 +      <title>Committing the results of the merge</title>
  13.146 +
  13.147 +      <para>Whenever we've done a merge, <command role="hg-cmd">hg
  13.148 +	  parents</command> will display two parents until we <command
  13.149 +	  role="hg-cmd">hg commit</command> the results of the
  13.150 +	  merge.</para>
  13.151 +
  13.152 +	&interaction.tour.merge.commit;
  13.153 +
  13.154 +      <para>We now have a new tip revision; notice that it has
  13.155 +	<emphasis>both</emphasis> of our former heads as its parents.
  13.156 +	These are the same revisions that were previously displayed by
  13.157 +	<command role="hg-cmd">hg parents</command>.</para>
  13.158 +
  13.159 +      &interaction.tour.merge.tip;
  13.160 +
  13.161 +      <para>In figure <xref endterm="fig.tour-merge.merge.caption"
  13.162 +	  linkend="fig.tour-merge.merge"/>, you can see a
  13.163 +	representation of what happens to the working directory during
  13.164 +	the merge, and how this affects the repository when the commit
  13.165 +	happens.  During the merge, the working directory has two
  13.166 +	parent changesets, and these become the parents of the new
  13.167 +	changeset.</para>
  13.168 +
  13.169 +    </sect2>
  13.170 +  </sect1>
  13.171 +  <sect1>
  13.172 +    <title>Merging conflicting changes</title>
  13.173 +
  13.174 +    <para>Most merges are simple affairs, but sometimes you'll find
  13.175 +      yourself merging changes where each modifies the same portions
  13.176 +      of the same files.  Unless both modifications are identical,
  13.177 +      this results in a <emphasis>conflict</emphasis>, where you have
  13.178 +      to decide how to reconcile the different changes into something
  13.179 +      coherent.</para>
  13.180 +
  13.181 +    <informalfigure id="fig.tour-merge.conflict">
  13.182 +      <mediaobject>
  13.183 +        <imageobject><imagedata fileref="images/tour-merge-conflict.png"/>
  13.184 +        </imageobject>
  13.185 +        <textobject><phrase>XXX add text</phrase></textobject>
  13.186 +        <caption><para id="fig.tour-merge.conflict.caption">Conflicting
  13.187 +          changes to a document</para></caption>
  13.188 +      </mediaobject>
  13.189 +    </informalfigure>
  13.190 +
  13.191 +    <para>Figure <xref endterm="fig.tour-merge.conflict.caption"
  13.192 +      linkend="fig.tour-merge.conflict"/> illustrates
  13.193 +      an instance of two conflicting changes to a document.  We
  13.194 +      started with a single version of the file; then we made some
  13.195 +      changes; while someone else made different changes to the same
  13.196 +      text.  Our task in resolving the conflicting changes is to
  13.197 +      decide what the file should look like.</para>
  13.198 +
  13.199 +    <para>Mercurial doesn't have a built-in facility for handling
  13.200 +      conflicts. Instead, it runs an external program called
  13.201 +      <command>hgmerge</command>.  This is a shell script that is
  13.202 +      bundled with Mercurial; you can change it to behave however you
  13.203 +      please.  What it does by default is try to find one of several
  13.204 +      different merging tools that are likely to be installed on your
  13.205 +      system.  It first tries a few fully automatic merging tools; if
  13.206 +      these don't succeed (because the resolution process requires
  13.207 +      human guidance) or aren't present, the script tries a few
  13.208 +      different graphical merging tools.</para>
  13.209 +
  13.210 +    <para>It's also possible to get Mercurial to run another program
  13.211 +      or script instead of <command>hgmerge</command>, by setting the
  13.212 +      <envar>HGMERGE</envar> environment variable to the name of your
  13.213 +      preferred program.</para>
  13.214 +
  13.215 +    <sect2>
  13.216 +      <title>Using a graphical merge tool</title>
  13.217 +
  13.218 +      <para>My preferred graphical merge tool is
  13.219 +	<command>kdiff3</command>, which I'll use to describe the
  13.220 +	features that are common to graphical file merging tools.  You
  13.221 +	can see a screenshot of <command>kdiff3</command> in action in
  13.222 +	figure <xref endterm="fig.tour-merge.kdiff3.caption"
  13.223 +	linkend="fig.tour-merge.kdiff3"/>.  The kind of
  13.224 +	merge it is performing is called a <emphasis>three-way
  13.225 +	  merge</emphasis>, because there are three different versions
  13.226 +	of the file of interest to us.  The tool thus splits the upper
  13.227 +	portion of the window into three panes:</para>
  13.228 +      <itemizedlist>
  13.229 +	<listitem><para>At the left is the <emphasis>base</emphasis>
  13.230 +	    version of the file, i.e. the most recent version from
  13.231 +	    which the two versions we're trying to merge are
  13.232 +	    descended.</para>
  13.233 +	</listitem>
  13.234 +	<listitem><para>In the middle is <quote>our</quote> version of
  13.235 +	    the file, with the contents that we modified.</para>
  13.236 +	</listitem>
  13.237 +	<listitem><para>On the right is <quote>their</quote> version
  13.238 +	    of the file, the one that from the changeset that we're
  13.239 +	    trying to merge with.</para>
  13.240 +	</listitem></itemizedlist>
  13.241 +      <para>In the pane below these is the current
  13.242 +	<emphasis>result</emphasis> of the merge. Our task is to
  13.243 +	replace all of the red text, which indicates unresolved
  13.244 +	conflicts, with some sensible merger of the
  13.245 +	<quote>ours</quote> and <quote>theirs</quote> versions of the
  13.246 +	file.</para>
  13.247 +
  13.248 +      <para>All four of these panes are <emphasis>locked
  13.249 +	  together</emphasis>; if we scroll vertically or horizontally
  13.250 +	in any of them, the others are updated to display the
  13.251 +	corresponding sections of their respective files.</para>
  13.252 +
  13.253 +      <informalfigure id="fig.tour-merge.kdiff3">
  13.254 +        <mediaobject>
  13.255 +          <imageobject><imagedata width="100%" fileref="images/kdiff3.png"/>
  13.256 +          </imageobject>
  13.257 +          <textobject><phrase>XXX add text</phrase></textobject>
  13.258 +          <caption><para id="fig.tour-merge.kdiff3.caption">Using
  13.259 +            <command>kdiff3</command> to merge versions of a file</para>
  13.260 +          </caption>
  13.261 +        </mediaobject>
  13.262 +      </informalfigure>
  13.263 +
  13.264 +      <para>For each conflicting portion of the file, we can choose to
  13.265 +	resolve the conflict using some combination of text from the
  13.266 +	base version, ours, or theirs.  We can also manually edit the
  13.267 +	merged file at any time, in case we need to make further
  13.268 +	modifications.</para>
  13.269 +
  13.270 +      <para>There are <emphasis>many</emphasis> file merging tools
  13.271 +	available, too many to cover here.  They vary in which
  13.272 +	platforms they are available for, and in their particular
  13.273 +	strengths and weaknesses.  Most are tuned for merging files
  13.274 +	containing plain text, while a few are aimed at specialised
  13.275 +	file formats (generally XML).</para>
  13.276 +
  13.277 +    </sect2>
  13.278 +    <sect2>
  13.279 +      <title>A worked example</title>
  13.280 +
  13.281 +      <para>In this example, we will reproduce the file modification
  13.282 +	history of figure <xref endterm="fig.tour-merge.conflict.caption"
  13.283 +	linkend="fig.tour-merge.conflict"/>
  13.284 +	above.  Let's begin by creating a repository with a base
  13.285 +	version of our document.</para>
  13.286 +
  13.287 +      &interaction.tour-merge-conflict.wife;
  13.288 +
  13.289 +      <para>We'll clone the repository and make a change to the
  13.290 +	file.</para>
  13.291 +
  13.292 +      &interaction.tour-merge-conflict.cousin;
  13.293 +
  13.294 +      <para>And another clone, to simulate someone else making a
  13.295 +	change to the file. (This hints at the idea that it's not all
  13.296 +	that unusual to merge with yourself when you isolate tasks in
  13.297 +	separate repositories, and indeed to find and resolve
  13.298 +	conflicts while doing so.)</para>
  13.299 +
  13.300 +      &interaction.tour-merge-conflict.son;
  13.301 +
  13.302 +      <para>Having created two
  13.303 +	different versions of the file, we'll set up an environment
  13.304 +	suitable for running our merge.</para>
  13.305 +
  13.306 +      &interaction.tour-merge-conflict.pull;
  13.307 +
  13.308 +      <para>In this example, I won't use Mercurial's normal
  13.309 +	<command>hgmerge</command> program to do the merge, because it
  13.310 +	would drop my nice automated example-running tool into a
  13.311 +	graphical user interface.  Instead, I'll set
  13.312 +	<envar>HGMERGE</envar> to tell Mercurial to use the
  13.313 +	non-interactive <command>merge</command> command.  This is
  13.314 +	bundled with many Unix-like systems. If you're following this
  13.315 +	example on your computer, don't bother setting
  13.316 +	<envar>HGMERGE</envar>.</para>
  13.317 +
  13.318 +      <para><emphasis role="bold">XXX FIX THIS
  13.319 +	  EXAMPLE.</emphasis></para>
  13.320 +
  13.321 +      &interaction.tour-merge-conflict.merge;
  13.322 +
  13.323 +      <para>Because <command>merge</command> can't resolve the
  13.324 +	conflicting changes, it leaves <emphasis>merge
  13.325 +	  markers</emphasis> inside the file that has conflicts,
  13.326 +	indicating which lines have conflicts, and whether they came
  13.327 +	from our version of the file or theirs.</para>
  13.328 +
  13.329 +      <para>Mercurial can tell from the way <command>merge</command>
  13.330 +	exits that it wasn't able to merge successfully, so it tells
  13.331 +	us what commands we'll need to run if we want to redo the
  13.332 +	merging operation.  This could be useful if, for example, we
  13.333 +	were running a graphical merge tool and quit because we were
  13.334 +	confused or realised we had made a mistake.</para>
  13.335 +
  13.336 +      <para>If automatic or manual merges fail, there's nothing to
  13.337 +	prevent us from <quote>fixing up</quote> the affected files
  13.338 +	ourselves, and committing the results of our merge:</para>
  13.339 +
  13.340 +      &interaction.tour-merge-conflict.commit;
  13.341 +
  13.342 +    </sect2>
  13.343 +  </sect1>
  13.344 +  <sect1 id="sec.tour-merge.fetch">
  13.345 +    <title>Simplifying the pull-merge-commit sequence</title>
  13.346 +
  13.347 +    <para>The process of merging changes as outlined above is
  13.348 +      straightforward, but requires running three commands in
  13.349 +      sequence.</para>
  13.350 +    <programlisting>hg pull
  13.351 +hg merge
  13.352 +hg commit -m 'Merged remote changes'</programlisting>
  13.353 +    <para>In the case of the final commit, you also need to enter a
  13.354 +      commit message, which is almost always going to be a piece of
  13.355 +      uninteresting <quote>boilerplate</quote> text.</para>
  13.356 +
  13.357 +    <para>It would be nice to reduce the number of steps needed, if
  13.358 +      this were possible.  Indeed, Mercurial is distributed with an
  13.359 +      extension called <literal role="hg-ext">fetch</literal> that
  13.360 +      does just this.</para>
  13.361 +
  13.362 +    <para>Mercurial provides a flexible extension mechanism that lets
  13.363 +      people extend its functionality, while keeping the core of
  13.364 +      Mercurial small and easy to deal with.  Some extensions add new
  13.365 +      commands that you can use from the command line, while others
  13.366 +      work <quote>behind the scenes,</quote> for example adding
  13.367 +      capabilities to the server.</para>
  13.368 +
  13.369 +    <para>The <literal role="hg-ext">fetch</literal> extension adds a
  13.370 +      new command called, not surprisingly, <command role="hg-cmd">hg
  13.371 +	fetch</command>.  This extension acts as a combination of
  13.372 +      <command role="hg-cmd">hg pull</command>, <command
  13.373 +	role="hg-cmd">hg update</command> and <command
  13.374 +	role="hg-cmd">hg merge</command>.  It begins by pulling
  13.375 +      changes from another repository into the current repository.  If
  13.376 +      it finds that the changes added a new head to the repository, it
  13.377 +      begins a merge, then commits the result of the merge with an
  13.378 +      automatically-generated commit message.  If no new heads were
  13.379 +      added, it updates the working directory to the new tip
  13.380 +      changeset.</para>
  13.381 +
  13.382 +    <para>Enabling the <literal role="hg-ext">fetch</literal>
  13.383 +      extension is easy.  Edit your <filename
  13.384 +	role="special">.hgrc</filename>, and either go to the <literal
  13.385 +	role="rc-extensions">extensions</literal> section or create an
  13.386 +      <literal role="rc-extensions">extensions</literal> section. Then
  13.387 +      add a line that simply reads <quote><literal>fetch
  13.388 +	</literal></quote>.</para>
  13.389 +    <programlisting>[extensions]
  13.390 +fetch =</programlisting>
  13.391 +    <para>(Normally, on the right-hand side of the
  13.392 +      <quote><literal>=</literal></quote> would appear the location of
  13.393 +      the extension, but since the <literal
  13.394 +	role="hg-ext">fetch</literal> extension is in the standard
  13.395 +      distribution, Mercurial knows where to search for it.)</para>
  13.396 +
  13.397 +  </sect1>
  13.398 +</chapter>
  13.399 +
  13.400 +<!--
  13.401 +local variables: 
  13.402 +sgml-parent-document: ("00book.xml" "book" "chapter")
  13.403 +end:
  13.404 +-->
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/en/ch03-concepts.xml	Fri Mar 20 16:43:35 2009 +0800
    14.3 @@ -0,0 +1,751 @@
    14.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    14.5 +
    14.6 +<chapter id="chap.concepts">
    14.7 +  <?dbhtml filename="behind-the-scenes.html"?>
    14.8 +  <title>Behind the scenes</title>
    14.9 +
   14.10 +  <para>Unlike many revision control systems, the concepts upon which
   14.11 +    Mercurial is built are simple enough that it's easy to understand
   14.12 +    how the software really works.  Knowing this certainly isn't
   14.13 +    necessary, but I find it useful to have a <quote>mental
   14.14 +      model</quote> of what's going on.</para>
   14.15 +
   14.16 +  <para>This understanding gives me confidence that Mercurial has been
   14.17 +    carefully designed to be both <emphasis>safe</emphasis> and
   14.18 +    <emphasis>efficient</emphasis>.  And just as importantly, if it's
   14.19 +    easy for me to retain a good idea of what the software is doing
   14.20 +    when I perform a revision control task, I'm less likely to be
   14.21 +    surprised by its behaviour.</para>
   14.22 +
   14.23 +  <para>In this chapter, we'll initially cover the core concepts
   14.24 +    behind Mercurial's design, then continue to discuss some of the
   14.25 +    interesting details of its implementation.</para>
   14.26 +
   14.27 +  <sect1>
   14.28 +    <title>Mercurial's historical record</title>
   14.29 +
   14.30 +    <sect2>
   14.31 +      <title>Tracking the history of a single file</title>
   14.32 +
   14.33 +      <para>When Mercurial tracks modifications to a file, it stores
   14.34 +	the history of that file in a metadata object called a
   14.35 +	<emphasis>filelog</emphasis>.  Each entry in the filelog
   14.36 +	contains enough information to reconstruct one revision of the
   14.37 +	file that is being tracked.  Filelogs are stored as files in
   14.38 +	the <filename role="special"
   14.39 +	  class="directory">.hg/store/data</filename> directory.  A
   14.40 +	filelog contains two kinds of information: revision data, and
   14.41 +	an index to help Mercurial to find a revision
   14.42 +	efficiently.</para>
   14.43 +
   14.44 +      <para>A file that is large, or has a lot of history, has its
   14.45 +	filelog stored in separate data
   14.46 +	(<quote><literal>.d</literal></quote> suffix) and index
   14.47 +	(<quote><literal>.i</literal></quote> suffix) files.  For
   14.48 +	small files without much history, the revision data and index
   14.49 +	are combined in a single <quote><literal>.i</literal></quote>
   14.50 +	file.  The correspondence between a file in the working
   14.51 +	directory and the filelog that tracks its history in the
   14.52 +	repository is illustrated in figure <xref
   14.53 +	  endterm="fig.concepts.filelog.caption"
   14.54 +	  linkend="fig.concepts.filelog"/>.</para>
   14.55 +
   14.56 +      <informalfigure id="fig.concepts.filelog">
   14.57 +        <mediaobject>
   14.58 +          <imageobject><imagedata fileref="images/filelog.png"/></imageobject>
   14.59 +          <textobject><phrase>XXX add text</phrase></textobject>
   14.60 +          <caption><para id="fig.concepts.filelog.caption">Relationships between
   14.61 +            files in working directory and filelogs in repository</para>
   14.62 +          </caption>
   14.63 +        </mediaobject>
   14.64 +      </informalfigure>
   14.65 +
   14.66 +    </sect2>
   14.67 +    <sect2>
   14.68 +      <title>Managing tracked files</title>
   14.69 +
   14.70 +      <para>Mercurial uses a structure called a
   14.71 +	<emphasis>manifest</emphasis> to collect together information
   14.72 +	about the files that it tracks.  Each entry in the manifest
   14.73 +	contains information about the files present in a single
   14.74 +	changeset.  An entry records which files are present in the
   14.75 +	changeset, the revision of each file, and a few other pieces
   14.76 +	of file metadata.</para>
   14.77 +
   14.78 +    </sect2>
   14.79 +    <sect2>
   14.80 +      <title>Recording changeset information</title>
   14.81 +
   14.82 +      <para>The <emphasis>changelog</emphasis> contains information
   14.83 +	about each changeset.  Each revision records who committed a
   14.84 +	change, the changeset comment, other pieces of
   14.85 +	changeset-related information, and the revision of the
   14.86 +	manifest to use.</para>
   14.87 +
   14.88 +    </sect2>
   14.89 +    <sect2>
   14.90 +      <title>Relationships between revisions</title>
   14.91 +
   14.92 +      <para>Within a changelog, a manifest, or a filelog, each
   14.93 +	revision stores a pointer to its immediate parent (or to its
   14.94 +	two parents, if it's a merge revision).  As I mentioned above,
   14.95 +	there are also relationships between revisions
   14.96 +	<emphasis>across</emphasis> these structures, and they are
   14.97 +	hierarchical in nature.</para>
   14.98 +
   14.99 +      <para>For every changeset in a repository, there is exactly one
  14.100 +	revision stored in the changelog.  Each revision of the
  14.101 +	changelog contains a pointer to a single revision of the
  14.102 +	manifest.  A revision of the manifest stores a pointer to a
  14.103 +	single revision of each filelog tracked when that changeset
  14.104 +	was created.  These relationships are illustrated in figure
  14.105 +	<xref endterm="fig.concepts.metadata.caption"
  14.106 +	  linkend="fig.concepts.metadata"/>.</para>
  14.107 +
  14.108 +      <informalfigure id="fig.concepts.metadata">
  14.109 +        <mediaobject>
  14.110 +          <imageobject><imagedata fileref="images/metadata.png"/></imageobject>
  14.111 +          <textobject><phrase>XXX add text</phrase></textobject>
  14.112 +          <caption><para id="fig.concepts.metadata.caption">Metadata
  14.113 +            relationships</para></caption>
  14.114 +        </mediaobject>
  14.115 +      </informalfigure>
  14.116 +
  14.117 +      <para>As the illustration shows, there is
  14.118 +	<emphasis>not</emphasis> a <quote>one to one</quote>
  14.119 +	relationship between revisions in the changelog, manifest, or
  14.120 +	filelog. If the manifest hasn't changed between two
  14.121 +	changesets, the changelog entries for those changesets will
  14.122 +	point to the same revision of the manifest.  If a file that
  14.123 +	Mercurial tracks hasn't changed between two changesets, the
  14.124 +	entry for that file in the two revisions of the manifest will
  14.125 +	point to the same revision of its filelog.</para>
  14.126 +
  14.127 +    </sect2>
  14.128 +  </sect1>
  14.129 +  <sect1>
  14.130 +    <title>Safe, efficient storage</title>
  14.131 +
  14.132 +    <para>The underpinnings of changelogs, manifests, and filelogs are
  14.133 +      provided by a single structure called the
  14.134 +      <emphasis>revlog</emphasis>.</para>
  14.135 +
  14.136 +    <sect2>
  14.137 +      <title>Efficient storage</title>
  14.138 +
  14.139 +      <para>The revlog provides efficient storage of revisions using a
  14.140 +	<emphasis>delta</emphasis> mechanism.  Instead of storing a
  14.141 +	complete copy of a file for each revision, it stores the
  14.142 +	changes needed to transform an older revision into the new
  14.143 +	revision.  For many kinds of file data, these deltas are
  14.144 +	typically a fraction of a percent of the size of a full copy
  14.145 +	of a file.</para>
  14.146 +
  14.147 +      <para>Some obsolete revision control systems can only work with
  14.148 +	deltas of text files.  They must either store binary files as
  14.149 +	complete snapshots or encoded into a text representation, both
  14.150 +	of which are wasteful approaches.  Mercurial can efficiently
  14.151 +	handle deltas of files with arbitrary binary contents; it
  14.152 +	doesn't need to treat text as special.</para>
  14.153 +
  14.154 +    </sect2>
  14.155 +    <sect2 id="sec.concepts.txn">
  14.156 +      <title>Safe operation</title>
  14.157 +
  14.158 +      <para>Mercurial only ever <emphasis>appends</emphasis> data to
  14.159 +	the end of a revlog file. It never modifies a section of a
  14.160 +	file after it has written it.  This is both more robust and
  14.161 +	efficient than schemes that need to modify or rewrite
  14.162 +	data.</para>
  14.163 +
  14.164 +      <para>In addition, Mercurial treats every write as part of a
  14.165 +	<emphasis>transaction</emphasis> that can span a number of
  14.166 +	files.  A transaction is <emphasis>atomic</emphasis>: either
  14.167 +	the entire transaction succeeds and its effects are all
  14.168 +	visible to readers in one go, or the whole thing is undone.
  14.169 +	This guarantee of atomicity means that if you're running two
  14.170 +	copies of Mercurial, where one is reading data and one is
  14.171 +	writing it, the reader will never see a partially written
  14.172 +	result that might confuse it.</para>
  14.173 +
  14.174 +      <para>The fact that Mercurial only appends to files makes it
  14.175 +	easier to provide this transactional guarantee.  The easier it
  14.176 +	is to do stuff like this, the more confident you should be
  14.177 +	that it's done correctly.</para>
  14.178 +
  14.179 +    </sect2>
  14.180 +    <sect2>
  14.181 +      <title>Fast retrieval</title>
  14.182 +
  14.183 +      <para>Mercurial cleverly avoids a pitfall common to all earlier
  14.184 +	revision control systems: the problem of <emphasis>inefficient
  14.185 +	  retrieval</emphasis>. Most revision control systems store
  14.186 +	the contents of a revision as an incremental series of
  14.187 +	modifications against a <quote>snapshot</quote>.  To
  14.188 +	reconstruct a specific revision, you must first read the
  14.189 +	snapshot, and then every one of the revisions between the
  14.190 +	snapshot and your target revision.  The more history that a
  14.191 +	file accumulates, the more revisions you must read, hence the
  14.192 +	longer it takes to reconstruct a particular revision.</para>
  14.193 +
  14.194 +      <informalfigure id="fig.concepts.snapshot">
  14.195 +        <mediaobject>
  14.196 +          <imageobject><imagedata fileref="images/snapshot.png"/></imageobject>
  14.197 +          <textobject><phrase>XXX add text</phrase></textobject>
  14.198 +          <caption><para id="fig.concepts.snapshot.caption">Snapshot of
  14.199 +            a revlog, with incremental deltas</para></caption>
  14.200 +        </mediaobject>
  14.201 +      </informalfigure>
  14.202 +
  14.203 +      <para>The innovation that Mercurial applies to this problem is
  14.204 +	simple but effective.  Once the cumulative amount of delta
  14.205 +	information stored since the last snapshot exceeds a fixed
  14.206 +	threshold, it stores a new snapshot (compressed, of course),
  14.207 +	instead of another delta.  This makes it possible to
  14.208 +	reconstruct <emphasis>any</emphasis> revision of a file
  14.209 +	quickly.  This approach works so well that it has since been
  14.210 +	copied by several other revision control systems.</para>
  14.211 +
  14.212 +      <para>Figure <xref endterm="fig.concepts.snapshot.caption"
  14.213 +          linkend="fig.concepts.snapshot"/> illustrates
  14.214 +	the idea.  In an entry in a revlog's index file, Mercurial
  14.215 +	stores the range of entries from the data file that it must
  14.216 +	read to reconstruct a particular revision.</para>
  14.217 +
  14.218 +      <sect3>
  14.219 +	<title>Aside: the influence of video compression</title>
  14.220 +
  14.221 +	<para>If you're familiar with video compression or have ever
  14.222 +	  watched a TV feed through a digital cable or satellite
  14.223 +	  service, you may know that most video compression schemes
  14.224 +	  store each frame of video as a delta against its predecessor
  14.225 +	  frame.  In addition, these schemes use <quote>lossy</quote>
  14.226 +	  compression techniques to increase the compression ratio, so
  14.227 +	  visual errors accumulate over the course of a number of
  14.228 +	  inter-frame deltas.</para>
  14.229 +
  14.230 +	<para>Because it's possible for a video stream to <quote>drop
  14.231 +	    out</quote> occasionally due to signal glitches, and to
  14.232 +	  limit the accumulation of artefacts introduced by the lossy
  14.233 +	  compression process, video encoders periodically insert a
  14.234 +	  complete frame (called a <quote>key frame</quote>) into the
  14.235 +	  video stream; the next delta is generated against that
  14.236 +	  frame.  This means that if the video signal gets
  14.237 +	  interrupted, it will resume once the next key frame is
  14.238 +	  received.  Also, the accumulation of encoding errors
  14.239 +	  restarts anew with each key frame.</para>
  14.240 +
  14.241 +      </sect3>
  14.242 +    </sect2>
  14.243 +    <sect2>
  14.244 +      <title>Identification and strong integrity</title>
  14.245 +
  14.246 +      <para>Along with delta or snapshot information, a revlog entry
  14.247 +	contains a cryptographic hash of the data that it represents.
  14.248 +	This makes it difficult to forge the contents of a revision,
  14.249 +	and easy to detect accidental corruption.</para>
  14.250 +
  14.251 +      <para>Hashes provide more than a mere check against corruption;
  14.252 +	they are used as the identifiers for revisions.  The changeset
  14.253 +	identification hashes that you see as an end user are from
  14.254 +	revisions of the changelog.  Although filelogs and the
  14.255 +	manifest also use hashes, Mercurial only uses these behind the
  14.256 +	scenes.</para>
  14.257 +
  14.258 +      <para>Mercurial verifies that hashes are correct when it
  14.259 +	retrieves file revisions and when it pulls changes from
  14.260 +	another repository.  If it encounters an integrity problem, it
  14.261 +	will complain and stop whatever it's doing.</para>
  14.262 +
  14.263 +      <para>In addition to the effect it has on retrieval efficiency,
  14.264 +	Mercurial's use of periodic snapshots makes it more robust
  14.265 +	against partial data corruption.  If a revlog becomes partly
  14.266 +	corrupted due to a hardware error or system bug, it's often
  14.267 +	possible to reconstruct some or most revisions from the
  14.268 +	uncorrupted sections of the revlog, both before and after the
  14.269 +	corrupted section.  This would not be possible with a
  14.270 +	delta-only storage model.</para>
  14.271 +
  14.272 +    </sect2>
  14.273 +  </sect1>
  14.274 +  <sect1>
  14.275 +    <title>Revision history, branching, and merging</title>
  14.276 +
  14.277 +    <para>Every entry in a Mercurial revlog knows the identity of its
  14.278 +      immediate ancestor revision, usually referred to as its
  14.279 +      <emphasis>parent</emphasis>.  In fact, a revision contains room
  14.280 +      for not one parent, but two.  Mercurial uses a special hash,
  14.281 +      called the <quote>null ID</quote>, to represent the idea
  14.282 +      <quote>there is no parent here</quote>.  This hash is simply a
  14.283 +      string of zeroes.</para>
  14.284 +
  14.285 +    <para>In figure <xref endterm="fig.concepts.revlog.caption"
  14.286 +        linkend="fig.concepts.revlog"/>, you can see
  14.287 +      an example of the conceptual structure of a revlog.  Filelogs,
  14.288 +      manifests, and changelogs all have this same structure; they
  14.289 +      differ only in the kind of data stored in each delta or
  14.290 +      snapshot.</para>
  14.291 +
  14.292 +    <para>The first revision in a revlog (at the bottom of the image)
  14.293 +      has the null ID in both of its parent slots.  For a
  14.294 +      <quote>normal</quote> revision, its first parent slot contains
  14.295 +      the ID of its parent revision, and its second contains the null
  14.296 +      ID, indicating that the revision has only one real parent.  Any
  14.297 +      two revisions that have the same parent ID are branches.  A
  14.298 +      revision that represents a merge between branches has two normal
  14.299 +      revision IDs in its parent slots.</para>
  14.300 +
  14.301 +    <informalfigure id="fig.concepts.revlog">
  14.302 +      <mediaobject>
  14.303 +        <imageobject><imagedata fileref="images/revlog.png"/></imageobject>
  14.304 +        <textobject><phrase>XXX add text</phrase></textobject>        
  14.305 +	<caption><para id="fig.concepts.revlog.caption">Revision in revlog</para>
  14.306 +	</caption>
  14.307 +      </mediaobject>
  14.308 +    </informalfigure>
  14.309 +
  14.310 +  </sect1>
  14.311 +  <sect1>
  14.312 +    <title>The working directory</title>
  14.313 +
  14.314 +    <para>In the working directory, Mercurial stores a snapshot of the
  14.315 +      files from the repository as of a particular changeset.</para>
  14.316 +
  14.317 +    <para>The working directory <quote>knows</quote> which changeset
  14.318 +      it contains.  When you update the working directory to contain a
  14.319 +      particular changeset, Mercurial looks up the appropriate
  14.320 +      revision of the manifest to find out which files it was tracking
  14.321 +      at the time that changeset was committed, and which revision of
  14.322 +      each file was then current.  It then recreates a copy of each of
  14.323 +      those files, with the same contents it had when the changeset
  14.324 +      was committed.</para>
  14.325 +
  14.326 +    <para>The <emphasis>dirstate</emphasis> contains Mercurial's
  14.327 +      knowledge of the working directory.  This details which
  14.328 +      changeset the working directory is updated to, and all of the
  14.329 +      files that Mercurial is tracking in the working
  14.330 +      directory.</para>
  14.331 +
  14.332 +    <para>Just as a revision of a revlog has room for two parents, so
  14.333 +      that it can represent either a normal revision (with one parent)
  14.334 +      or a merge of two earlier revisions, the dirstate has slots for
  14.335 +      two parents.  When you use the <command role="hg-cmd">hg
  14.336 +	update</command> command, the changeset that you update to is
  14.337 +      stored in the <quote>first parent</quote> slot, and the null ID
  14.338 +      in the second. When you <command role="hg-cmd">hg
  14.339 +	merge</command> with another changeset, the first parent
  14.340 +      remains unchanged, and the second parent is filled in with the
  14.341 +      changeset you're merging with.  The <command role="hg-cmd">hg
  14.342 +	parents</command> command tells you what the parents of the
  14.343 +      dirstate are.</para>
  14.344 +
  14.345 +    <sect2>
  14.346 +      <title>What happens when you commit</title>
  14.347 +
  14.348 +      <para>The dirstate stores parent information for more than just
  14.349 +	book-keeping purposes.  Mercurial uses the parents of the
  14.350 +	dirstate as <emphasis>the parents of a new
  14.351 +	  changeset</emphasis> when you perform a commit.</para>
  14.352 +
  14.353 +      <informalfigure id="fig.concepts.wdir">
  14.354 +        <mediaobject>
  14.355 +          <imageobject><imagedata fileref="images/wdir.png"/></imageobject>
  14.356 +          <textobject><phrase>XXX add text</phrase></textobject>
  14.357 +          <caption><para id="fig.concepts.wdir.caption">The working
  14.358 +            directory can have two parents</para></caption>
  14.359 +        </mediaobject>
  14.360 +      </informalfigure>
  14.361 +
  14.362 +      <para>Figure <xref endterm="fig.concepts.wdir.caption"
  14.363 +          linkend="fig.concepts.wdir"/> shows the
  14.364 +	normal state of the working directory, where it has a single
  14.365 +	changeset as parent.  That changeset is the
  14.366 +	<emphasis>tip</emphasis>, the newest changeset in the
  14.367 +	repository that has no children.</para>
  14.368 +
  14.369 +      <informalfigure id="fig.concepts.wdir-after-commit">
  14.370 +        <mediaobject>
  14.371 +          <imageobject><imagedata fileref="images/wdir-after-commit.png"/>
  14.372 +          </imageobject>
  14.373 +          <textobject><phrase>XXX add text</phrase></textobject>
  14.374 +          <caption><para id="fig.concepts.wdir-after-commit.caption">The working
  14.375 +            directory gains new parents after a commit</para></caption>
  14.376 +        </mediaobject>
  14.377 +      </informalfigure>
  14.378 +
  14.379 +      <para>It's useful to think of the working directory as
  14.380 +	<quote>the changeset I'm about to commit</quote>.  Any files
  14.381 +	that you tell Mercurial that you've added, removed, renamed,
  14.382 +	or copied will be reflected in that changeset, as will
  14.383 +	modifications to any files that Mercurial is already tracking;
  14.384 +	the new changeset will have the parents of the working
  14.385 +	directory as its parents.</para>
  14.386 +
  14.387 +      <para>After a commit, Mercurial will update the parents of the
  14.388 +	working directory, so that the first parent is the ID of the
  14.389 +	new changeset, and the second is the null ID.  This is shown
  14.390 +	in figure <xref endterm="fig.concepts.wdir-after-commit.caption"
  14.391 +	  linkend="fig.concepts.wdir-after-commit"/>.
  14.392 +	Mercurial
  14.393 +	doesn't touch any of the files in the working directory when
  14.394 +	you commit; it just modifies the dirstate to note its new
  14.395 +	parents.</para>
  14.396 +
  14.397 +    </sect2>
  14.398 +    <sect2>
  14.399 +      <title>Creating a new head</title>
  14.400 +
  14.401 +      <para>It's perfectly normal to update the working directory to a
  14.402 +	changeset other than the current tip.  For example, you might
  14.403 +	want to know what your project looked like last Tuesday, or
  14.404 +	you could be looking through changesets to see which one
  14.405 +	introduced a bug.  In cases like this, the natural thing to do
  14.406 +	is update the working directory to the changeset you're
  14.407 +	interested in, and then examine the files in the working
  14.408 +	directory directly to see their contents as they were when you
  14.409 +	committed that changeset.  The effect of this is shown in
  14.410 +	figure <xref endterm="fig.concepts.wdir-pre-branch.caption"
  14.411 +	  linkend="fig.concepts.wdir-pre-branch"/>.</para>
  14.412 +
  14.413 +      <informalfigure id="fig.concepts.wdir-pre-branch">
  14.414 +        <mediaobject>
  14.415 +          <imageobject><imagedata fileref="images/wdir-pre-branch.png"/>
  14.416 +          </imageobject>
  14.417 +          <textobject><phrase>XXX add text</phrase></textobject>
  14.418 +          <caption><para id="fig.concepts.wdir-pre-branch.caption">The working
  14.419 +            directory, updated to an older changeset</para></caption>
  14.420 +        </mediaobject>
  14.421 +      </informalfigure>
  14.422 +
  14.423 +      <para>Having updated the working directory to an older
  14.424 +	changeset, what happens if you make some changes, and then
  14.425 +	commit?  Mercurial behaves in the same way as I outlined
  14.426 +	above.  The parents of the working directory become the
  14.427 +	parents of the new changeset.  This new changeset has no
  14.428 +	children, so it becomes the new tip.  And the repository now
  14.429 +	contains two changesets that have no children; we call these
  14.430 +	<emphasis>heads</emphasis>.  You can see the structure that
  14.431 +	this creates in figure <xref
  14.432 +	  endterm="fig.concepts.wdir-branch.caption"
  14.433 +	  linkend="fig.concepts.wdir-branch"/>.</para>
  14.434 +
  14.435 +      <informalfigure id="fig.concepts.wdir-branch">
  14.436 +        <mediaobject>
  14.437 +          <imageobject><imagedata fileref="images/wdir-branch.png"/>
  14.438 +          </imageobject>
  14.439 +          <textobject><phrase>XXX add text</phrase></textobject>
  14.440 +          <caption><para id="fig.concepts.wdir-branch.caption">After a
  14.441 +            commit made while synced to an older changeset</para></caption>
  14.442 +        </mediaobject>
  14.443 +      </informalfigure>
  14.444 +
  14.445 +      <note>
  14.446 +	<para>  If you're new to Mercurial, you should keep in mind a
  14.447 +	  common <quote>error</quote>, which is to use the <command
  14.448 +	    role="hg-cmd">hg pull</command> command without any
  14.449 +	  options.  By default, the <command role="hg-cmd">hg
  14.450 +	    pull</command> command <emphasis>does not</emphasis>
  14.451 +	  update the working directory, so you'll bring new changesets
  14.452 +	  into your repository, but the working directory will stay
  14.453 +	  synced at the same changeset as before the pull.  If you
  14.454 +	  make some changes and commit afterwards, you'll thus create
  14.455 +	  a new head, because your working directory isn't synced to
  14.456 +	  whatever the current tip is.</para>
  14.457 +
  14.458 +	<para>  I put the word <quote>error</quote> in quotes because
  14.459 +	  all that you need to do to rectify this situation is
  14.460 +	  <command role="hg-cmd">hg merge</command>, then <command
  14.461 +	    role="hg-cmd">hg commit</command>.  In other words, this
  14.462 +	  almost never has negative consequences; it just surprises
  14.463 +	  people.  I'll discuss other ways to avoid this behaviour,
  14.464 +	  and why Mercurial behaves in this initially surprising way,
  14.465 +	  later on.</para>
  14.466 +      </note>
  14.467 +
  14.468 +    </sect2>
  14.469 +    <sect2>
  14.470 +      <title>Merging heads</title>
  14.471 +
  14.472 +      <para>When you run the <command role="hg-cmd">hg merge</command>
  14.473 +	command, Mercurial leaves the first parent of the working
  14.474 +	directory unchanged, and sets the second parent to the
  14.475 +	changeset you're merging with, as shown in figure <xref
  14.476 +	  endterm="fig.concepts.wdir-merge.caption" 
  14.477 +	  linkend="fig.concepts.wdir-merge"/>.</para>
  14.478 +
  14.479 +      <informalfigure id="fig.concepts.wdir-merge">
  14.480 +        <mediaobject>
  14.481 +          <imageobject><imagedata fileref="images/wdir-merge.png"/>
  14.482 +          </imageobject>
  14.483 +          <textobject><phrase>XXX add text</phrase></textobject>
  14.484 +          <caption><para id="fig.concepts.wdir-merge.caption">Merging two
  14.485 +            heads</para></caption>
  14.486 +        </mediaobject>
  14.487 +      </informalfigure>
  14.488 +
  14.489 +      <para>Mercurial also has to modify the working directory, to
  14.490 +	merge the files managed in the two changesets.  Simplified a
  14.491 +	little, the merging process goes like this, for every file in
  14.492 +	the manifests of both changesets.</para>
  14.493 +      <itemizedlist>
  14.494 +	<listitem><para>If neither changeset has modified a file, do
  14.495 +	    nothing with that file.</para>
  14.496 +	</listitem>
  14.497 +	<listitem><para>If one changeset has modified a file, and the
  14.498 +	    other hasn't, create the modified copy of the file in the
  14.499 +	    working directory.</para>
  14.500 +	</listitem>
  14.501 +	<listitem><para>If one changeset has removed a file, and the
  14.502 +	    other hasn't (or has also deleted it), delete the file
  14.503 +	    from the working directory.</para>
  14.504 +	</listitem>
  14.505 +	<listitem><para>If one changeset has removed a file, but the
  14.506 +	    other has modified the file, ask the user what to do: keep
  14.507 +	    the modified file, or remove it?</para>
  14.508 +	</listitem>
  14.509 +	<listitem><para>If both changesets have modified a file,
  14.510 +	    invoke an external merge program to choose the new
  14.511 +	    contents for the merged file.  This may require input from
  14.512 +	    the user.</para>
  14.513 +	</listitem>
  14.514 +	<listitem><para>If one changeset has modified a file, and the
  14.515 +	    other has renamed or copied the file, make sure that the
  14.516 +	    changes follow the new name of the file.</para>
  14.517 +	</listitem></itemizedlist>
  14.518 +      <para>There are more details&emdash;merging has plenty of corner
  14.519 +	cases&emdash;but these are the most common choices that are
  14.520 +	involved in a merge.  As you can see, most cases are
  14.521 +	completely automatic, and indeed most merges finish
  14.522 +	automatically, without requiring your input to resolve any
  14.523 +	conflicts.</para>
  14.524 +
  14.525 +      <para>When you're thinking about what happens when you commit
  14.526 +	after a merge, once again the working directory is <quote>the
  14.527 +	  changeset I'm about to commit</quote>.  After the <command
  14.528 +	  role="hg-cmd">hg merge</command> command completes, the
  14.529 +	working directory has two parents; these will become the
  14.530 +	parents of the new changeset.</para>
  14.531 +
  14.532 +      <para>Mercurial lets you perform multiple merges, but you must
  14.533 +	commit the results of each individual merge as you go.  This
  14.534 +	is necessary because Mercurial only tracks two parents for
  14.535 +	both revisions and the working directory.  While it would be
  14.536 +	technically possible to merge multiple changesets at once, the
  14.537 +	prospect of user confusion and making a terrible mess of a
  14.538 +	merge immediately becomes overwhelming.</para>
  14.539 +
  14.540 +    </sect2>
  14.541 +  </sect1>
  14.542 +  <sect1>
  14.543 +    <title>Other interesting design features</title>
  14.544 +
  14.545 +    <para>In the sections above, I've tried to highlight some of the
  14.546 +      most important aspects of Mercurial's design, to illustrate that
  14.547 +      it pays careful attention to reliability and performance.
  14.548 +      However, the attention to detail doesn't stop there.  There are
  14.549 +      a number of other aspects of Mercurial's construction that I
  14.550 +      personally find interesting.  I'll detail a few of them here,
  14.551 +      separate from the <quote>big ticket</quote> items above, so that
  14.552 +      if you're interested, you can gain a better idea of the amount
  14.553 +      of thinking that goes into a well-designed system.</para>
  14.554 +
  14.555 +    <sect2>
  14.556 +      <title>Clever compression</title>
  14.557 +
  14.558 +      <para>When appropriate, Mercurial will store both snapshots and
  14.559 +	deltas in compressed form.  It does this by always
  14.560 +	<emphasis>trying to</emphasis> compress a snapshot or delta,
  14.561 +	but only storing the compressed version if it's smaller than
  14.562 +	the uncompressed version.</para>
  14.563 +
  14.564 +      <para>This means that Mercurial does <quote>the right
  14.565 +	  thing</quote> when storing a file whose native form is
  14.566 +	compressed, such as a <literal>zip</literal> archive or a JPEG
  14.567 +	image.  When these types of files are compressed a second
  14.568 +	time, the resulting file is usually bigger than the
  14.569 +	once-compressed form, and so Mercurial will store the plain
  14.570 +	<literal>zip</literal> or JPEG.</para>
  14.571 +
  14.572 +      <para>Deltas between revisions of a compressed file are usually
  14.573 +	larger than snapshots of the file, and Mercurial again does
  14.574 +	<quote>the right thing</quote> in these cases.  It finds that
  14.575 +	such a delta exceeds the threshold at which it should store a
  14.576 +	complete snapshot of the file, so it stores the snapshot,
  14.577 +	again saving space compared to a naive delta-only
  14.578 +	approach.</para>
  14.579 +
  14.580 +      <sect3>
  14.581 +	<title>Network recompression</title>
  14.582 +
  14.583 +	<para>When storing revisions on disk, Mercurial uses the
  14.584 +	  <quote>deflate</quote> compression algorithm (the same one
  14.585 +	  used by the popular <literal>zip</literal> archive format),
  14.586 +	  which balances good speed with a respectable compression
  14.587 +	  ratio.  However, when transmitting revision data over a
  14.588 +	  network connection, Mercurial uncompresses the compressed
  14.589 +	  revision data.</para>
  14.590 +
  14.591 +	<para>If the connection is over HTTP, Mercurial recompresses
  14.592 +	  the entire stream of data using a compression algorithm that
  14.593 +	  gives a better compression ratio (the Burrows-Wheeler
  14.594 +	  algorithm from the widely used <literal>bzip2</literal>
  14.595 +	  compression package).  This combination of algorithm and
  14.596 +	  compression of the entire stream (instead of a revision at a
  14.597 +	  time) substantially reduces the number of bytes to be
  14.598 +	  transferred, yielding better network performance over almost
  14.599 +	  all kinds of network.</para>
  14.600 +
  14.601 +	<para>(If the connection is over <command>ssh</command>,
  14.602 +	  Mercurial <emphasis>doesn't</emphasis> recompress the
  14.603 +	  stream, because <command>ssh</command> can already do this
  14.604 +	  itself.)</para>
  14.605 +
  14.606 +      </sect3>
  14.607 +    </sect2>
  14.608 +    <sect2>
  14.609 +      <title>Read/write ordering and atomicity</title>
  14.610 +
  14.611 +      <para>Appending to files isn't the whole story when it comes to
  14.612 +	guaranteeing that a reader won't see a partial write.  If you
  14.613 +	recall figure <xref endterm="fig.concepts.metadata.caption"
  14.614 +	linkend="fig.concepts.metadata"/>, revisions in the
  14.615 +	changelog point to revisions in the manifest, and revisions in
  14.616 +	the manifest point to revisions in filelogs.  This hierarchy
  14.617 +	is deliberate.</para>
  14.618 +
  14.619 +      <para>A writer starts a transaction by writing filelog and
  14.620 +	manifest data, and doesn't write any changelog data until
  14.621 +	those are finished.  A reader starts by reading changelog
  14.622 +	data, then manifest data, followed by filelog data.</para>
  14.623 +
  14.624 +      <para>Since the writer has always finished writing filelog and
  14.625 +	manifest data before it writes to the changelog, a reader will
  14.626 +	never read a pointer to a partially written manifest revision
  14.627 +	from the changelog, and it will never read a pointer to a
  14.628 +	partially written filelog revision from the manifest.</para>
  14.629 +
  14.630 +    </sect2>
  14.631 +    <sect2>
  14.632 +      <title>Concurrent access</title>
  14.633 +
  14.634 +      <para>The read/write ordering and atomicity guarantees mean that
  14.635 +	Mercurial never needs to <emphasis>lock</emphasis> a
  14.636 +	repository when it's reading data, even if the repository is
  14.637 +	being written to while the read is occurring. This has a big
  14.638 +	effect on scalability; you can have an arbitrary number of
  14.639 +	Mercurial processes safely reading data from a repository
  14.640 +	safely all at once, no matter whether it's being written to or
  14.641 +	not.</para>
  14.642 +
  14.643 +      <para>The lockless nature of reading means that if you're
  14.644 +	sharing a repository on a multi-user system, you don't need to
  14.645 +	grant other local users permission to
  14.646 +	<emphasis>write</emphasis> to your repository in order for
  14.647 +	them to be able to clone it or pull changes from it; they only
  14.648 +	need <emphasis>read</emphasis> permission.  (This is
  14.649 +	<emphasis>not</emphasis> a common feature among revision
  14.650 +	control systems, so don't take it for granted!  Most require
  14.651 +	readers to be able to lock a repository to access it safely,
  14.652 +	and this requires write permission on at least one directory,
  14.653 +	which of course makes for all kinds of nasty and annoying
  14.654 +	security and administrative problems.)</para>
  14.655 +
  14.656 +      <para>Mercurial uses locks to ensure that only one process can
  14.657 +	write to a repository at a time (the locking mechanism is safe
  14.658 +	even over filesystems that are notoriously hostile to locking,
  14.659 +	such as NFS).  If a repository is locked, a writer will wait
  14.660 +	for a while to retry if the repository becomes unlocked, but
  14.661 +	if the repository remains locked for too long, the process
  14.662 +	attempting to write will time out after a while. This means
  14.663 +	that your daily automated scripts won't get stuck forever and
  14.664 +	pile up if a system crashes unnoticed, for example.  (Yes, the
  14.665 +	timeout is configurable, from zero to infinity.)</para>
  14.666 +
  14.667 +      <sect3>
  14.668 +	<title>Safe dirstate access</title>
  14.669 +
  14.670 +	<para>As with revision data, Mercurial doesn't take a lock to
  14.671 +	  read the dirstate file; it does acquire a lock to write it.
  14.672 +	  To avoid the possibility of reading a partially written copy
  14.673 +	  of the dirstate file, Mercurial writes to a file with a
  14.674 +	  unique name in the same directory as the dirstate file, then
  14.675 +	  renames the temporary file atomically to
  14.676 +	  <filename>dirstate</filename>.  The file named
  14.677 +	  <filename>dirstate</filename> is thus guaranteed to be
  14.678 +	  complete, not partially written.</para>
  14.679 +
  14.680 +      </sect3>
  14.681 +    </sect2>
  14.682 +    <sect2>
  14.683 +      <title>Avoiding seeks</title>
  14.684 +
  14.685 +      <para>Critical to Mercurial's performance is the avoidance of
  14.686 +	seeks of the disk head, since any seek is far more expensive
  14.687 +	than even a comparatively large read operation.</para>
  14.688 +
  14.689 +      <para>This is why, for example, the dirstate is stored in a
  14.690 +	single file.  If there were a dirstate file per directory that
  14.691 +	Mercurial tracked, the disk would seek once per directory.
  14.692 +	Instead, Mercurial reads the entire single dirstate file in
  14.693 +	one step.</para>
  14.694 +
  14.695 +      <para>Mercurial also uses a <quote>copy on write</quote> scheme
  14.696 +	when cloning a repository on local storage.  Instead of
  14.697 +	copying every revlog file from the old repository into the new
  14.698 +	repository, it makes a <quote>hard link</quote>, which is a
  14.699 +	shorthand way to say <quote>these two names point to the same
  14.700 +	  file</quote>.  When Mercurial is about to write to one of a
  14.701 +	revlog's files, it checks to see if the number of names
  14.702 +	pointing at the file is greater than one.  If it is, more than
  14.703 +	one repository is using the file, so Mercurial makes a new
  14.704 +	copy of the file that is private to this repository.</para>
  14.705 +
  14.706 +      <para>A few revision control developers have pointed out that
  14.707 +	this idea of making a complete private copy of a file is not
  14.708 +	very efficient in its use of storage.  While this is true,
  14.709 +	storage is cheap, and this method gives the highest
  14.710 +	performance while deferring most book-keeping to the operating
  14.711 +	system.  An alternative scheme would most likely reduce
  14.712 +	performance and increase the complexity of the software, each
  14.713 +	of which is much more important to the <quote>feel</quote> of
  14.714 +	day-to-day use.</para>
  14.715 +
  14.716 +    </sect2>
  14.717 +    <sect2>
  14.718 +      <title>Other contents of the dirstate</title>
  14.719 +
  14.720 +      <para>Because Mercurial doesn't force you to tell it when you're
  14.721 +	modifying a file, it uses the dirstate to store some extra
  14.722 +	information so it can determine efficiently whether you have
  14.723 +	modified a file.  For each file in the working directory, it
  14.724 +	stores the time that it last modified the file itself, and the
  14.725 +	size of the file at that time.</para>
  14.726 +
  14.727 +      <para>When you explicitly <command role="hg-cmd">hg
  14.728 +	  add</command>, <command role="hg-cmd">hg remove</command>,
  14.729 +	<command role="hg-cmd">hg rename</command> or <command
  14.730 +	  role="hg-cmd">hg copy</command> files, Mercurial updates the
  14.731 +	dirstate so that it knows what to do with those files when you
  14.732 +	commit.</para>
  14.733 +
  14.734 +      <para>When Mercurial is checking the states of files in the
  14.735 +	working directory, it first checks a file's modification time.
  14.736 +	If that has not changed, the file must not have been modified.
  14.737 +	If the file's size has changed, the file must have been
  14.738 +	modified.  If the modification time has changed, but the size
  14.739 +	has not, only then does Mercurial need to read the actual
  14.740 +	contents of the file to see if they've changed. Storing these
  14.741 +	few extra pieces of information dramatically reduces the
  14.742 +	amount of data that Mercurial needs to read, which yields
  14.743 +	large performance improvements compared to other revision
  14.744 +	control systems.</para>
  14.745 +
  14.746 +    </sect2>
  14.747 +  </sect1>
  14.748 +</chapter>
  14.749 +
  14.750 +<!--
  14.751 +local variables: 
  14.752 +sgml-parent-document: ("00book.xml" "book" "chapter")
  14.753 +end:
  14.754 +-->
    15.1 --- a/en/ch03-tour-merge.xml	Fri Mar 20 15:40:06 2009 +0800
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,401 +0,0 @@
    15.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    15.5 -
    15.6 -<chapter id="chap.tour-merge">
    15.7 -  <?dbhtml filename="a-tour-of-mercurial-merging-work.html"?>
    15.8 -  <title>A tour of Mercurial: merging work</title>
    15.9 -
   15.10 -  <para>We've now covered cloning a repository, making changes in a
   15.11 -    repository, and pulling or pushing changes from one repository
   15.12 -    into another.  Our next step is <emphasis>merging</emphasis>
   15.13 -    changes from separate repositories.</para>
   15.14 -
   15.15 -  <sect1>
   15.16 -    <title>Merging streams of work</title>
   15.17 -
   15.18 -    <para>Merging is a fundamental part of working with a distributed
   15.19 -      revision control tool.</para>
   15.20 -    <itemizedlist>
   15.21 -      <listitem><para>Alice and Bob each have a personal copy of a
   15.22 -	  repository for a project they're collaborating on.  Alice
   15.23 -	  fixes a bug in her repository; Bob adds a new feature in
   15.24 -	  his.  They want the shared repository to contain both the
   15.25 -	  bug fix and the new feature.</para>
   15.26 -      </listitem>
   15.27 -      <listitem><para>I frequently work on several different tasks for
   15.28 -	  a single project at once, each safely isolated in its own
   15.29 -	  repository. Working this way means that I often need to
   15.30 -	  merge one piece of my own work with another.</para>
   15.31 -      </listitem></itemizedlist>
   15.32 -
   15.33 -    <para>Because merging is such a common thing to need to do,
   15.34 -      Mercurial makes it easy.  Let's walk through the process.  We'll
   15.35 -      begin by cloning yet another repository (see how often they
   15.36 -      spring up?) and making a change in it.</para>
   15.37 -
   15.38 -    &interaction.tour.merge.clone;
   15.39 -
   15.40 -    <para>We should now have two copies of
   15.41 -      <filename>hello.c</filename> with different contents.  The
   15.42 -      histories of the two repositories have also diverged, as
   15.43 -      illustrated in figure <xref endterm="fig.tour-merge.sep-repos.caption"
   15.44 -	linkend="fig.tour-merge.sep-repos"/>.</para>
   15.45 -
   15.46 -    &interaction.tour.merge.cat;
   15.47 -
   15.48 -    <informalfigure id="fig.tour-merge.sep-repos">
   15.49 -      <mediaobject>
   15.50 -	<imageobject><imagedata fileref="images/tour-merge-sep-repos.png"/></imageobject>
   15.51 -	<textobject><phrase>XXX add text</phrase></textobject>
   15.52 -	<caption><para id="fig.tour-merge.sep-repos.caption">Divergent recent
   15.53 -	  histories of the <filename
   15.54 -	      class="directory">my-hello</filename> and <filename
   15.55 -	      class="directory">my-new-hello</filename>
   15.56 -	    repositories</para></caption>
   15.57 -      </mediaobject>
   15.58 -    </informalfigure>
   15.59 -
   15.60 -    <para>We already know that pulling changes from our <filename
   15.61 -	class="directory">my-hello</filename> repository will have no
   15.62 -      effect on the working directory.</para>
   15.63 -
   15.64 -    &interaction.tour.merge.pull;
   15.65 -
   15.66 -    <para>However, the <command role="hg-cmd">hg pull</command>
   15.67 -      command says something about <quote>heads</quote>.</para>
   15.68 -
   15.69 -    <sect2>
   15.70 -      <title>Head changesets</title>
   15.71 -
   15.72 -      <para>A head is a change that has no descendants, or children,
   15.73 -	as they're also known.  The tip revision is thus a head,
   15.74 -	because the newest revision in a repository doesn't have any
   15.75 -	children, but a repository can contain more than one
   15.76 -	head.</para>
   15.77 -
   15.78 -      <informalfigure id="fig.tour-merge.pull">
   15.79 -	<mediaobject>
   15.80 -	  <imageobject><imagedata fileref="images/tour-merge-pull.png"/></imageobject>
   15.81 -	  <textobject><phrase>XXX add text</phrase></textobject>
   15.82 -	  <caption><para id="fig.tour-merge.pull.caption">Repository contents after
   15.83 -	    pulling from <filename class="directory">my-hello</filename> into
   15.84 -	    <filename class="directory">my-new-hello</filename></para></caption>
   15.85 -	</mediaobject>
   15.86 -      </informalfigure>
   15.87 -
   15.88 -      <para>In figure <xref endterm="fig.tour-merge.pull.caption"
   15.89 -        linkend="fig.tour-merge.pull"/>, you can
   15.90 -	see the effect of the pull from <filename
   15.91 -	  class="directory">my-hello</filename> into <filename
   15.92 -	  class="directory">my-new-hello</filename>.  The history that
   15.93 -	was already present in <filename
   15.94 -	  class="directory">my-new-hello</filename> is untouched, but
   15.95 -	a new revision has been added.  By referring to figure <xref
   15.96 -	  endterm="fig.tour-merge.sep-repos.caption" 
   15.97 -	  linkend="fig.tour-merge.sep-repos"/>, we can see that the
   15.98 -	<emphasis>changeset ID</emphasis> remains the same in the new
   15.99 -	repository, but the <emphasis>revision number</emphasis> has
  15.100 -	changed.  (This, incidentally, is a fine example of why it's
  15.101 -	not safe to use revision numbers when discussing changesets.)
  15.102 -	We can view the heads in a repository using the <command
  15.103 -	  role="hg-cmd">hg heads</command> command.</para>
  15.104 -
  15.105 -      &interaction.tour.merge.heads;
  15.106 -
  15.107 -    </sect2>
  15.108 -    <sect2>
  15.109 -      <title>Performing the merge</title>
  15.110 -
  15.111 -      <para>What happens if we try to use the normal <command
  15.112 -	  role="hg-cmd">hg update</command> command to update to the
  15.113 -	new tip?</para>
  15.114 -
  15.115 -      &interaction.tour.merge.update;
  15.116 -
  15.117 -      <para>Mercurial is telling us that the <command role="hg-cmd">hg
  15.118 -	  update</command> command won't do a merge; it won't update
  15.119 -	the working directory when it thinks we might be wanting to do
  15.120 -	a merge, unless we force it to do so.  Instead, we use the
  15.121 -	<command role="hg-cmd">hg merge</command> command to merge the
  15.122 -	two heads.</para>
  15.123 -
  15.124 -      &interaction.tour.merge.merge;
  15.125 -
  15.126 -      <informalfigure id="fig.tour-merge.merge">
  15.127 -	<mediaobject>
  15.128 -	  <imageobject><imagedata fileref="images/tour-merge-merge.png"/></imageobject>
  15.129 -	  <textobject><phrase>XXX add text</phrase></textobject>
  15.130 -	  <caption><para id="fig.tour-merge.merge.caption">Working directory and
  15.131 -	      repository during merge, and following commit</para></caption>
  15.132 -	</mediaobject>
  15.133 -      </informalfigure>
  15.134 -
  15.135 -      <para>This updates the working directory so that it contains
  15.136 -	changes from <emphasis>both</emphasis> heads, which is
  15.137 -	reflected in both the output of <command role="hg-cmd">hg
  15.138 -	  parents</command> and the contents of
  15.139 -	<filename>hello.c</filename>.</para>
  15.140 -
  15.141 -      &interaction.tour.merge.parents;
  15.142 -
  15.143 -    </sect2>
  15.144 -    <sect2>
  15.145 -      <title>Committing the results of the merge</title>
  15.146 -
  15.147 -      <para>Whenever we've done a merge, <command role="hg-cmd">hg
  15.148 -	  parents</command> will display two parents until we <command
  15.149 -	  role="hg-cmd">hg commit</command> the results of the
  15.150 -	  merge.</para>
  15.151 -
  15.152 -	&interaction.tour.merge.commit;
  15.153 -
  15.154 -      <para>We now have a new tip revision; notice that it has
  15.155 -	<emphasis>both</emphasis> of our former heads as its parents.
  15.156 -	These are the same revisions that were previously displayed by
  15.157 -	<command role="hg-cmd">hg parents</command>.</para>
  15.158 -
  15.159 -      &interaction.tour.merge.tip;
  15.160 -
  15.161 -      <para>In figure <xref endterm="fig.tour-merge.merge.caption"
  15.162 -	  linkend="fig.tour-merge.merge"/>, you can see a
  15.163 -	representation of what happens to the working directory during
  15.164 -	the merge, and how this affects the repository when the commit
  15.165 -	happens.  During the merge, the working directory has two
  15.166 -	parent changesets, and these become the parents of the new
  15.167 -	changeset.</para>
  15.168 -
  15.169 -    </sect2>
  15.170 -  </sect1>
  15.171 -  <sect1>
  15.172 -    <title>Merging conflicting changes</title>
  15.173 -
  15.174 -    <para>Most merges are simple affairs, but sometimes you'll find
  15.175 -      yourself merging changes where each modifies the same portions
  15.176 -      of the same files.  Unless both modifications are identical,
  15.177 -      this results in a <emphasis>conflict</emphasis>, where you have
  15.178 -      to decide how to reconcile the different changes into something
  15.179 -      coherent.</para>
  15.180 -
  15.181 -    <informalfigure id="fig.tour-merge.conflict">
  15.182 -      <mediaobject>
  15.183 -        <imageobject><imagedata fileref="images/tour-merge-conflict.png"/>
  15.184 -        </imageobject>
  15.185 -        <textobject><phrase>XXX add text</phrase></textobject>
  15.186 -        <caption><para id="fig.tour-merge.conflict.caption">Conflicting
  15.187 -          changes to a document</para></caption>
  15.188 -      </mediaobject>
  15.189 -    </informalfigure>
  15.190 -
  15.191 -    <para>Figure <xref endterm="fig.tour-merge.conflict.caption"
  15.192 -      linkend="fig.tour-merge.conflict"/> illustrates
  15.193 -      an instance of two conflicting changes to a document.  We
  15.194 -      started with a single version of the file; then we made some
  15.195 -      changes; while someone else made different changes to the same
  15.196 -      text.  Our task in resolving the conflicting changes is to
  15.197 -      decide what the file should look like.</para>
  15.198 -
  15.199 -    <para>Mercurial doesn't have a built-in facility for handling
  15.200 -      conflicts. Instead, it runs an external program called
  15.201 -      <command>hgmerge</command>.  This is a shell script that is
  15.202 -      bundled with Mercurial; you can change it to behave however you
  15.203 -      please.  What it does by default is try to find one of several
  15.204 -      different merging tools that are likely to be installed on your
  15.205 -      system.  It first tries a few fully automatic merging tools; if
  15.206 -      these don't succeed (because the resolution process requires
  15.207 -      human guidance) or aren't present, the script tries a few
  15.208 -      different graphical merging tools.</para>
  15.209 -
  15.210 -    <para>It's also possible to get Mercurial to run another program
  15.211 -      or script instead of <command>hgmerge</command>, by setting the
  15.212 -      <envar>HGMERGE</envar> environment variable to the name of your
  15.213 -      preferred program.</para>
  15.214 -
  15.215 -    <sect2>
  15.216 -      <title>Using a graphical merge tool</title>
  15.217 -
  15.218 -      <para>My preferred graphical merge tool is
  15.219 -	<command>kdiff3</command>, which I'll use to describe the
  15.220 -	features that are common to graphical file merging tools.  You
  15.221 -	can see a screenshot of <command>kdiff3</command> in action in
  15.222 -	figure <xref endterm="fig.tour-merge.kdiff3.caption"
  15.223 -	linkend="fig.tour-merge.kdiff3"/>.  The kind of
  15.224 -	merge it is performing is called a <emphasis>three-way
  15.225 -	  merge</emphasis>, because there are three different versions
  15.226 -	of the file of interest to us.  The tool thus splits the upper
  15.227 -	portion of the window into three panes:</para>
  15.228 -      <itemizedlist>
  15.229 -	<listitem><para>At the left is the <emphasis>base</emphasis>
  15.230 -	    version of the file, i.e. the most recent version from
  15.231 -	    which the two versions we're trying to merge are
  15.232 -	    descended.</para>
  15.233 -	</listitem>
  15.234 -	<listitem><para>In the middle is <quote>our</quote> version of
  15.235 -	    the file, with the contents that we modified.</para>
  15.236 -	</listitem>
  15.237 -	<listitem><para>On the right is <quote>their</quote> version
  15.238 -	    of the file, the one that from the changeset that we're
  15.239 -	    trying to merge with.</para>
  15.240 -	</listitem></itemizedlist>
  15.241 -      <para>In the pane below these is the current
  15.242 -	<emphasis>result</emphasis> of the merge. Our task is to
  15.243 -	replace all of the red text, which indicates unresolved
  15.244 -	conflicts, with some sensible merger of the
  15.245 -	<quote>ours</quote> and <quote>theirs</quote> versions of the
  15.246 -	file.</para>
  15.247 -
  15.248 -      <para>All four of these panes are <emphasis>locked
  15.249 -	  together</emphasis>; if we scroll vertically or horizontally
  15.250 -	in any of them, the others are updated to display the
  15.251 -	corresponding sections of their respective files.</para>
  15.252 -
  15.253 -      <informalfigure id="fig.tour-merge.kdiff3">
  15.254 -        <mediaobject>
  15.255 -          <imageobject><imagedata width="100%" fileref="images/kdiff3.png"/>
  15.256 -          </imageobject>
  15.257 -          <textobject><phrase>XXX add text</phrase></textobject>
  15.258 -          <caption><para id="fig.tour-merge.kdiff3.caption">Using
  15.259 -            <command>kdiff3</command> to merge versions of a file</para>
  15.260 -          </caption>
  15.261 -        </mediaobject>
  15.262 -      </informalfigure>
  15.263 -
  15.264 -      <para>For each conflicting portion of the file, we can choose to
  15.265 -	resolve the conflict using some combination of text from the
  15.266 -	base version, ours, or theirs.  We can also manually edit the
  15.267 -	merged file at any time, in case we need to make further
  15.268 -	modifications.</para>
  15.269 -
  15.270 -      <para>There are <emphasis>many</emphasis> file merging tools
  15.271 -	available, too many to cover here.  They vary in which
  15.272 -	platforms they are available for, and in their particular
  15.273 -	strengths and weaknesses.  Most are tuned for merging files
  15.274 -	containing plain text, while a few are aimed at specialised
  15.275 -	file formats (generally XML).</para>
  15.276 -
  15.277 -    </sect2>
  15.278 -    <sect2>
  15.279 -      <title>A worked example</title>
  15.280 -
  15.281 -      <para>In this example, we will reproduce the file modification
  15.282 -	history of figure <xref endterm="fig.tour-merge.conflict.caption"
  15.283 -	linkend="fig.tour-merge.conflict"/>
  15.284 -	above.  Let's begin by creating a repository with a base
  15.285 -	version of our document.</para>
  15.286 -
  15.287 -      &interaction.tour-merge-conflict.wife;
  15.288 -
  15.289 -      <para>We'll clone the repository and make a change to the
  15.290 -	file.</para>
  15.291 -
  15.292 -      &interaction.tour-merge-conflict.cousin;
  15.293 -
  15.294 -      <para>And another clone, to simulate someone else making a
  15.295 -	change to the file. (This hints at the idea that it's not all
  15.296 -	that unusual to merge with yourself when you isolate tasks in
  15.297 -	separate repositories, and indeed to find and resolve
  15.298 -	conflicts while doing so.)</para>
  15.299 -
  15.300 -      &interaction.tour-merge-conflict.son;
  15.301 -
  15.302 -      <para>Having created two
  15.303 -	different versions of the file, we'll set up an environment
  15.304 -	suitable for running our merge.</para>
  15.305 -
  15.306 -      &interaction.tour-merge-conflict.pull;
  15.307 -
  15.308 -      <para>In this example, I won't use Mercurial's normal
  15.309 -	<command>hgmerge</command> program to do the merge, because it
  15.310 -	would drop my nice automated example-running tool into a
  15.311 -	graphical user interface.  Instead, I'll set
  15.312 -	<envar>HGMERGE</envar> to tell Mercurial to use the
  15.313 -	non-interactive <command>merge</command> command.  This is
  15.314 -	bundled with many Unix-like systems. If you're following this
  15.315 -	example on your computer, don't bother setting
  15.316 -	<envar>HGMERGE</envar>.</para>
  15.317 -
  15.318 -      <para><emphasis role="bold">XXX FIX THIS
  15.319 -	  EXAMPLE.</emphasis></para>
  15.320 -
  15.321 -      &interaction.tour-merge-conflict.merge;
  15.322 -
  15.323 -      <para>Because <command>merge</command> can't resolve the
  15.324 -	conflicting changes, it leaves <emphasis>merge
  15.325 -	  markers</emphasis> inside the file that has conflicts,
  15.326 -	indicating which lines have conflicts, and whether they came
  15.327 -	from our version of the file or theirs.</para>
  15.328 -
  15.329 -      <para>Mercurial can tell from the way <command>merge</command>
  15.330 -	exits that it wasn't able to merge successfully, so it tells
  15.331 -	us what commands we'll need to run if we want to redo the
  15.332 -	merging operation.  This could be useful if, for example, we
  15.333 -	were running a graphical merge tool and quit because we were
  15.334 -	confused or realised we had made a mistake.</para>
  15.335 -
  15.336 -      <para>If automatic or manual merges fail, there's nothing to
  15.337 -	prevent us from <quote>fixing up</quote> the affected files
  15.338 -	ourselves, and committing the results of our merge:</para>
  15.339 -
  15.340 -      &interaction.tour-merge-conflict.commit;
  15.341 -
  15.342 -    </sect2>
  15.343 -  </sect1>
  15.344 -  <sect1 id="sec.tour-merge.fetch">
  15.345 -    <title>Simplifying the pull-merge-commit sequence</title>
  15.346 -
  15.347 -    <para>The process of merging changes as outlined above is
  15.348 -      straightforward, but requires running three commands in
  15.349 -      sequence.</para>
  15.350 -    <programlisting>hg pull
  15.351 -hg merge
  15.352 -hg commit -m 'Merged remote changes'</programlisting>
  15.353 -    <para>In the case of the final commit, you also need to enter a
  15.354 -      commit message, which is almost always going to be a piece of
  15.355 -      uninteresting <quote>boilerplate</quote> text.</para>
  15.356 -
  15.357 -    <para>It would be nice to reduce the number of steps needed, if
  15.358 -      this were possible.  Indeed, Mercurial is distributed with an
  15.359 -      extension called <literal role="hg-ext">fetch</literal> that
  15.360 -      does just this.</para>
  15.361 -
  15.362 -    <para>Mercurial provides a flexible extension mechanism that lets
  15.363 -      people extend its functionality, while keeping the core of
  15.364 -      Mercurial small and easy to deal with.  Some extensions add new
  15.365 -      commands that you can use from the command line, while others
  15.366 -      work <quote>behind the scenes,</quote> for example adding
  15.367 -      capabilities to the server.</para>
  15.368 -
  15.369 -    <para>The <literal role="hg-ext">fetch</literal> extension adds a
  15.370 -      new command called, not surprisingly, <command role="hg-cmd">hg
  15.371 -	fetch</command>.  This extension acts as a combination of
  15.372 -      <command role="hg-cmd">hg pull</command>, <command
  15.373 -	role="hg-cmd">hg update</command> and <command
  15.374 -	role="hg-cmd">hg merge</command>.  It begins by pulling
  15.375 -      changes from another repository into the current repository.  If
  15.376 -      it finds that the changes added a new head to the repository, it
  15.377 -      begins a merge, then commits the result of the merge with an
  15.378 -      automatically-generated commit message.  If no new heads were
  15.379 -      added, it updates the working directory to the new tip
  15.380 -      changeset.</para>
  15.381 -
  15.382 -    <para>Enabling the <literal role="hg-ext">fetch</literal>
  15.383 -      extension is easy.  Edit your <filename
  15.384 -	role="special">.hgrc</filename>, and either go to the <literal
  15.385 -	role="rc-extensions">extensions</literal> section or create an
  15.386 -      <literal role="rc-extensions">extensions</literal> section. Then
  15.387 -      add a line that simply reads <quote><literal>fetch
  15.388 -	</literal></quote>.</para>
  15.389 -    <programlisting>[extensions]
  15.390 -fetch =</programlisting>
  15.391 -    <para>(Normally, on the right-hand side of the
  15.392 -      <quote><literal>=</literal></quote> would appear the location of
  15.393 -      the extension, but since the <literal
  15.394 -	role="hg-ext">fetch</literal> extension is in the standard
  15.395 -      distribution, Mercurial knows where to search for it.)</para>
  15.396 -
  15.397 -  </sect1>
  15.398 -</chapter>
  15.399 -
  15.400 -<!--
  15.401 -local variables: 
  15.402 -sgml-parent-document: ("00book.xml" "book" "chapter")
  15.403 -end:
  15.404 --->
    16.1 --- a/en/ch04-concepts.xml	Fri Mar 20 15:40:06 2009 +0800
    16.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.3 @@ -1,751 +0,0 @@
    16.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    16.5 -
    16.6 -<chapter id="chap.concepts">
    16.7 -  <?dbhtml filename="behind-the-scenes.html"?>
    16.8 -  <title>Behind the scenes</title>
    16.9 -
   16.10 -  <para>Unlike many revision control systems, the concepts upon which
   16.11 -    Mercurial is built are simple enough that it's easy to understand
   16.12 -    how the software really works.  Knowing this certainly isn't
   16.13 -    necessary, but I find it useful to have a <quote>mental
   16.14 -      model</quote> of what's going on.</para>
   16.15 -
   16.16 -  <para>This understanding gives me confidence that Mercurial has been
   16.17 -    carefully designed to be both <emphasis>safe</emphasis> and
   16.18 -    <emphasis>efficient</emphasis>.  And just as importantly, if it's
   16.19 -    easy for me to retain a good idea of what the software is doing
   16.20 -    when I perform a revision control task, I'm less likely to be
   16.21 -    surprised by its behaviour.</para>
   16.22 -
   16.23 -  <para>In this chapter, we'll initially cover the core concepts
   16.24 -    behind Mercurial's design, then continue to discuss some of the
   16.25 -    interesting details of its implementation.</para>
   16.26 -
   16.27 -  <sect1>
   16.28 -    <title>Mercurial's historical record</title>
   16.29 -
   16.30 -    <sect2>
   16.31 -      <title>Tracking the history of a single file</title>
   16.32 -
   16.33 -      <para>When Mercurial tracks modifications to a file, it stores
   16.34 -	the history of that file in a metadata object called a
   16.35 -	<emphasis>filelog</emphasis>.  Each entry in the filelog
   16.36 -	contains enough information to reconstruct one revision of the
   16.37 -	file that is being tracked.  Filelogs are stored as files in
   16.38 -	the <filename role="special"
   16.39 -	  class="directory">.hg/store/data</filename> directory.  A
   16.40 -	filelog contains two kinds of information: revision data, and
   16.41 -	an index to help Mercurial to find a revision
   16.42 -	efficiently.</para>
   16.43 -
   16.44 -      <para>A file that is large, or has a lot of history, has its
   16.45 -	filelog stored in separate data
   16.46 -	(<quote><literal>.d</literal></quote> suffix) and index
   16.47 -	(<quote><literal>.i</literal></quote> suffix) files.  For
   16.48 -	small files without much history, the revision data and index
   16.49 -	are combined in a single <quote><literal>.i</literal></quote>
   16.50 -	file.  The correspondence between a file in the working
   16.51 -	directory and the filelog that tracks its history in the
   16.52 -	repository is illustrated in figure <xref
   16.53 -	  endterm="fig.concepts.filelog.caption"
   16.54 -	  linkend="fig.concepts.filelog"/>.</para>
   16.55 -
   16.56 -      <informalfigure id="fig.concepts.filelog">
   16.57 -        <mediaobject>
   16.58 -          <imageobject><imagedata fileref="images/filelog.png"/></imageobject>
   16.59 -          <textobject><phrase>XXX add text</phrase></textobject>
   16.60 -          <caption><para id="fig.concepts.filelog.caption">Relationships between
   16.61 -            files in working directory and filelogs in repository</para>
   16.62 -          </caption>
   16.63 -        </mediaobject>
   16.64 -      </informalfigure>
   16.65 -
   16.66 -    </sect2>
   16.67 -    <sect2>
   16.68 -      <title>Managing tracked files</title>
   16.69 -
   16.70 -      <para>Mercurial uses a structure called a
   16.71 -	<emphasis>manifest</emphasis> to collect together information
   16.72 -	about the files that it tracks.  Each entry in the manifest
   16.73 -	contains information about the files present in a single
   16.74 -	changeset.  An entry records which files are present in the
   16.75 -	changeset, the revision of each file, and a few other pieces
   16.76 -	of file metadata.</para>
   16.77 -
   16.78 -    </sect2>
   16.79 -    <sect2>
   16.80 -      <title>Recording changeset information</title>
   16.81 -
   16.82 -      <para>The <emphasis>changelog</emphasis> contains information
   16.83 -	about each changeset.  Each revision records who committed a
   16.84 -	change, the changeset comment, other pieces of
   16.85 -	changeset-related information, and the revision of the
   16.86 -	manifest to use.</para>
   16.87 -
   16.88 -    </sect2>
   16.89 -    <sect2>
   16.90 -      <title>Relationships between revisions</title>
   16.91 -
   16.92 -      <para>Within a changelog, a manifest, or a filelog, each
   16.93 -	revision stores a pointer to its immediate parent (or to its
   16.94 -	two parents, if it's a merge revision).  As I mentioned above,
   16.95 -	there are also relationships between revisions
   16.96 -	<emphasis>across</emphasis> these structures, and they are
   16.97 -	hierarchical in nature.</para>
   16.98 -
   16.99 -      <para>For every changeset in a repository, there is exactly one
  16.100 -	revision stored in the changelog.  Each revision of the
  16.101 -	changelog contains a pointer to a single revision of the
  16.102 -	manifest.  A revision of the manifest stores a pointer to a
  16.103 -	single revision of each filelog tracked when that changeset
  16.104 -	was created.  These relationships are illustrated in figure
  16.105 -	<xref endterm="fig.concepts.metadata.caption"
  16.106 -	  linkend="fig.concepts.metadata"/>.</para>
  16.107 -
  16.108 -      <informalfigure id="fig.concepts.metadata">
  16.109 -        <mediaobject>
  16.110 -          <imageobject><imagedata fileref="images/metadata.png"/></imageobject>
  16.111 -          <textobject><phrase>XXX add text</phrase></textobject>
  16.112 -          <caption><para id="fig.concepts.metadata.caption">Metadata
  16.113 -            relationships</para></caption>
  16.114 -        </mediaobject>
  16.115 -      </informalfigure>
  16.116 -
  16.117 -      <para>As the illustration shows, there is
  16.118 -	<emphasis>not</emphasis> a <quote>one to one</quote>
  16.119 -	relationship between revisions in the changelog, manifest, or
  16.120 -	filelog. If the manifest hasn't changed between two
  16.121 -	changesets, the changelog entries for those changesets will
  16.122 -	point to the same revision of the manifest.  If a file that
  16.123 -	Mercurial tracks hasn't changed between two changesets, the
  16.124 -	entry for that file in the two revisions of the manifest will
  16.125 -	point to the same revision of its filelog.</para>
  16.126 -
  16.127 -    </sect2>
  16.128 -  </sect1>
  16.129 -  <sect1>
  16.130 -    <title>Safe, efficient storage</title>
  16.131 -
  16.132 -    <para>The underpinnings of changelogs, manifests, and filelogs are
  16.133 -      provided by a single structure called the
  16.134 -      <emphasis>revlog</emphasis>.</para>
  16.135 -
  16.136 -    <sect2>
  16.137 -      <title>Efficient storage</title>
  16.138 -
  16.139 -      <para>The revlog provides efficient storage of revisions using a
  16.140 -	<emphasis>delta</emphasis> mechanism.  Instead of storing a
  16.141 -	complete copy of a file for each revision, it stores the
  16.142 -	changes needed to transform an older revision into the new
  16.143 -	revision.  For many kinds of file data, these deltas are
  16.144 -	typically a fraction of a percent of the size of a full copy
  16.145 -	of a file.</para>
  16.146 -
  16.147 -      <para>Some obsolete revision control systems can only work with
  16.148 -	deltas of text files.  They must either store binary files as
  16.149 -	complete snapshots or encoded into a text representation, both
  16.150 -	of which are wasteful approaches.  Mercurial can efficiently
  16.151 -	handle deltas of files with arbitrary binary contents; it
  16.152 -	doesn't need to treat text as special.</para>
  16.153 -
  16.154 -    </sect2>
  16.155 -    <sect2 id="sec.concepts.txn">
  16.156 -      <title>Safe operation</title>
  16.157 -
  16.158 -      <para>Mercurial only ever <emphasis>appends</emphasis> data to
  16.159 -	the end of a revlog file. It never modifies a section of a
  16.160 -	file after it has written it.  This is both more robust and
  16.161 -	efficient than schemes that need to modify or rewrite
  16.162 -	data.</para>
  16.163 -
  16.164 -      <para>In addition, Mercurial treats every write as part of a
  16.165 -	<emphasis>transaction</emphasis> that can span a number of
  16.166 -	files.  A transaction is <emphasis>atomic</emphasis>: either
  16.167 -	the entire transaction succeeds and its effects are all
  16.168 -	visible to readers in one go, or the whole thing is undone.
  16.169 -	This guarantee of atomicity means that if you're running two
  16.170 -	copies of Mercurial, where one is reading data and one is
  16.171 -	writing it, the reader will never see a partially written
  16.172 -	result that might confuse it.</para>
  16.173 -
  16.174 -      <para>The fact that Mercurial only appends to files makes it
  16.175 -	easier to provide this transactional guarantee.  The easier it
  16.176 -	is to do stuff like this, the more confident you should be
  16.177 -	that it's done correctly.</para>
  16.178 -
  16.179 -    </sect2>
  16.180 -    <sect2>
  16.181 -      <title>Fast retrieval</title>
  16.182 -
  16.183 -      <para>Mercurial cleverly avoids a pitfall common to all earlier
  16.184 -	revision control systems: the problem of <emphasis>inefficient
  16.185 -	  retrieval</emphasis>. Most revision control systems store
  16.186 -	the contents of a revision as an incremental series of
  16.187 -	modifications against a <quote>snapshot</quote>.  To
  16.188 -	reconstruct a specific revision, you must first read the
  16.189 -	snapshot, and then every one of the revisions between the
  16.190 -	snapshot and your target revision.  The more history that a
  16.191 -	file accumulates, the more revisions you must read, hence the
  16.192 -	longer it takes to reconstruct a particular revision.</para>
  16.193 -
  16.194 -      <informalfigure id="fig.concepts.snapshot">
  16.195 -        <mediaobject>
  16.196 -          <imageobject><imagedata fileref="images/snapshot.png"/></imageobject>
  16.197 -          <textobject><phrase>XXX add text</phrase></textobject>
  16.198 -          <caption><para id="fig.concepts.snapshot.caption">Snapshot of
  16.199 -            a revlog, with incremental deltas</para></caption>
  16.200 -        </mediaobject>
  16.201 -      </informalfigure>
  16.202 -
  16.203 -      <para>The innovation that Mercurial applies to this problem is
  16.204 -	simple but effective.  Once the cumulative amount of delta
  16.205 -	information stored since the last snapshot exceeds a fixed
  16.206 -	threshold, it stores a new snapshot (compressed, of course),
  16.207 -	instead of another delta.  This makes it possible to
  16.208 -	reconstruct <emphasis>any</emphasis> revision of a file
  16.209 -	quickly.  This approach works so well that it has since been
  16.210 -	copied by several other revision control systems.</para>
  16.211 -
  16.212 -      <para>Figure <xref endterm="fig.concepts.snapshot.caption"
  16.213 -          linkend="fig.concepts.snapshot"/> illustrates
  16.214 -	the idea.  In an entry in a revlog's index file, Mercurial
  16.215 -	stores the range of entries from the data file that it must
  16.216 -	read to reconstruct a particular revision.</para>
  16.217 -
  16.218 -      <sect3>
  16.219 -	<title>Aside: the influence of video compression</title>
  16.220 -
  16.221 -	<para>If you're familiar with video compression or have ever
  16.222 -	  watched a TV feed through a digital cable or satellite
  16.223 -	  service, you may know that most video compression schemes
  16.224 -	  store each frame of video as a delta against its predecessor
  16.225 -	  frame.  In addition, these schemes use <quote>lossy</quote>
  16.226 -	  compression techniques to increase the compression ratio, so
  16.227 -	  visual errors accumulate over the course of a number of
  16.228 -	  inter-frame deltas.</para>
  16.229 -
  16.230 -	<para>Because it's possible for a video stream to <quote>drop
  16.231 -	    out</quote> occasionally due to signal glitches, and to
  16.232 -	  limit the accumulation of artefacts introduced by the lossy
  16.233 -	  compression process, video encoders periodically insert a
  16.234 -	  complete frame (called a <quote>key frame</quote>) into the
  16.235 -	  video stream; the next delta is generated against that
  16.236 -	  frame.  This means that if the video signal gets
  16.237 -	  interrupted, it will resume once the next key frame is
  16.238 -	  received.  Also, the accumulation of encoding errors
  16.239 -	  restarts anew with each key frame.</para>
  16.240 -
  16.241 -      </sect3>
  16.242 -    </sect2>
  16.243 -    <sect2>
  16.244 -      <title>Identification and strong integrity</title>
  16.245 -
  16.246 -      <para>Along with delta or snapshot information, a revlog entry
  16.247 -	contains a cryptographic hash of the data that it represents.
  16.248 -	This makes it difficult to forge the contents of a revision,
  16.249 -	and easy to detect accidental corruption.</para>
  16.250 -
  16.251 -      <para>Hashes provide more than a mere check against corruption;
  16.252 -	they are used as the identifiers for revisions.  The changeset
  16.253 -	identification hashes that you see as an end user are from
  16.254 -	revisions of the changelog.  Although filelogs and the
  16.255 -	manifest also use hashes, Mercurial only uses these behind the
  16.256 -	scenes.</para>
  16.257 -
  16.258 -      <para>Mercurial verifies that hashes are correct when it
  16.259 -	retrieves file revisions and when it pulls changes from
  16.260 -	another repository.  If it encounters an integrity problem, it
  16.261 -	will complain and stop whatever it's doing.</para>
  16.262 -
  16.263 -      <para>In addition to the effect it has on retrieval efficiency,
  16.264 -	Mercurial's use of periodic snapshots makes it more robust
  16.265 -	against partial data corruption.  If a revlog becomes partly
  16.266 -	corrupted due to a hardware error or system bug, it's often
  16.267 -	possible to reconstruct some or most revisions from the
  16.268 -	uncorrupted sections of the revlog, both before and after the
  16.269 -	corrupted section.  This would not be possible with a
  16.270 -	delta-only storage model.</para>
  16.271 -
  16.272 -    </sect2>
  16.273 -  </sect1>
  16.274 -  <sect1>
  16.275 -    <title>Revision history, branching, and merging</title>
  16.276 -
  16.277 -    <para>Every entry in a Mercurial revlog knows the identity of its
  16.278 -      immediate ancestor revision, usually referred to as its
  16.279 -      <emphasis>parent</emphasis>.  In fact, a revision contains room
  16.280 -      for not one parent, but two.  Mercurial uses a special hash,
  16.281 -      called the <quote>null ID</quote>, to represent the idea
  16.282 -      <quote>there is no parent here</quote>.  This hash is simply a
  16.283 -      string of zeroes.</para>
  16.284 -
  16.285 -    <para>In figure <xref endterm="fig.concepts.revlog.caption"
  16.286 -        linkend="fig.concepts.revlog"/>, you can see
  16.287 -      an example of the conceptual structure of a revlog.  Filelogs,
  16.288 -      manifests, and changelogs all have this same structure; they
  16.289 -      differ only in the kind of data stored in each delta or
  16.290 -      snapshot.</para>
  16.291 -
  16.292 -    <para>The first revision in a revlog (at the bottom of the image)
  16.293 -      has the null ID in both of its parent slots.  For a
  16.294 -      <quote>normal</quote> revision, its first parent slot contains
  16.295 -      the ID of its parent revision, and its second contains the null
  16.296 -      ID, indicating that the revision has only one real parent.  Any
  16.297 -      two revisions that have the same parent ID are branches.  A
  16.298 -      revision that represents a merge between branches has two normal
  16.299 -      revision IDs in its parent slots.</para>
  16.300 -
  16.301 -    <informalfigure id="fig.concepts.revlog">
  16.302 -      <mediaobject>
  16.303 -        <imageobject><imagedata fileref="images/revlog.png"/></imageobject>
  16.304 -        <textobject><phrase>XXX add text</phrase></textobject>        
  16.305 -	<caption><para id="fig.concepts.revlog.caption">Revision in revlog</para>
  16.306 -	</caption>
  16.307 -      </mediaobject>
  16.308 -    </informalfigure>
  16.309 -
  16.310 -  </sect1>
  16.311 -  <sect1>
  16.312 -    <title>The working directory</title>
  16.313 -
  16.314 -    <para>In the working directory, Mercurial stores a snapshot of the
  16.315 -      files from the repository as of a particular changeset.</para>
  16.316 -
  16.317 -    <para>The working directory <quote>knows</quote> which changeset
  16.318 -      it contains.  When you update the working directory to contain a
  16.319 -      particular changeset, Mercurial looks up the appropriate
  16.320 -      revision of the manifest to find out which files it was tracking
  16.321 -      at the time that changeset was committed, and which revision of
  16.322 -      each file was then current.  It then recreates a copy of each of
  16.323 -      those files, with the same contents it had when the changeset
  16.324 -      was committed.</para>
  16.325 -
  16.326 -    <para>The <emphasis>dirstate</emphasis> contains Mercurial's
  16.327 -      knowledge of the working directory.  This details which
  16.328 -      changeset the working directory is updated to, and all of the
  16.329 -      files that Mercurial is tracking in the working
  16.330 -      directory.</para>
  16.331 -
  16.332 -    <para>Just as a revision of a revlog has room for two parents, so
  16.333 -      that it can represent either a normal revision (with one parent)
  16.334 -      or a merge of two earlier revisions, the dirstate has slots for
  16.335 -      two parents.  When you use the <command role="hg-cmd">hg
  16.336 -	update</command> command, the changeset that you update to is
  16.337 -      stored in the <quote>first parent</quote> slot, and the null ID
  16.338 -      in the second. When you <command role="hg-cmd">hg
  16.339 -	merge</command> with another changeset, the first parent
  16.340 -      remains unchanged, and the second parent is filled in with the
  16.341 -      changeset you're merging with.  The <command role="hg-cmd">hg
  16.342 -	parents</command> command tells you what the parents of the
  16.343 -      dirstate are.</para>
  16.344 -
  16.345 -    <sect2>
  16.346 -      <title>What happens when you commit</title>
  16.347 -
  16.348 -      <para>The dirstate stores parent information for more than just
  16.349 -	book-keeping purposes.  Mercurial uses the parents of the
  16.350 -	dirstate as <emphasis>the parents of a new
  16.351 -	  changeset</emphasis> when you perform a commit.</para>
  16.352 -
  16.353 -      <informalfigure id="fig.concepts.wdir">
  16.354 -        <mediaobject>
  16.355 -          <imageobject><imagedata fileref="images/wdir.png"/></imageobject>
  16.356 -          <textobject><phrase>XXX add text</phrase></textobject>
  16.357 -          <caption><para id="fig.concepts.wdir.caption">The working
  16.358 -            directory can have two parents</para></caption>
  16.359 -        </mediaobject>
  16.360 -      </informalfigure>
  16.361 -
  16.362 -      <para>Figure <xref endterm="fig.concepts.wdir.caption"
  16.363 -          linkend="fig.concepts.wdir"/> shows the
  16.364 -	normal state of the working directory, where it has a single
  16.365 -	changeset as parent.  That changeset is the
  16.366 -	<emphasis>tip</emphasis>, the newest changeset in the
  16.367 -	repository that has no children.</para>
  16.368 -
  16.369 -      <informalfigure id="fig.concepts.wdir-after-commit">
  16.370 -        <mediaobject>
  16.371 -          <imageobject><imagedata fileref="images/wdir-after-commit.png"/>
  16.372 -          </imageobject>
  16.373 -          <textobject><phrase>XXX add text</phrase></textobject>
  16.374 -          <caption><para id="fig.concepts.wdir-after-commit.caption">The working
  16.375 -            directory gains new parents after a commit</para></caption>
  16.376 -        </mediaobject>
  16.377 -      </informalfigure>
  16.378 -
  16.379 -      <para>It's useful to think of the working directory as
  16.380 -	<quote>the changeset I'm about to commit</quote>.  Any files
  16.381 -	that you tell Mercurial that you've added, removed, renamed,
  16.382 -	or copied will be reflected in that changeset, as will
  16.383 -	modifications to any files that Mercurial is already tracking;
  16.384 -	the new changeset will have the parents of the working
  16.385 -	directory as its parents.</para>
  16.386 -
  16.387 -      <para>After a commit, Mercurial will update the parents of the
  16.388 -	working directory, so that the first parent is the ID of the
  16.389 -	new changeset, and the second is the null ID.  This is shown
  16.390 -	in figure <xref endterm="fig.concepts.wdir-after-commit.caption"
  16.391 -	  linkend="fig.concepts.wdir-after-commit"/>.
  16.392 -	Mercurial
  16.393 -	doesn't touch any of the files in the working directory when
  16.394 -	you commit; it just modifies the dirstate to note its new
  16.395 -	parents.</para>
  16.396 -
  16.397 -    </sect2>
  16.398 -    <sect2>
  16.399 -      <title>Creating a new head</title>
  16.400 -
  16.401 -      <para>It's perfectly normal to update the working directory to a
  16.402 -	changeset other than the current tip.  For example, you might
  16.403 -	want to know what your project looked like last Tuesday, or
  16.404 -	you could be looking through changesets to see which one
  16.405 -	introduced a bug.  In cases like this, the natural thing to do
  16.406 -	is update the working directory to the changeset you're
  16.407 -	interested in, and then examine the files in the working
  16.408 -	directory directly to see their contents as they were when you
  16.409 -	committed that changeset.  The effect of this is shown in
  16.410 -	figure <xref endterm="fig.concepts.wdir-pre-branch.caption"
  16.411 -	  linkend="fig.concepts.wdir-pre-branch"/>.</para>
  16.412 -
  16.413 -      <informalfigure id="fig.concepts.wdir-pre-branch">
  16.414 -        <mediaobject>
  16.415 -          <imageobject><imagedata fileref="images/wdir-pre-branch.png"/>
  16.416 -          </imageobject>
  16.417 -          <textobject><phrase>XXX add text</phrase></textobject>
  16.418 -          <caption><para id="fig.concepts.wdir-pre-branch.caption">The working
  16.419 -            directory, updated to an older changeset</para></caption>
  16.420 -        </mediaobject>
  16.421 -      </informalfigure>
  16.422 -
  16.423 -      <para>Having updated the working directory to an older
  16.424 -	changeset, what happens if you make some changes, and then
  16.425 -	commit?  Mercurial behaves in the same way as I outlined
  16.426 -	above.  The parents of the working directory become the
  16.427 -	parents of the new changeset.  This new changeset has no
  16.428 -	children, so it becomes the new tip.  And the repository now
  16.429 -	contains two changesets that have no children; we call these
  16.430 -	<emphasis>heads</emphasis>.  You can see the structure that
  16.431 -	this creates in figure <xref
  16.432 -	  endterm="fig.concepts.wdir-branch.caption"
  16.433 -	  linkend="fig.concepts.wdir-branch"/>.</para>
  16.434 -
  16.435 -      <informalfigure id="fig.concepts.wdir-branch">
  16.436 -        <mediaobject>
  16.437 -          <imageobject><imagedata fileref="images/wdir-branch.png"/>
  16.438 -          </imageobject>
  16.439 -          <textobject><phrase>XXX add text</phrase></textobject>
  16.440 -          <caption><para id="fig.concepts.wdir-branch.caption">After a
  16.441 -            commit made while synced to an older changeset</para></caption>
  16.442 -        </mediaobject>
  16.443 -      </informalfigure>
  16.444 -
  16.445 -      <note>
  16.446 -	<para>  If you're new to Mercurial, you should keep in mind a
  16.447 -	  common <quote>error</quote>, which is to use the <command
  16.448 -	    role="hg-cmd">hg pull</command> command without any
  16.449 -	  options.  By default, the <command role="hg-cmd">hg
  16.450 -	    pull</command> command <emphasis>does not</emphasis>
  16.451 -	  update the working directory, so you'll bring new changesets
  16.452 -	  into your repository, but the working directory will stay
  16.453 -	  synced at the same changeset as before the pull.  If you
  16.454 -	  make some changes and commit afterwards, you'll thus create
  16.455 -	  a new head, because your working directory isn't synced to
  16.456 -	  whatever the current tip is.</para>
  16.457 -
  16.458 -	<para>  I put the word <quote>error</quote> in quotes because
  16.459 -	  all that you need to do to rectify this situation is
  16.460 -	  <command role="hg-cmd">hg merge</command>, then <command
  16.461 -	    role="hg-cmd">hg commit</command>.  In other words, this
  16.462 -	  almost never has negative consequences; it just surprises
  16.463 -	  people.  I'll discuss other ways to avoid this behaviour,
  16.464 -	  and why Mercurial behaves in this initially surprising way,
  16.465 -	  later on.</para>
  16.466 -      </note>
  16.467 -
  16.468 -    </sect2>
  16.469 -    <sect2>
  16.470 -      <title>Merging heads</title>
  16.471 -
  16.472 -      <para>When you run the <command role="hg-cmd">hg merge</command>
  16.473 -	command, Mercurial leaves the first parent of the working
  16.474 -	directory unchanged, and sets the second parent to the
  16.475 -	changeset you're merging with, as shown in figure <xref
  16.476 -	  endterm="fig.concepts.wdir-merge.caption" 
  16.477 -	  linkend="fig.concepts.wdir-merge"/>.</para>
  16.478 -
  16.479 -      <informalfigure id="fig.concepts.wdir-merge">
  16.480 -        <mediaobject>
  16.481 -          <imageobject><imagedata fileref="images/wdir-merge.png"/>
  16.482 -          </imageobject>
  16.483 -          <textobject><phrase>XXX add text</phrase></textobject>
  16.484 -          <caption><para id="fig.concepts.wdir-merge.caption">Merging two
  16.485 -            heads</para></caption>
  16.486 -        </mediaobject>
  16.487 -      </informalfigure>
  16.488 -
  16.489 -      <para>Mercurial also has to modify the working directory, to
  16.490 -	merge the files managed in the two changesets.  Simplified a
  16.491 -	little, the merging process goes like this, for every file in
  16.492 -	the manifests of both changesets.</para>
  16.493 -      <itemizedlist>
  16.494 -	<listitem><para>If neither changeset has modified a file, do
  16.495 -	    nothing with that file.</para>
  16.496 -	</listitem>
  16.497 -	<listitem><para>If one changeset has modified a file, and the
  16.498 -	    other hasn't, create the modified copy of the file in the
  16.499 -	    working directory.</para>
  16.500 -	</listitem>
  16.501 -	<listitem><para>If one changeset has removed a file, and the
  16.502 -	    other hasn't (or has also deleted it), delete the file
  16.503 -	    from the working directory.</para>
  16.504 -	</listitem>
  16.505 -	<listitem><para>If one changeset has removed a file, but the
  16.506 -	    other has modified the file, ask the user what to do: keep
  16.507 -	    the modified file, or remove it?</para>
  16.508 -	</listitem>
  16.509 -	<listitem><para>If both changesets have modified a file,
  16.510 -	    invoke an external merge program to choose the new
  16.511 -	    contents for the merged file.  This may require input from
  16.512 -	    the user.</para>
  16.513 -	</listitem>
  16.514 -	<listitem><para>If one changeset has modified a file, and the
  16.515 -	    other has renamed or copied the file, make sure that the
  16.516 -	    changes follow the new name of the file.</para>
  16.517 -	</listitem></itemizedlist>
  16.518 -      <para>There are more details&emdash;merging has plenty of corner
  16.519 -	cases&emdash;but these are the most common choices that are
  16.520 -	involved in a merge.  As you can see, most cases are
  16.521 -	completely automatic, and indeed most merges finish
  16.522 -	automatically, without requiring your input to resolve any
  16.523 -	conflicts.</para>
  16.524 -
  16.525 -      <para>When you're thinking about what happens when you commit
  16.526 -	after a merge, once again the working directory is <quote>the
  16.527 -	  changeset I'm about to commit</quote>.  After the <command
  16.528 -	  role="hg-cmd">hg merge</command> command completes, the
  16.529 -	working directory has two parents; these will become the
  16.530 -	parents of the new changeset.</para>
  16.531 -
  16.532 -      <para>Mercurial lets you perform multiple merges, but you must
  16.533 -	commit the results of each individual merge as you go.  This
  16.534 -	is necessary because Mercurial only tracks two parents for
  16.535 -	both revisions and the working directory.  While it would be
  16.536 -	technically possible to merge multiple changesets at once, the
  16.537 -	prospect of user confusion and making a terrible mess of a
  16.538 -	merge immediately becomes overwhelming.</para>
  16.539 -
  16.540 -    </sect2>
  16.541 -  </sect1>
  16.542 -  <sect1>
  16.543 -    <title>Other interesting design features</title>
  16.544 -
  16.545 -    <para>In the sections above, I've tried to highlight some of the
  16.546 -      most important aspects of Mercurial's design, to illustrate that
  16.547 -      it pays careful attention to reliability and performance.
  16.548 -      However, the attention to detail doesn't stop there.  There are
  16.549 -      a number of other aspects of Mercurial's construction that I
  16.550 -      personally find interesting.  I'll detail a few of them here,
  16.551 -      separate from the <quote>big ticket</quote> items above, so that
  16.552 -      if you're interested, you can gain a better idea of the amount
  16.553 -      of thinking that goes into a well-designed system.</para>
  16.554 -
  16.555 -    <sect2>
  16.556 -      <title>Clever compression</title>
  16.557 -
  16.558 -      <para>When appropriate, Mercurial will store both snapshots and
  16.559 -	deltas in compressed form.  It does this by always
  16.560 -	<emphasis>trying to</emphasis> compress a snapshot or delta,
  16.561 -	but only storing the compressed version if it's smaller than
  16.562 -	the uncompressed version.</para>
  16.563 -
  16.564 -      <para>This means that Mercurial does <quote>the right
  16.565 -	  thing</quote> when storing a file whose native form is
  16.566 -	compressed, such as a <literal>zip</literal> archive or a JPEG
  16.567 -	image.  When these types of files are compressed a second
  16.568 -	time, the resulting file is usually bigger than the
  16.569 -	once-compressed form, and so Mercurial will store the plain
  16.570 -	<literal>zip</literal> or JPEG.</para>
  16.571 -
  16.572 -      <para>Deltas between revisions of a compressed file are usually
  16.573 -	larger than snapshots of the file, and Mercurial again does
  16.574 -	<quote>the right thing</quote> in these cases.  It finds that
  16.575 -	such a delta exceeds the threshold at which it should store a
  16.576 -	complete snapshot of the file, so it stores the snapshot,
  16.577 -	again saving space compared to a naive delta-only
  16.578 -	approach.</para>
  16.579 -
  16.580 -      <sect3>
  16.581 -	<title>Network recompression</title>
  16.582 -
  16.583 -	<para>When storing revisions on disk, Mercurial uses the
  16.584 -	  <quote>deflate</quote> compression algorithm (the same one
  16.585 -	  used by the popular <literal>zip</literal> archive format),
  16.586 -	  which balances good speed with a respectable compression
  16.587 -	  ratio.  However, when transmitting revision data over a
  16.588 -	  network connection, Mercurial uncompresses the compressed
  16.589 -	  revision data.</para>
  16.590 -
  16.591 -	<para>If the connection is over HTTP, Mercurial recompresses
  16.592 -	  the entire stream of data using a compression algorithm that
  16.593 -	  gives a better compression ratio (the Burrows-Wheeler
  16.594 -	  algorithm from the widely used <literal>bzip2</literal>
  16.595 -	  compression package).  This combination of algorithm and
  16.596 -	  compression of the entire stream (instead of a revision at a
  16.597 -	  time) substantially reduces the number of bytes to be
  16.598 -	  transferred, yielding better network performance over almost
  16.599 -	  all kinds of network.</para>
  16.600 -
  16.601 -	<para>(If the connection is over <command>ssh</command>,
  16.602 -	  Mercurial <emphasis>doesn't</emphasis> recompress the
  16.603 -	  stream, because <command>ssh</command> can already do this
  16.604 -	  itself.)</para>
  16.605 -
  16.606 -      </sect3>
  16.607 -    </sect2>
  16.608 -    <sect2>
  16.609 -      <title>Read/write ordering and atomicity</title>
  16.610 -
  16.611 -      <para>Appending to files isn't the whole story when it comes to
  16.612 -	guaranteeing that a reader won't see a partial write.  If you
  16.613 -	recall figure <xref endterm="fig.concepts.metadata.caption"
  16.614 -	linkend="fig.concepts.metadata"/>, revisions in the
  16.615 -	changelog point to revisions in the manifest, and revisions in
  16.616 -	the manifest point to revisions in filelogs.  This hierarchy
  16.617 -	is deliberate.</para>
  16.618 -
  16.619 -      <para>A writer starts a transaction by writing filelog and
  16.620 -	manifest data, and doesn't write any changelog data until
  16.621 -	those are finished.  A reader starts by reading changelog
  16.622 -	data, then manifest data, followed by filelog data.</para>
  16.623 -
  16.624 -      <para>Since the writer has always finished writing filelog and
  16.625 -	manifest data before it writes to the changelog, a reader will
  16.626 -	never read a pointer to a partially written manifest revision
  16.627 -	from the changelog, and it will never read a pointer to a
  16.628 -	partially written filelog revision from the manifest.</para>
  16.629 -
  16.630 -    </sect2>
  16.631 -    <sect2>
  16.632 -      <title>Concurrent access</title>
  16.633 -
  16.634 -      <para>The read/write ordering and atomicity guarantees mean that
  16.635 -	Mercurial never needs to <emphasis>lock</emphasis> a
  16.636 -	repository when it's reading data, even if the repository is
  16.637 -	being written to while the read is occurring. This has a big
  16.638 -	effect on scalability; you can have an arbitrary number of
  16.639 -	Mercurial processes safely reading data from a repository
  16.640 -	safely all at once, no matter whether it's being written to or
  16.641 -	not.</para>
  16.642 -
  16.643 -      <para>The lockless nature of reading means that if you're
  16.644 -	sharing a repository on a multi-user system, you don't need to
  16.645 -	grant other local users permission to
  16.646 -	<emphasis>write</emphasis> to your repository in order for
  16.647 -	them to be able to clone it or pull changes from it; they only
  16.648 -	need <emphasis>read</emphasis> permission.  (This is
  16.649 -	<emphasis>not</emphasis> a common feature among revision
  16.650 -	control systems, so don't take it for granted!  Most require
  16.651 -	readers to be able to lock a repository to access it safely,
  16.652 -	and this requires write permission on at least one directory,
  16.653 -	which of course makes for all kinds of nasty and annoying
  16.654 -	security and administrative problems.)</para>
  16.655 -
  16.656 -      <para>Mercurial uses locks to ensure that only one process can
  16.657 -	write to a repository at a time (the locking mechanism is safe
  16.658 -	even over filesystems that are notoriously hostile to locking,
  16.659 -	such as NFS).  If a repository is locked, a writer will wait
  16.660 -	for a while to retry if the repository becomes unlocked, but
  16.661 -	if the repository remains locked for too long, the process
  16.662 -	attempting to write will time out after a while. This means
  16.663 -	that your daily automated scripts won't get stuck forever and
  16.664 -	pile up if a system crashes unnoticed, for example.  (Yes, the
  16.665 -	timeout is configurable, from zero to infinity.)</para>
  16.666 -
  16.667 -      <sect3>
  16.668 -	<title>Safe dirstate access</title>
  16.669 -
  16.670 -	<para>As with revision data, Mercurial doesn't take a lock to
  16.671 -	  read the dirstate file; it does acquire a lock to write it.
  16.672 -	  To avoid the possibility of reading a partially written copy
  16.673 -	  of the dirstate file, Mercurial writes to a file with a
  16.674 -	  unique name in the same directory as the dirstate file, then
  16.675 -	  renames the temporary file atomically to
  16.676 -	  <filename>dirstate</filename>.  The file named
  16.677 -	  <filename>dirstate</filename> is thus guaranteed to be
  16.678 -	  complete, not partially written.</para>
  16.679 -
  16.680 -      </sect3>
  16.681 -    </sect2>
  16.682 -    <sect2>
  16.683 -      <title>Avoiding seeks</title>
  16.684 -
  16.685 -      <para>Critical to Mercurial's performance is the avoidance of
  16.686 -	seeks of the disk head, since any seek is far more expensive
  16.687 -	than even a comparatively large read operation.</para>
  16.688 -
  16.689 -      <para>This is why, for example, the dirstate is stored in a
  16.690 -	single file.  If there were a dirstate file per directory that
  16.691 -	Mercurial tracked, the disk would seek once per directory.
  16.692 -	Instead, Mercurial reads the entire single dirstate file in
  16.693 -	one step.</para>
  16.694 -
  16.695 -      <para>Mercurial also uses a <quote>copy on write</quote> scheme
  16.696 -	when cloning a repository on local storage.  Instead of
  16.697 -	copying every revlog file from the old repository into the new
  16.698 -	repository, it makes a <quote>hard link</quote>, which is a
  16.699 -	shorthand way to say <quote>these two names point to the same
  16.700 -	  file</quote>.  When Mercurial is about to write to one of a
  16.701 -	revlog's files, it checks to see if the number of names
  16.702 -	pointing at the file is greater than one.  If it is, more than
  16.703 -	one repository is using the file, so Mercurial makes a new
  16.704 -	copy of the file that is private to this repository.</para>
  16.705 -
  16.706 -      <para>A few revision control developers have pointed out that
  16.707 -	this idea of making a complete private copy of a file is not
  16.708 -	very efficient in its use of storage.  While this is true,
  16.709 -	storage is cheap, and this method gives the highest
  16.710 -	performance while deferring most book-keeping to the operating
  16.711 -	system.  An alternative scheme would most likely reduce
  16.712 -	performance and increase the complexity of the software, each
  16.713 -	of which is much more important to the <quote>feel</quote> of
  16.714 -	day-to-day use.</para>
  16.715 -
  16.716 -    </sect2>
  16.717 -    <sect2>
  16.718 -      <title>Other contents of the dirstate</title>
  16.719 -
  16.720 -      <para>Because Mercurial doesn't force you to tell it when you're
  16.721 -	modifying a file, it uses the dirstate to store some extra
  16.722 -	information so it can determine efficiently whether you have
  16.723 -	modified a file.  For each file in the working directory, it
  16.724 -	stores the time that it last modified the file itself, and the
  16.725 -	size of the file at that time.</para>
  16.726 -
  16.727 -      <para>When you explicitly <command role="hg-cmd">hg
  16.728 -	  add</command>, <command role="hg-cmd">hg remove</command>,
  16.729 -	<command role="hg-cmd">hg rename</command> or <command
  16.730 -	  role="hg-cmd">hg copy</command> files, Mercurial updates the
  16.731 -	dirstate so that it knows what to do with those files when you
  16.732 -	commit.</para>
  16.733 -
  16.734 -      <para>When Mercurial is checking the states of files in the
  16.735 -	working directory, it first checks a file's modification time.
  16.736 -	If that has not changed, the file must not have been modified.
  16.737 -	If the file's size has changed, the file must have been
  16.738 -	modified.  If the modification time has changed, but the size
  16.739 -	has not, only then does Mercurial need to read the actual
  16.740 -	contents of the file to see if they've changed. Storing these
  16.741 -	few extra pieces of information dramatically reduces the
  16.742 -	amount of data that Mercurial needs to read, which yields
  16.743 -	large performance improvements compared to other revision
  16.744 -	control systems.</para>
  16.745 -
  16.746 -    </sect2>
  16.747 -  </sect1>
  16.748 -</chapter>
  16.749 -
  16.750 -<!--
  16.751 -local variables: 
  16.752 -sgml-parent-document: ("00book.xml" "book" "chapter")
  16.753 -end:
  16.754 --->
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/en/ch04-daily.xml	Fri Mar 20 16:43:35 2009 +0800
    17.3 @@ -0,0 +1,544 @@
    17.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    17.5 +
    17.6 +<chapter id="chap.daily">
    17.7 +  <?dbhtml filename="mercurial-in-daily-use.html"?>
    17.8 +  <title>Mercurial in daily use</title>
    17.9 +
   17.10 +  <sect1>
   17.11 +    <title>Telling Mercurial which files to track</title>
   17.12 +
   17.13 +    <para id="x_1a3">Mercurial does not work with files in your repository unless
   17.14 +      you tell it to manage them.  The <command role="hg-cmd">hg
   17.15 +	status</command> command will tell you which files Mercurial
   17.16 +      doesn't know about; it uses a
   17.17 +      <quote><literal>?</literal></quote> to display such
   17.18 +      files.</para>
   17.19 +
   17.20 +    <para id="x_1a4">To tell Mercurial to track a file, use the <command
   17.21 +	role="hg-cmd">hg add</command> command.  Once you have added a
   17.22 +      file, the entry in the output of <command role="hg-cmd">hg
   17.23 +	status</command> for that file changes from
   17.24 +      <quote><literal>?</literal></quote> to
   17.25 +      <quote><literal>A</literal></quote>.</para>
   17.26 +
   17.27 +      &interaction.daily.files.add;
   17.28 +
   17.29 +    <para id="x_1a5">After you run a <command role="hg-cmd">hg commit</command>,
   17.30 +      the files that you added before the commit will no longer be
   17.31 +      listed in the output of <command role="hg-cmd">hg
   17.32 +	status</command>.  The reason for this is that <command
   17.33 +	role="hg-cmd">hg status</command> only tells you about
   17.34 +      <quote>interesting</quote> files&emdash;those that you have
   17.35 +      modified or told Mercurial to do something with&emdash;by
   17.36 +      default.  If you have a repository that contains thousands of
   17.37 +      files, you will rarely want to know about files that Mercurial
   17.38 +      is tracking, but that have not changed.  (You can still get this
   17.39 +      information; we'll return to this later.)</para>
   17.40 +
   17.41 +    <para id="x_1a6">Once you add a file, Mercurial doesn't do anything with it
   17.42 +      immediately.  Instead, it will take a snapshot of the file's
   17.43 +      state the next time you perform a commit.  It will then continue
   17.44 +      to track the changes you make to the file every time you commit,
   17.45 +      until you remove the file.</para>
   17.46 +
   17.47 +    <sect2>
   17.48 +      <title>Explicit versus implicit file naming</title>
   17.49 +
   17.50 +      <para id="x_1a7">A useful behaviour that Mercurial has is that if you pass
   17.51 +	the name of a directory to a command, every Mercurial command
   17.52 +	will treat this as <quote>I want to operate on every file in
   17.53 +	  this directory and its subdirectories</quote>.</para>
   17.54 +
   17.55 +      &interaction.daily.files.add-dir;
   17.56 +
   17.57 +      <para id="x_1a8">Notice in this example that Mercurial printed the names of
   17.58 +	the files it added, whereas it didn't do so when we added the
   17.59 +	file named <filename>a</filename> in the earlier
   17.60 +	example.</para>
   17.61 +
   17.62 +      <para id="x_1a9">What's going on is that in the former case, we explicitly
   17.63 +	named the file to add on the command line, so the assumption
   17.64 +	that Mercurial makes in such cases is that you know what you
   17.65 +	were doing, and it doesn't print any output.</para>
   17.66 +
   17.67 +      <para id="x_1aa">However, when we <emphasis>imply</emphasis> the names of
   17.68 +	files by giving the name of a directory, Mercurial takes the
   17.69 +	extra step of printing the name of each file that it does
   17.70 +	something with.  This makes it more clear what is happening,
   17.71 +	and reduces the likelihood of a silent and nasty surprise.
   17.72 +	This behaviour is common to most Mercurial commands.</para>
   17.73 +
   17.74 +    </sect2>
   17.75 +    <sect2>
   17.76 +      <title>Aside: Mercurial tracks files, not directories</title>
   17.77 +
   17.78 +      <para id="x_1ab">Mercurial does not track directory information.  Instead,
   17.79 +	it tracks the path to a file.  Before creating a file, it
   17.80 +	first creates any missing directory components of the path.
   17.81 +	After it deletes a file, it then deletes any empty directories
   17.82 +	that were in the deleted file's path.  This sounds like a
   17.83 +	trivial distinction, but it has one minor practical
   17.84 +	consequence: it is not possible to represent a completely
   17.85 +	empty directory in Mercurial.</para>
   17.86 +
   17.87 +      <para id="x_1ac">Empty directories are rarely useful, and there are
   17.88 +	unintrusive workarounds that you can use to achieve an
   17.89 +	appropriate effect.  The developers of Mercurial thus felt
   17.90 +	that the complexity that would be required to manage empty
   17.91 +	directories was not worth the limited benefit this feature
   17.92 +	would bring.</para>
   17.93 +
   17.94 +      <para id="x_1ad">If you need an empty directory in your repository, there
   17.95 +	are a few ways to achieve this. One is to create a directory,
   17.96 +	then <command role="hg-cmd">hg add</command> a
   17.97 +	<quote>hidden</quote> file to that directory.  On Unix-like
   17.98 +	systems, any file name that begins with a period
   17.99 +	(<quote><literal>.</literal></quote>) is treated as hidden by
  17.100 +	most commands and GUI tools.  This approach is illustrated
  17.101 +	below.</para>
  17.102 +
  17.103 +&interaction.daily.files.hidden;
  17.104 +
  17.105 +      <para id="x_1ae">Another way to tackle a need for an empty directory is to
  17.106 +	simply create one in your automated build scripts before they
  17.107 +	will need it.</para>
  17.108 +
  17.109 +    </sect2>
  17.110 +  </sect1>
  17.111 +  <sect1>
  17.112 +    <title>How to stop tracking a file</title>
  17.113 +
  17.114 +    <para id="x_1af">Once you decide that a file no longer belongs in your
  17.115 +      repository, use the <command role="hg-cmd">hg remove</command>
  17.116 +      command; this deletes the file, and tells Mercurial to stop
  17.117 +      tracking it.  A removed file is represented in the output of
  17.118 +      <command role="hg-cmd">hg status</command> with a
  17.119 +      <quote><literal>R</literal></quote>.</para>
  17.120 +
  17.121 +    &interaction.daily.files.remove;
  17.122 +
  17.123 +    <para id="x_1b0">After you <command role="hg-cmd">hg remove</command> a file,
  17.124 +      Mercurial will no longer track changes to that file, even if you
  17.125 +      recreate a file with the same name in your working directory.
  17.126 +      If you do recreate a file with the same name and want Mercurial
  17.127 +      to track the new file, simply <command role="hg-cmd">hg
  17.128 +	add</command> it. Mercurial will know that the newly added
  17.129 +      file is not related to the old file of the same name.</para>
  17.130 +
  17.131 +    <sect2>
  17.132 +      <title>Removing a file does not affect its history</title>
  17.133 +
  17.134 +      <para id="x_1b1">It is important to understand that removing a file has
  17.135 +	only two effects.</para>
  17.136 +      <itemizedlist>
  17.137 +	<listitem><para id="x_1b2">It removes the current version of the file
  17.138 +	    from the working directory.</para>
  17.139 +	</listitem>
  17.140 +	<listitem><para id="x_1b3">It stops Mercurial from tracking changes to
  17.141 +	    the file, from the time of the next commit.</para>
  17.142 +	</listitem></itemizedlist>
  17.143 +      <para id="x_1b4">Removing a file <emphasis>does not</emphasis> in any way
  17.144 +	alter the <emphasis>history</emphasis> of the file.</para>
  17.145 +
  17.146 +      <para id="x_1b5">If you update the working directory to a changeset in
  17.147 +	which a file that you have removed was still tracked, it will
  17.148 +	reappear in the working directory, with the contents it had
  17.149 +	when you committed that changeset.  If you then update the
  17.150 +	working directory to a later changeset, in which the file had
  17.151 +	been removed, Mercurial will once again remove the file from
  17.152 +	the working directory.</para>
  17.153 +
  17.154 +    </sect2>
  17.155 +    <sect2>
  17.156 +      <title>Missing files</title>
  17.157 +
  17.158 +      <para id="x_1b6">Mercurial considers a file that you have deleted, but not
  17.159 +	used <command role="hg-cmd">hg remove</command> to delete, to
  17.160 +	be <emphasis>missing</emphasis>.  A missing file is
  17.161 +	represented with <quote><literal>!</literal></quote> in the
  17.162 +	output of <command role="hg-cmd">hg status</command>.
  17.163 +	Mercurial commands will not generally do anything with missing
  17.164 +	files.</para>
  17.165 +
  17.166 +      &interaction.daily.files.missing;
  17.167 +
  17.168 +      <para id="x_1b7">If your repository contains a file that <command
  17.169 +	  role="hg-cmd">hg status</command> reports as missing, and
  17.170 +	you want the file to stay gone, you can run <command
  17.171 +	  role="hg-cmd">hg remove <option
  17.172 +	    role="hg-opt-remove">--after</option></command> at any
  17.173 +	time later on, to tell Mercurial that you really did mean to
  17.174 +	remove the file.</para>
  17.175 +
  17.176 +      &interaction.daily.files.remove-after;
  17.177 +
  17.178 +      <para id="x_1b8">On the other hand, if you deleted the missing file by
  17.179 +	accident, give <command role="hg-cmd">hg revert</command> the
  17.180 +	name of the file to recover.  It will reappear, in unmodified
  17.181 +	form.</para>
  17.182 +
  17.183 +&interaction.daily.files.recover-missing;
  17.184 +
  17.185 +    </sect2>
  17.186 +    <sect2>
  17.187 +      <title>Aside: why tell Mercurial explicitly to remove a
  17.188 +	file?</title>
  17.189 +
  17.190 +      <para id="x_1b9">You might wonder why Mercurial requires you to explicitly
  17.191 +	tell it that you are deleting a file.  Early during the
  17.192 +	development of Mercurial, it let you delete a file however you
  17.193 +	pleased; Mercurial would notice the absence of the file
  17.194 +	automatically when you next ran a <command role="hg-cmd">hg
  17.195 +	  commit</command>, and stop tracking the file.  In practice,
  17.196 +	this made it too easy to accidentally remove a file without
  17.197 +	noticing.</para>
  17.198 +
  17.199 +    </sect2>
  17.200 +    <sect2>
  17.201 +      <title>Useful shorthand&emdash;adding and removing files in one
  17.202 +	step</title>
  17.203 +
  17.204 +      <para id="x_1ba">Mercurial offers a combination command, <command
  17.205 +	  role="hg-cmd">hg addremove</command>, that adds untracked
  17.206 +	files and marks missing files as removed.</para>
  17.207 +
  17.208 +      &interaction.daily.files.addremove;
  17.209 +
  17.210 +      <para id="x_1bb">The <command role="hg-cmd">hg commit</command> command
  17.211 +	also provides a <option role="hg-opt-commit">-A</option>
  17.212 +	option that performs this same add-and-remove, immediately
  17.213 +	followed by a commit.</para>
  17.214 +
  17.215 +      &interaction.daily.files.commit-addremove;
  17.216 +
  17.217 +    </sect2>
  17.218 +  </sect1>
  17.219 +  <sect1>
  17.220 +    <title>Copying files</title>
  17.221 +
  17.222 +    <para id="x_1bc">Mercurial provides a <command role="hg-cmd">hg
  17.223 +	copy</command> command that lets you make a new copy of a
  17.224 +      file.  When you copy a file using this command, Mercurial makes
  17.225 +      a record of the fact that the new file is a copy of the original
  17.226 +      file.  It treats these copied files specially when you merge
  17.227 +      your work with someone else's.</para>
  17.228 +
  17.229 +    <sect2>
  17.230 +      <title>The results of copying during a merge</title>
  17.231 +
  17.232 +      <para id="x_1bd">What happens during a merge is that changes
  17.233 +	<quote>follow</quote> a copy.  To best illustrate what this
  17.234 +	means, let's create an example.  We'll start with the usual
  17.235 +	tiny repository that contains a single file.</para>
  17.236 +
  17.237 +      &interaction.daily.copy.init;
  17.238 +
  17.239 +      <para id="x_1be">We need to do some work in
  17.240 +	parallel, so that we'll have something to merge.  So let's
  17.241 +	clone our repository.</para>
  17.242 +
  17.243 +      &interaction.daily.copy.clone;
  17.244 +
  17.245 +      <para id="x_1bf">Back in our initial repository, let's use the <command
  17.246 +	  role="hg-cmd">hg copy</command> command to make a copy of
  17.247 +	the first file we created.</para>
  17.248 +
  17.249 +      &interaction.daily.copy.copy;
  17.250 +
  17.251 +      <para id="x_1c0">If we look at the output of the <command role="hg-cmd">hg
  17.252 +	  status</command> command afterwards, the copied file looks
  17.253 +	just like a normal added file.</para>
  17.254 +
  17.255 +      &interaction.daily.copy.status;
  17.256 +
  17.257 +      <para id="x_1c1">But if we pass the <option
  17.258 +	  role="hg-opt-status">-C</option> option to <command
  17.259 +	  role="hg-cmd">hg status</command>, it prints another line of
  17.260 +	output: this is the file that our newly-added file was copied
  17.261 +	<emphasis>from</emphasis>.</para>
  17.262 +
  17.263 +      &interaction.daily.copy.status-copy;
  17.264 +
  17.265 +      <para id="x_1c2">Now, back in the repository we cloned, let's make a change
  17.266 +	in parallel.  We'll add a line of content to the original file
  17.267 +	that we created.</para>
  17.268 +
  17.269 +      &interaction.daily.copy.other;
  17.270 +
  17.271 +      <para id="x_1c3">Now we have a modified <filename>file</filename> in this
  17.272 +	repository.  When we pull the changes from the first
  17.273 +	repository, and merge the two heads, Mercurial will propagate
  17.274 +	the changes that we made locally to <filename>file</filename>
  17.275 +	into its copy, <filename>new-file</filename>.</para>
  17.276 +
  17.277 +      &interaction.daily.copy.merge;
  17.278 +
  17.279 +    </sect2>
  17.280 +    <sect2 id="sec.daily.why-copy">
  17.281 +      <title>Why should changes follow copies?</title>
  17.282 +
  17.283 +      <para id="x_1c4">This behaviour, of changes to a file propagating out to
  17.284 +	copies of the file, might seem esoteric, but in most cases
  17.285 +	it's highly desirable.</para>
  17.286 +
  17.287 +      <para id="x_1c5">First of all, remember that this propagation
  17.288 +	<emphasis>only</emphasis> happens when you merge.  So if you
  17.289 +	<command role="hg-cmd">hg copy</command> a file, and
  17.290 +	subsequently modify the original file during the normal course
  17.291 +	of your work, nothing will happen.</para>
  17.292 +
  17.293 +      <para id="x_1c6">The second thing to know is that modifications will only
  17.294 +	propagate across a copy as long as the repository that you're
  17.295 +	pulling changes from <emphasis>doesn't know</emphasis> about
  17.296 +	the copy.</para>
  17.297 +
  17.298 +      <para id="x_1c7">The reason that Mercurial does this is as follows.  Let's
  17.299 +	say I make an important bug fix in a source file, and commit
  17.300 +	my changes. Meanwhile, you've decided to <command
  17.301 +	  role="hg-cmd">hg copy</command> the file in your repository,
  17.302 +	without knowing about the bug or having seen the fix, and you
  17.303 +	have started hacking on your copy of the file.</para>
  17.304 +
  17.305 +      <para id="x_1c8">If you pulled and merged my changes, and Mercurial
  17.306 +	<emphasis>didn't</emphasis> propagate changes across copies,
  17.307 +	your source file would now contain the bug, and unless you
  17.308 +	remembered to propagate the bug fix by hand, the bug would
  17.309 +	<emphasis>remain</emphasis> in your copy of the file.</para>
  17.310 +
  17.311 +      <para id="x_1c9">By automatically propagating the change that fixed the bug
  17.312 +	from the original file to the copy, Mercurial prevents this
  17.313 +	class of problem. To my knowledge, Mercurial is the
  17.314 +	<emphasis>only</emphasis> revision control system that
  17.315 +	propagates changes across copies like this.</para>
  17.316 +
  17.317 +      <para id="x_1ca">Once your change history has a record that the copy and
  17.318 +	subsequent merge occurred, there's usually no further need to
  17.319 +	propagate changes from the original file to the copied file,
  17.320 +	and that's why Mercurial only propagates changes across copies
  17.321 +	until this point, and no further.</para>
  17.322 +
  17.323 +    </sect2>
  17.324 +    <sect2>
  17.325 +      <title>How to make changes <emphasis>not</emphasis> follow a
  17.326 +	copy</title>
  17.327 +
  17.328 +      <para id="x_1cb">If, for some reason, you decide that this business of
  17.329 +	automatically propagating changes across copies is not for
  17.330 +	you, simply use your system's normal file copy command (on
  17.331 +	Unix-like systems, that's <command>cp</command>) to make a
  17.332 +	copy of a file, then <command role="hg-cmd">hg add</command>
  17.333 +	the new copy by hand.  Before you do so, though, please do
  17.334 +	reread section <xref linkend="sec.daily.why-copy"/>, and make
  17.335 +	an informed
  17.336 +	decision that this behaviour is not appropriate to your
  17.337 +	specific case.</para>
  17.338 +
  17.339 +    </sect2>
  17.340 +    <sect2>
  17.341 +      <title>Behaviour of the <command role="hg-cmd">hg copy</command>
  17.342 +	command</title>
  17.343 +
  17.344 +      <para id="x_1cc">When you use the <command role="hg-cmd">hg copy</command>
  17.345 +	command, Mercurial makes a copy of each source file as it
  17.346 +	currently stands in the working directory.  This means that if
  17.347 +	you make some modifications to a file, then <command
  17.348 +	  role="hg-cmd">hg copy</command> it without first having
  17.349 +	committed those changes, the new copy will also contain the
  17.350 +	modifications you have made up until that point.  (I find this
  17.351 +	behaviour a little counterintuitive, which is why I mention it
  17.352 +	here.)</para>
  17.353 +
  17.354 +      <para id="x_1cd">The <command role="hg-cmd">hg copy</command> command acts
  17.355 +	similarly to the Unix <command>cp</command> command (you can
  17.356 +	use the <command role="hg-cmd">hg cp</command> alias if you
  17.357 +	prefer).  The last argument is the
  17.358 +	<emphasis>destination</emphasis>, and all prior arguments are
  17.359 +	<emphasis>sources</emphasis>.  If you pass it a single file as
  17.360 +	the source, and the destination does not exist, it creates a
  17.361 +	new file with that name.</para>
  17.362 +
  17.363 +      &interaction.daily.copy.simple;
  17.364 +      
  17.365 +      <para id="x_1ce">If the destination is a directory, Mercurial copies its
  17.366 +	sources into that directory.</para>
  17.367 +
  17.368 +      &interaction.daily.copy.dir-dest;
  17.369 +
  17.370 +      <para id="x_1cf">Copying a directory is
  17.371 +	recursive, and preserves the directory structure of the
  17.372 +	source.</para>
  17.373 +
  17.374 +      &interaction.daily.copy.dir-src;
  17.375 +
  17.376 +      <para id="x_1d0">If the source and destination are both directories, the
  17.377 +	source tree is recreated in the destination directory.</para>
  17.378 +
  17.379 +	&interaction.daily.copy.dir-src-dest;
  17.380 +
  17.381 +      <para id="x_1d1">As with the <command role="hg-cmd">hg rename</command>
  17.382 +	command, if you copy a file manually and then want Mercurial
  17.383 +	to know that you've copied the file, simply use the <option
  17.384 +	  role="hg-opt-copy">--after</option> option to <command
  17.385 +	  role="hg-cmd">hg copy</command>.</para>
  17.386 +
  17.387 +      &interaction.daily.copy.after;
  17.388 +
  17.389 +    </sect2>
  17.390 +  </sect1>
  17.391 +  <sect1>
  17.392 +    <title>Renaming files</title>
  17.393 +
  17.394 +    <para id="x_1d2">It's rather more common to need to rename a file than to
  17.395 +      make a copy of it.  The reason I discussed the <command
  17.396 +	role="hg-cmd">hg copy</command> command before talking about
  17.397 +      renaming files is that Mercurial treats a rename in essentially
  17.398 +      the same way as a copy.  Therefore, knowing what Mercurial does
  17.399 +      when you copy a file tells you what to expect when you rename a
  17.400 +      file.</para>
  17.401 +
  17.402 +    <para id="x_1d3">When you use the <command role="hg-cmd">hg rename</command>
  17.403 +      command, Mercurial makes a copy of each source file, then
  17.404 +      deletes it and marks the file as removed.</para>
  17.405 +
  17.406 +      &interaction.daily.rename.rename;
  17.407 +
  17.408 +    <para id="x_1d4">The <command role="hg-cmd">hg status</command> command shows
  17.409 +      the newly copied file as added, and the copied-from file as
  17.410 +      removed.</para>
  17.411 +
  17.412 +    &interaction.daily.rename.status;
  17.413 +
  17.414 +    <para id="x_1d5">As with the results of a <command role="hg-cmd">hg
  17.415 +	copy</command>, we must use the <option
  17.416 +	role="hg-opt-status">-C</option> option to <command
  17.417 +	role="hg-cmd">hg status</command> to see that the added file
  17.418 +      is really being tracked by Mercurial as a copy of the original,
  17.419 +      now removed, file.</para>
  17.420 +
  17.421 +    &interaction.daily.rename.status-copy;
  17.422 +
  17.423 +    <para id="x_1d6">As with <command role="hg-cmd">hg remove</command> and
  17.424 +      <command role="hg-cmd">hg copy</command>, you can tell Mercurial
  17.425 +      about a rename after the fact using the <option
  17.426 +	role="hg-opt-rename">--after</option> option.  In most other
  17.427 +      respects, the behaviour of the <command role="hg-cmd">hg
  17.428 +	rename</command> command, and the options it accepts, are
  17.429 +      similar to the <command role="hg-cmd">hg copy</command>
  17.430 +      command.</para>
  17.431 +
  17.432 +    <sect2>
  17.433 +      <title>Renaming files and merging changes</title>
  17.434 +
  17.435 +      <para id="x_1d7">Since Mercurial's rename is implemented as
  17.436 +	copy-and-remove, the same propagation of changes happens when
  17.437 +	you merge after a rename as after a copy.</para>
  17.438 +
  17.439 +      <para id="x_1d8">If I modify a file, and you rename it to a new name, and
  17.440 +	then we merge our respective changes, my modifications to the
  17.441 +	file under its original name will be propagated into the file
  17.442 +	under its new name. (This is something you might expect to
  17.443 +	<quote>simply work,</quote> but not all revision control
  17.444 +	systems actually do this.)</para>
  17.445 +
  17.446 +      <para id="x_1d9">Whereas having changes follow a copy is a feature where
  17.447 +	you can perhaps nod and say <quote>yes, that might be
  17.448 +	  useful,</quote> it should be clear that having them follow a
  17.449 +	rename is definitely important.  Without this facility, it
  17.450 +	would simply be too easy for changes to become orphaned when
  17.451 +	files are renamed.</para>
  17.452 +
  17.453 +    </sect2>
  17.454 +    <sect2>
  17.455 +      <title>Divergent renames and merging</title>
  17.456 +
  17.457 +      <para id="x_1da">The case of diverging names occurs when two developers
  17.458 +	start with a file&emdash;let's call it
  17.459 +	<filename>foo</filename>&emdash;in their respective
  17.460 +	repositories.</para>
  17.461 +
  17.462 +      &interaction.rename.divergent.clone;
  17.463 +
  17.464 +      <para id="x_1db">Anne renames the file to <filename>bar</filename>.</para>
  17.465 +
  17.466 +      &interaction.rename.divergent.rename.anne;
  17.467 +
  17.468 +      <para id="x_1dc">Meanwhile, Bob renames it to
  17.469 +	<filename>quux</filename>.</para>
  17.470 +
  17.471 +	&interaction.rename.divergent.rename.bob;
  17.472 +
  17.473 +      <para id="x_1dd">I like to think of this as a conflict because each
  17.474 +	developer has expressed different intentions about what the
  17.475 +	file ought to be named.</para>
  17.476 +
  17.477 +      <para id="x_1de">What do you think should happen when they merge their
  17.478 +	work? Mercurial's actual behaviour is that it always preserves
  17.479 +	<emphasis>both</emphasis> names when it merges changesets that
  17.480 +	contain divergent renames.</para>
  17.481 +
  17.482 +      &interaction.rename.divergent.merge;
  17.483 +
  17.484 +      <para id="x_1df">Notice that Mercurial does warn about the divergent
  17.485 +	renames, but it leaves it up to you to do something about the
  17.486 +	divergence after the merge.</para>
  17.487 +
  17.488 +    </sect2>
  17.489 +    <sect2>
  17.490 +      <title>Convergent renames and merging</title>
  17.491 +
  17.492 +      <para id="x_1e0">Another kind of rename conflict occurs when two people
  17.493 +	choose to rename different <emphasis>source</emphasis> files
  17.494 +	to the same <emphasis>destination</emphasis>. In this case,
  17.495 +	Mercurial runs its normal merge machinery, and lets you guide
  17.496 +	it to a suitable resolution.</para>
  17.497 +
  17.498 +    </sect2>
  17.499 +    <sect2>
  17.500 +      <title>Other name-related corner cases</title>
  17.501 +
  17.502 +      <para id="x_1e1">Mercurial has a longstanding bug in which it fails to
  17.503 +	handle a merge where one side has a file with a given name,
  17.504 +	while another has a directory with the same name.  This is
  17.505 +	documented as <ulink role="hg-bug"
  17.506 +	  url="http://www.selenic.com/mercurial/bts/issue29">issue
  17.507 +	  29</ulink>.</para>
  17.508 +
  17.509 +      &interaction.issue29.go;
  17.510 +
  17.511 +    </sect2>
  17.512 +  </sect1>
  17.513 +  <sect1>
  17.514 +    <title>Recovering from mistakes</title>
  17.515 +
  17.516 +    <para id="x_1e2">Mercurial has some useful commands that will help you to
  17.517 +      recover from some common mistakes.</para>
  17.518 +
  17.519 +    <para id="x_1e3">The <command role="hg-cmd">hg revert</command> command lets
  17.520 +      you undo changes that you have made to your working directory.
  17.521 +      For example, if you <command role="hg-cmd">hg add</command> a
  17.522 +      file by accident, just run <command role="hg-cmd">hg
  17.523 +	revert</command> with the name of the file you added, and
  17.524 +      while the file won't be touched in any way, it won't be tracked
  17.525 +      for adding by Mercurial any longer, either.  You can also use
  17.526 +      <command role="hg-cmd">hg revert</command> to get rid of
  17.527 +      erroneous changes to a file.</para>
  17.528 +
  17.529 +    <para id="x_1e4">It's useful to remember that the <command role="hg-cmd">hg
  17.530 +	revert</command> command is useful for changes that you have
  17.531 +      not yet committed.  Once you've committed a change, if you
  17.532 +      decide it was a mistake, you can still do something about it,
  17.533 +      though your options may be more limited.</para>
  17.534 +
  17.535 +    <para id="x_1e5">For more information about the <command role="hg-cmd">hg
  17.536 +	revert</command> command, and details about how to deal with
  17.537 +      changes you have already committed, see chapter <xref
  17.538 +	linkend="chap.undo"/>.</para>
  17.539 +
  17.540 +  </sect1>
  17.541 +</chapter>
  17.542 +
  17.543 +<!--
  17.544 +local variables: 
  17.545 +sgml-parent-document: ("00book.xml" "book" "chapter")
  17.546 +end:
  17.547 +-->
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/en/ch05-collab.xml	Fri Mar 20 16:43:35 2009 +0800
    18.3 @@ -0,0 +1,1437 @@
    18.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    18.5 +
    18.6 +<chapter id="cha.collab">
    18.7 +  <?dbhtml filename="collaborating-with-other-people.html"?>
    18.8 +  <title>Collaborating with other people</title>
    18.9 +
   18.10 +  <para>As a completely decentralised tool, Mercurial doesn't impose
   18.11 +    any policy on how people ought to work with each other.  However,
   18.12 +    if you're new to distributed revision control, it helps to have
   18.13 +    some tools and examples in mind when you're thinking about
   18.14 +    possible workflow models.</para>
   18.15 +
   18.16 +  <sect1>
   18.17 +    <title>Mercurial's web interface</title>
   18.18 +
   18.19 +    <para>Mercurial has a powerful web interface that provides several
   18.20 +      useful capabilities.</para>
   18.21 +
   18.22 +    <para>For interactive use, the web interface lets you browse a
   18.23 +      single repository or a collection of repositories.  You can view
   18.24 +      the history of a repository, examine each change (comments and
   18.25 +      diffs), and view the contents of each directory and file.</para>
   18.26 +
   18.27 +    <para>Also for human consumption, the web interface provides an
   18.28 +      RSS feed of the changes in a repository.  This lets you
   18.29 +      <quote>subscribe</quote> to a repository using your favourite
   18.30 +      feed reader, and be automatically notified of activity in that
   18.31 +      repository as soon as it happens.  I find this capability much
   18.32 +      more convenient than the model of subscribing to a mailing list
   18.33 +      to which notifications are sent, as it requires no additional
   18.34 +      configuration on the part of whoever is serving the
   18.35 +      repository.</para>
   18.36 +
   18.37 +    <para>The web interface also lets remote users clone a repository,
   18.38 +      pull changes from it, and (when the server is configured to
   18.39 +      permit it) push changes back to it.  Mercurial's HTTP tunneling
   18.40 +      protocol aggressively compresses data, so that it works
   18.41 +      efficiently even over low-bandwidth network connections.</para>
   18.42 +
   18.43 +    <para>The easiest way to get started with the web interface is to
   18.44 +      use your web browser to visit an existing repository, such as
   18.45 +      the master Mercurial repository at <ulink
   18.46 +	url="http://www.selenic.com/repo/hg?style=gitweb">http://www.selenic.com/repo/hg?style=gitweb</ulink>.</para>
   18.47 +
   18.48 +    <para>If you're interested in providing a web interface to your
   18.49 +      own repositories, Mercurial provides two ways to do this.  The
   18.50 +      first is using the <command role="hg-cmd">hg serve</command>
   18.51 +      command, which is best suited to short-term
   18.52 +      <quote>lightweight</quote> serving.  See section <xref
   18.53 +	linkend="sec.collab.serve"/> below for details of how to use
   18.54 +      this command.  If you have a long-lived repository that you'd
   18.55 +      like to make permanently available, Mercurial has built-in
   18.56 +      support for the CGI (Common Gateway Interface) standard, which
   18.57 +      all common web servers support.  See section <xref
   18.58 +	linkend="sec.collab.cgi"/> for details of CGI
   18.59 +      configuration.</para>
   18.60 +
   18.61 +  </sect1>
   18.62 +  <sect1>
   18.63 +    <title>Collaboration models</title>
   18.64 +
   18.65 +    <para>With a suitably flexible tool, making decisions about
   18.66 +      workflow is much more of a social engineering challenge than a
   18.67 +      technical one. Mercurial imposes few limitations on how you can
   18.68 +      structure the flow of work in a project, so it's up to you and
   18.69 +      your group to set up and live with a model that matches your own
   18.70 +      particular needs.</para>
   18.71 +
   18.72 +    <sect2>
   18.73 +      <title>Factors to keep in mind</title>
   18.74 +
   18.75 +      <para>The most important aspect of any model that you must keep
   18.76 +	in mind is how well it matches the needs and capabilities of
   18.77 +	the people who will be using it.  This might seem
   18.78 +	self-evident; even so, you still can't afford to forget it for
   18.79 +	a moment.</para>
   18.80 +
   18.81 +      <para>I once put together a workflow model that seemed to make
   18.82 +	perfect sense to me, but that caused a considerable amount of
   18.83 +	consternation and strife within my development team.  In spite
   18.84 +	of my attempts to explain why we needed a complex set of
   18.85 +	branches, and how changes ought to flow between them, a few
   18.86 +	team members revolted.  Even though they were smart people,
   18.87 +	they didn't want to pay attention to the constraints we were
   18.88 +	operating under, or face the consequences of those constraints
   18.89 +	in the details of the model that I was advocating.</para>
   18.90 +
   18.91 +      <para>Don't sweep foreseeable social or technical problems under
   18.92 +	the rug. Whatever scheme you put into effect, you should plan
   18.93 +	for mistakes and problem scenarios.  Consider adding automated
   18.94 +	machinery to prevent, or quickly recover from, trouble that
   18.95 +	you can anticipate.  As an example, if you intend to have a
   18.96 +	branch with not-for-release changes in it, you'd do well to
   18.97 +	think early about the possibility that someone might
   18.98 +	accidentally merge those changes into a release branch.  You
   18.99 +	could avoid this particular problem by writing a hook that
  18.100 +	prevents changes from being merged from an inappropriate
  18.101 +	branch.</para>
  18.102 +
  18.103 +    </sect2>
  18.104 +    <sect2>
  18.105 +      <title>Informal anarchy</title>
  18.106 +
  18.107 +      <para>I wouldn't suggest an <quote>anything goes</quote>
  18.108 +	approach as something sustainable, but it's a model that's
  18.109 +	easy to grasp, and it works perfectly well in a few unusual
  18.110 +	situations.</para>
  18.111 +
  18.112 +      <para>As one example, many projects have a loose-knit group of
  18.113 +	collaborators who rarely physically meet each other.  Some
  18.114 +	groups like to overcome the isolation of working at a distance
  18.115 +	by organising occasional <quote>sprints</quote>.  In a sprint,
  18.116 +	a number of people get together in a single location (a
  18.117 +	company's conference room, a hotel meeting room, that kind of
  18.118 +	place) and spend several days more or less locked in there,
  18.119 +	hacking intensely on a handful of projects.</para>
  18.120 +
  18.121 +      <para>A sprint is the perfect place to use the <command
  18.122 +	  role="hg-cmd">hg serve</command> command, since <command
  18.123 +	  role="hg-cmd">hg serve</command> does not require any fancy
  18.124 +	server infrastructure.  You can get started with <command
  18.125 +	  role="hg-cmd">hg serve</command> in moments, by reading
  18.126 +	section <xref linkend="sec.collab.serve"/> below.  Then simply
  18.127 +	tell
  18.128 +	the person next to you that you're running a server, send the
  18.129 +	URL to them in an instant message, and you immediately have a
  18.130 +	quick-turnaround way to work together.  They can type your URL
  18.131 +	into their web browser and quickly review your changes; or
  18.132 +	they can pull a bugfix from you and verify it; or they can
  18.133 +	clone a branch containing a new feature and try it out.</para>
  18.134 +
  18.135 +      <para>The charm, and the problem, with doing things in an ad hoc
  18.136 +	fashion like this is that only people who know about your
  18.137 +	changes, and where they are, can see them.  Such an informal
  18.138 +	approach simply doesn't scale beyond a handful people, because
  18.139 +	each individual needs to know about $n$ different repositories
  18.140 +	to pull from.</para>
  18.141 +
  18.142 +    </sect2>
  18.143 +    <sect2>
  18.144 +      <title>A single central repository</title>
  18.145 +
  18.146 +      <para>For smaller projects migrating from a centralised revision
  18.147 +	control tool, perhaps the easiest way to get started is to
  18.148 +	have changes flow through a single shared central repository.
  18.149 +	This is also the most common <quote>building block</quote> for
  18.150 +	more ambitious workflow schemes.</para>
  18.151 +
  18.152 +      <para>Contributors start by cloning a copy of this repository.
  18.153 +	They can pull changes from it whenever they need to, and some
  18.154 +	(perhaps all) developers have permission to push a change back
  18.155 +	when they're ready for other people to see it.</para>
  18.156 +
  18.157 +      <para>Under this model, it can still often make sense for people
  18.158 +	to pull changes directly from each other, without going
  18.159 +	through the central repository.  Consider a case in which I
  18.160 +	have a tentative bug fix, but I am worried that if I were to
  18.161 +	publish it to the central repository, it might subsequently
  18.162 +	break everyone else's trees as they pull it.  To reduce the
  18.163 +	potential for damage, I can ask you to clone my repository
  18.164 +	into a temporary repository of your own and test it.  This
  18.165 +	lets us put off publishing the potentially unsafe change until
  18.166 +	it has had a little testing.</para>
  18.167 +
  18.168 +      <para>In this kind of scenario, people usually use the
  18.169 +	<command>ssh</command> protocol to securely push changes to
  18.170 +	the central repository, as documented in section <xref
  18.171 +	  linkend="sec.collab.ssh"/>.  It's also
  18.172 +	usual to publish a read-only copy of the repository over HTTP
  18.173 +	using CGI, as in section <xref linkend="sec.collab.cgi"/>.
  18.174 +	Publishing over HTTP
  18.175 +	satisfies the needs of people who don't have push access, and
  18.176 +	those who want to use web browsers to browse the repository's
  18.177 +	history.</para>
  18.178 +
  18.179 +    </sect2>
  18.180 +    <sect2>
  18.181 +      <title>Working with multiple branches</title>
  18.182 +
  18.183 +      <para>Projects of any significant size naturally tend to make
  18.184 +	progress on several fronts simultaneously.  In the case of
  18.185 +	software, it's common for a project to go through periodic
  18.186 +	official releases.  A release might then go into
  18.187 +	<quote>maintenance mode</quote> for a while after its first
  18.188 +	publication; maintenance releases tend to contain only bug
  18.189 +	fixes, not new features.  In parallel with these maintenance
  18.190 +	releases, one or more future releases may be under
  18.191 +	development.  People normally use the word
  18.192 +	<quote>branch</quote> to refer to one of these many slightly
  18.193 +	different directions in which development is
  18.194 +	proceeding.</para>
  18.195 +
  18.196 +      <para>Mercurial is particularly well suited to managing a number
  18.197 +	of simultaneous, but not identical, branches.  Each
  18.198 +	<quote>development direction</quote> can live in its own
  18.199 +	central repository, and you can merge changes from one to
  18.200 +	another as the need arises.  Because repositories are
  18.201 +	independent of each other, unstable changes in a development
  18.202 +	branch will never affect a stable branch unless someone
  18.203 +	explicitly merges those changes in.</para>
  18.204 +
  18.205 +      <para>Here's an example of how this can work in practice.  Let's
  18.206 +	say you have one <quote>main branch</quote> on a central
  18.207 +	server.</para>
  18.208 +
  18.209 +      &interaction.branching.init;
  18.210 +
  18.211 +      <para>People clone it, make changes locally, test them, and push
  18.212 +	them back.</para>
  18.213 +
  18.214 +      <para>Once the main branch reaches a release milestone, you can
  18.215 +	use the <command role="hg-cmd">hg tag</command> command to
  18.216 +	give a permanent name to the milestone revision.</para>
  18.217 +
  18.218 +	&interaction.branching.tag;
  18.219 +
  18.220 +      <para>Let's say some ongoing
  18.221 +	development occurs on the main branch.</para>
  18.222 +
  18.223 +      &interaction.branching.main;
  18.224 +
  18.225 +      <para>Using the tag that was recorded at the milestone, people
  18.226 +	who clone that repository at any time in the future can use
  18.227 +	<command role="hg-cmd">hg update</command> to get a copy of
  18.228 +	the working directory exactly as it was when that tagged
  18.229 +	revision was committed.</para>
  18.230 +
  18.231 +      &interaction.branching.update;
  18.232 +
  18.233 +      <para>In addition, immediately after the main branch is tagged,
  18.234 +	someone can then clone the main branch on the server to a new
  18.235 +	<quote>stable</quote> branch, also on the server.</para>
  18.236 +
  18.237 +      &interaction.branching.clone;
  18.238 +
  18.239 +      <para>Someone who needs to make a change to the stable branch
  18.240 +	can then clone <emphasis>that</emphasis> repository, make
  18.241 +	their changes, commit, and push their changes back there.</para>
  18.242 +
  18.243 +      &interaction.branching.stable;
  18.244 +
  18.245 +      <para>Because Mercurial repositories are independent, and
  18.246 +	Mercurial doesn't move changes around automatically, the
  18.247 +	stable and main branches are <emphasis>isolated</emphasis>
  18.248 +	from each other.  The changes that you made on the main branch
  18.249 +	don't <quote>leak</quote> to the stable branch, and vice
  18.250 +	versa.</para>
  18.251 +
  18.252 +      <para>You'll often want all of your bugfixes on the stable
  18.253 +	branch to show up on the main branch, too.  Rather than
  18.254 +	rewrite a bugfix on the main branch, you can simply pull and
  18.255 +	merge changes from the stable to the main branch, and
  18.256 +	Mercurial will bring those bugfixes in for you.</para>
  18.257 +
  18.258 +	&interaction.branching.merge;
  18.259 +
  18.260 +      <para>The main branch will still contain changes that are not on
  18.261 +	the stable branch, but it will also contain all of the
  18.262 +	bugfixes from the stable branch.  The stable branch remains
  18.263 +	unaffected by these changes.</para>
  18.264 +
  18.265 +    </sect2>
  18.266 +    <sect2>
  18.267 +      <title>Feature branches</title>
  18.268 +
  18.269 +      <para>For larger projects, an effective way to manage change is
  18.270 +	to break up a team into smaller groups.  Each group has a
  18.271 +	shared branch of its own, cloned from a single
  18.272 +	<quote>master</quote> branch used by the entire project.
  18.273 +	People working on an individual branch are typically quite
  18.274 +	isolated from developments on other branches.</para>
  18.275 +
  18.276 +      <informalfigure id="fig.collab.feature-branches">
  18.277 +        <mediaobject>
  18.278 +          <imageobject><imagedata fileref="images/feature-branches.png"/>
  18.279 +          </imageobject>
  18.280 +          <textobject><phrase>XXX add text</phrase></textobject>
  18.281 +          <caption><para id="fig.collab.feature-branches.caption">Feature
  18.282 +            branches</para></caption>
  18.283 +        </mediaobject>
  18.284 +      </informalfigure>
  18.285 +
  18.286 +      <para>When a particular feature is deemed to be in suitable
  18.287 +	shape, someone on that feature team pulls and merges from the
  18.288 +	master branch into the feature branch, then pushes back up to
  18.289 +	the master branch.</para>
  18.290 +
  18.291 +    </sect2>
  18.292 +    <sect2>
  18.293 +      <title>The release train</title>
  18.294 +
  18.295 +      <para>Some projects are organised on a <quote>train</quote>
  18.296 +	basis: a release is scheduled to happen every few months, and
  18.297 +	whatever features are ready when the <quote>train</quote> is
  18.298 +	ready to leave are allowed in.</para>
  18.299 +
  18.300 +      <para>This model resembles working with feature branches.  The
  18.301 +	difference is that when a feature branch misses a train,
  18.302 +	someone on the feature team pulls and merges the changes that
  18.303 +	went out on that train release into the feature branch, and
  18.304 +	the team continues its work on top of that release so that
  18.305 +	their feature can make the next release.</para>
  18.306 +
  18.307 +    </sect2>
  18.308 +    <sect2>
  18.309 +      <title>The Linux kernel model</title>
  18.310 +
  18.311 +      <para>The development of the Linux kernel has a shallow
  18.312 +	hierarchical structure, surrounded by a cloud of apparent
  18.313 +	chaos.  Because most Linux developers use
  18.314 +	<command>git</command>, a distributed revision control tool
  18.315 +	with capabilities similar to Mercurial, it's useful to
  18.316 +	describe the way work flows in that environment; if you like
  18.317 +	the ideas, the approach translates well across tools.</para>
  18.318 +
  18.319 +      <para>At the center of the community sits Linus Torvalds, the
  18.320 +	creator of Linux.  He publishes a single source repository
  18.321 +	that is considered the <quote>authoritative</quote> current
  18.322 +	tree by the entire developer community. Anyone can clone
  18.323 +	Linus's tree, but he is very choosy about whose trees he pulls
  18.324 +	from.</para>
  18.325 +
  18.326 +      <para>Linus has a number of <quote>trusted lieutenants</quote>.
  18.327 +	As a general rule, he pulls whatever changes they publish, in
  18.328 +	most cases without even reviewing those changes.  Some of
  18.329 +	those lieutenants are generally agreed to be
  18.330 +	<quote>maintainers</quote>, responsible for specific
  18.331 +	subsystems within the kernel.  If a random kernel hacker wants
  18.332 +	to make a change to a subsystem that they want to end up in
  18.333 +	Linus's tree, they must find out who the subsystem's
  18.334 +	maintainer is, and ask that maintainer to take their change.
  18.335 +	If the maintainer reviews their changes and agrees to take
  18.336 +	them, they'll pass them along to Linus in due course.</para>
  18.337 +
  18.338 +      <para>Individual lieutenants have their own approaches to
  18.339 +	reviewing, accepting, and publishing changes; and for deciding
  18.340 +	when to feed them to Linus.  In addition, there are several
  18.341 +	well known branches that people use for different purposes.
  18.342 +	For example, a few people maintain <quote>stable</quote>
  18.343 +	repositories of older versions of the kernel, to which they
  18.344 +	apply critical fixes as needed.  Some maintainers publish
  18.345 +	multiple trees: one for experimental changes; one for changes
  18.346 +	that they are about to feed upstream; and so on.  Others just
  18.347 +	publish a single tree.</para>
  18.348 +
  18.349 +      <para>This model has two notable features.  The first is that
  18.350 +	it's <quote>pull only</quote>.  You have to ask, convince, or
  18.351 +	beg another developer to take a change from you, because there
  18.352 +	are almost no trees to which more than one person can push,
  18.353 +	and there's no way to push changes into a tree that someone
  18.354 +	else controls.</para>
  18.355 +
  18.356 +      <para>The second is that it's based on reputation and acclaim.
  18.357 +	If you're an unknown, Linus will probably ignore changes from
  18.358 +	you without even responding.  But a subsystem maintainer will
  18.359 +	probably review them, and will likely take them if they pass
  18.360 +	their criteria for suitability. The more <quote>good</quote>
  18.361 +	changes you contribute to a maintainer, the more likely they
  18.362 +	are to trust your judgment and accept your changes.  If you're
  18.363 +	well-known and maintain a long-lived branch for something
  18.364 +	Linus hasn't yet accepted, people with similar interests may
  18.365 +	pull your changes regularly to keep up with your work.</para>
  18.366 +
  18.367 +      <para>Reputation and acclaim don't necessarily cross subsystem
  18.368 +	or <quote>people</quote> boundaries.  If you're a respected
  18.369 +	but specialised storage hacker, and you try to fix a
  18.370 +	networking bug, that change will receive a level of scrutiny
  18.371 +	from a network maintainer comparable to a change from a
  18.372 +	complete stranger.</para>
  18.373 +
  18.374 +      <para>To people who come from more orderly project backgrounds,
  18.375 +	the comparatively chaotic Linux kernel development process
  18.376 +	often seems completely insane.  It's subject to the whims of
  18.377 +	individuals; people make sweeping changes whenever they deem
  18.378 +	it appropriate; and the pace of development is astounding.
  18.379 +	And yet Linux is a highly successful, well-regarded piece of
  18.380 +	software.</para>
  18.381 +
  18.382 +    </sect2>
  18.383 +    <sect2>
  18.384 +      <title>Pull-only versus shared-push collaboration</title>
  18.385 +
  18.386 +      <para>A perpetual source of heat in the open source community is
  18.387 +	whether a development model in which people only ever pull
  18.388 +	changes from others is <quote>better than</quote> one in which
  18.389 +	multiple people can push changes to a shared
  18.390 +	repository.</para>
  18.391 +
  18.392 +      <para>Typically, the backers of the shared-push model use tools
  18.393 +	that actively enforce this approach.  If you're using a
  18.394 +	centralised revision control tool such as Subversion, there's
  18.395 +	no way to make a choice over which model you'll use: the tool
  18.396 +	gives you shared-push, and if you want to do anything else,
  18.397 +	you'll have to roll your own approach on top (such as applying
  18.398 +	a patch by hand).</para>
  18.399 +
  18.400 +      <para>A good distributed revision control tool, such as
  18.401 +	Mercurial, will support both models.  You and your
  18.402 +	collaborators can then structure how you work together based
  18.403 +	on your own needs and preferences, not on what contortions
  18.404 +	your tools force you into.</para>
  18.405 +
  18.406 +    </sect2>
  18.407 +    <sect2>
  18.408 +      <title>Where collaboration meets branch management</title>
  18.409 +
  18.410 +      <para>Once you and your team set up some shared repositories and
  18.411 +	start propagating changes back and forth between local and
  18.412 +	shared repos, you begin to face a related, but slightly
  18.413 +	different challenge: that of managing the multiple directions
  18.414 +	in which your team may be moving at once.  Even though this
  18.415 +	subject is intimately related to how your team collaborates,
  18.416 +	it's dense enough to merit treatment of its own, in chapter
  18.417 +	<xref linkend="chap.branch"/>.</para>
  18.418 +
  18.419 +    </sect2>
  18.420 +  </sect1>
  18.421 +  <sect1>
  18.422 +    <title>The technical side of sharing</title>
  18.423 +
  18.424 +    <para>The remainder of this chapter is devoted to the question of
  18.425 +      serving data to your collaborators.</para>
  18.426 +
  18.427 +  </sect1>
  18.428 +  <sect1 id="sec.collab.serve">
  18.429 +    <title>Informal sharing with <command role="hg-cmd">hg
  18.430 +	serve</command></title>
  18.431 +
  18.432 +    <para>Mercurial's <command role="hg-cmd">hg serve</command>
  18.433 +      command is wonderfully suited to small, tight-knit, and
  18.434 +      fast-paced group environments.  It also provides a great way to
  18.435 +      get a feel for using Mercurial commands over a network.</para>
  18.436 +
  18.437 +    <para>Run <command role="hg-cmd">hg serve</command> inside a
  18.438 +      repository, and in under a second it will bring up a specialised
  18.439 +      HTTP server; this will accept connections from any client, and
  18.440 +      serve up data for that repository until you terminate it.
  18.441 +      Anyone who knows the URL of the server you just started, and can
  18.442 +      talk to your computer over the network, can then use a web
  18.443 +      browser or Mercurial to read data from that repository.  A URL
  18.444 +      for a <command role="hg-cmd">hg serve</command> instance running
  18.445 +      on a laptop is likely to look something like
  18.446 +      <literal>http://my-laptop.local:8000/</literal>.</para>
  18.447 +
  18.448 +    <para>The <command role="hg-cmd">hg serve</command> command is
  18.449 +      <emphasis>not</emphasis> a general-purpose web server. It can do
  18.450 +      only two things:</para>
  18.451 +    <itemizedlist>
  18.452 +      <listitem><para>Allow people to browse the history of the
  18.453 +	  repository it's serving, from their normal web
  18.454 +	  browsers.</para>
  18.455 +      </listitem>
  18.456 +      <listitem><para>Speak Mercurial's wire protocol, so that people
  18.457 +	  can <command role="hg-cmd">hg clone</command> or <command
  18.458 +	    role="hg-cmd">hg pull</command> changes from that
  18.459 +	  repository.</para>
  18.460 +      </listitem></itemizedlist>
  18.461 +    <para>In particular, <command role="hg-cmd">hg serve</command>
  18.462 +      won't allow remote users to <emphasis>modify</emphasis> your
  18.463 +      repository.  It's intended for read-only use.</para>
  18.464 +
  18.465 +    <para>If you're getting started with Mercurial, there's nothing to
  18.466 +      prevent you from using <command role="hg-cmd">hg serve</command>
  18.467 +      to serve up a repository on your own computer, then use commands
  18.468 +      like <command role="hg-cmd">hg clone</command>, <command
  18.469 +	role="hg-cmd">hg incoming</command>, and so on to talk to that
  18.470 +      server as if the repository was hosted remotely. This can help
  18.471 +      you to quickly get acquainted with using commands on
  18.472 +      network-hosted repositories.</para>
  18.473 +
  18.474 +    <sect2>
  18.475 +      <title>A few things to keep in mind</title>
  18.476 +
  18.477 +      <para>Because it provides unauthenticated read access to all
  18.478 +	clients, you should only use <command role="hg-cmd">hg
  18.479 +	  serve</command> in an environment where you either don't
  18.480 +	care, or have complete control over, who can access your
  18.481 +	network and pull data from your repository.</para>
  18.482 +
  18.483 +      <para>The <command role="hg-cmd">hg serve</command> command
  18.484 +	knows nothing about any firewall software you might have
  18.485 +	installed on your system or network.  It cannot detect or
  18.486 +	control your firewall software.  If other people are unable to
  18.487 +	talk to a running <command role="hg-cmd">hg serve</command>
  18.488 +	instance, the second thing you should do
  18.489 +	(<emphasis>after</emphasis> you make sure that they're using
  18.490 +	the correct URL) is check your firewall configuration.</para>
  18.491 +
  18.492 +      <para>By default, <command role="hg-cmd">hg serve</command>
  18.493 +	listens for incoming connections on port 8000.  If another
  18.494 +	process is already listening on the port you want to use, you
  18.495 +	can specify a different port to listen on using the <option
  18.496 +	  role="hg-opt-serve">-p</option> option.</para>
  18.497 +
  18.498 +      <para>Normally, when <command role="hg-cmd">hg serve</command>
  18.499 +	starts, it prints no output, which can be a bit unnerving.  If
  18.500 +	you'd like to confirm that it is indeed running correctly, and
  18.501 +	find out what URL you should send to your collaborators, start
  18.502 +	it with the <option role="hg-opt-global">-v</option>
  18.503 +	option.</para>
  18.504 +
  18.505 +    </sect2>
  18.506 +  </sect1>
  18.507 +  <sect1 id="sec.collab.ssh">
  18.508 +    <title>Using the Secure Shell (ssh) protocol</title>
  18.509 +
  18.510 +    <para>You can pull and push changes securely over a network
  18.511 +      connection using the Secure Shell (<literal>ssh</literal>)
  18.512 +      protocol.  To use this successfully, you may have to do a little
  18.513 +      bit of configuration on the client or server sides.</para>
  18.514 +
  18.515 +    <para>If you're not familiar with ssh, it's a network protocol
  18.516 +      that lets you securely communicate with another computer.  To
  18.517 +      use it with Mercurial, you'll be setting up one or more user
  18.518 +      accounts on a server so that remote users can log in and execute
  18.519 +      commands.</para>
  18.520 +
  18.521 +    <para>(If you <emphasis>are</emphasis> familiar with ssh, you'll
  18.522 +      probably find some of the material that follows to be elementary
  18.523 +      in nature.)</para>
  18.524 +
  18.525 +    <sect2>
  18.526 +      <title>How to read and write ssh URLs</title>
  18.527 +
  18.528 +      <para>An ssh URL tends to look like this:</para>
  18.529 +      <programlisting>ssh://bos@hg.serpentine.com:22/hg/hgbook</programlisting>
  18.530 +      <orderedlist>
  18.531 +	<listitem><para>The <quote><literal>ssh://</literal></quote>
  18.532 +	    part tells Mercurial to use the ssh protocol.</para>
  18.533 +	</listitem>
  18.534 +	<listitem><para>The <quote><literal>bos@</literal></quote>
  18.535 +	    component indicates what username to log into the server
  18.536 +	    as.  You can leave this out if the remote username is the
  18.537 +	    same as your local username.</para>
  18.538 +	</listitem>
  18.539 +	<listitem><para>The
  18.540 +	    <quote><literal>hg.serpentine.com</literal></quote> gives
  18.541 +	    the hostname of the server to log into.</para>
  18.542 +	</listitem>
  18.543 +	<listitem><para>The <quote>:22</quote> identifies the port
  18.544 +	    number to connect to the server on.  The default port is
  18.545 +	    22, so you only need to specify a colon and port number if
  18.546 +	    you're <emphasis>not</emphasis> using port 22.</para>
  18.547 +	</listitem>
  18.548 +	<listitem><para>The remainder of the URL is the local path to
  18.549 +	    the repository on the server.</para>
  18.550 +	</listitem></orderedlist>
  18.551 +
  18.552 +      <para>There's plenty of scope for confusion with the path
  18.553 +	component of ssh URLs, as there is no standard way for tools
  18.554 +	to interpret it.  Some programs behave differently than others
  18.555 +	when dealing with these paths. This isn't an ideal situation,
  18.556 +	but it's unlikely to change.  Please read the following
  18.557 +	paragraphs carefully.</para>
  18.558 +
  18.559 +      <para>Mercurial treats the path to a repository on the server as
  18.560 +	relative to the remote user's home directory.  For example, if
  18.561 +	user <literal>foo</literal> on the server has a home directory
  18.562 +	of <filename class="directory">/home/foo</filename>, then an
  18.563 +	ssh URL that contains a path component of <filename
  18.564 +	  class="directory">bar</filename> <emphasis>really</emphasis>
  18.565 +	refers to the directory <filename
  18.566 +	  class="directory">/home/foo/bar</filename>.</para>
  18.567 +
  18.568 +      <para>If you want to specify a path relative to another user's
  18.569 +	home directory, you can use a path that starts with a tilde
  18.570 +	character followed by the user's name (let's call them
  18.571 +	<literal>otheruser</literal>), like this.</para>
  18.572 +      <programlisting>ssh://server/~otheruser/hg/repo</programlisting>
  18.573 +
  18.574 +      <para>And if you really want to specify an
  18.575 +	<emphasis>absolute</emphasis> path on the server, begin the
  18.576 +	path component with two slashes, as in this example.</para>
  18.577 +      <programlisting>ssh://server//absolute/path</programlisting>
  18.578 +
  18.579 +    </sect2>
  18.580 +    <sect2>
  18.581 +      <title>Finding an ssh client for your system</title>
  18.582 +
  18.583 +      <para>Almost every Unix-like system comes with OpenSSH
  18.584 +	preinstalled.  If you're using such a system, run
  18.585 +	<literal>which ssh</literal> to find out if the
  18.586 +	<command>ssh</command> command is installed (it's usually in
  18.587 +	<filename class="directory">/usr/bin</filename>).  In the
  18.588 +	unlikely event that it isn't present, take a look at your
  18.589 +	system documentation to figure out how to install it.</para>
  18.590 +
  18.591 +      <para>On Windows, you'll first need to download a suitable ssh
  18.592 +	client.  There are two alternatives.</para>
  18.593 +      <itemizedlist>
  18.594 +	<listitem><para>Simon Tatham's excellent PuTTY package
  18.595 +	    <citation>web:putty</citation> provides a complete suite
  18.596 +	    of ssh client commands.</para>
  18.597 +	</listitem>
  18.598 +	<listitem><para>If you have a high tolerance for pain, you can
  18.599 +	    use the Cygwin port of OpenSSH.</para>
  18.600 +	</listitem></itemizedlist>
  18.601 +      <para>In either case, you'll need to edit your <filename
  18.602 +      role="special">hg.ini</filename> file to
  18.603 +	tell Mercurial where to find the actual client command.  For
  18.604 +	example, if you're using PuTTY, you'll need to use the
  18.605 +	<command>plink</command> command as a command-line ssh
  18.606 +	client.</para>
  18.607 +      <programlisting>[ui]
  18.608 +ssh = C:/path/to/plink.exe -ssh -i "C:/path/to/my/private/key"</programlisting>
  18.609 +
  18.610 +      <note>
  18.611 +	<para>  The path to <command>plink</command> shouldn't contain
  18.612 +	  any whitespace characters, or Mercurial may not be able to
  18.613 +	  run it correctly (so putting it in <filename
  18.614 +	    class="directory">C:\Program Files</filename> is probably
  18.615 +	  not a good idea).</para>
  18.616 +      </note>
  18.617 +
  18.618 +    </sect2>
  18.619 +    <sect2>
  18.620 +      <title>Generating a key pair</title>
  18.621 +
  18.622 +      <para>To avoid the need to repetitively type a password every
  18.623 +	time you need to use your ssh client, I recommend generating a
  18.624 +	key pair.  On a Unix-like system, the
  18.625 +	<command>ssh-keygen</command> command will do the trick. On
  18.626 +	Windows, if you're using PuTTY, the
  18.627 +	<command>puttygen</command> command is what you'll
  18.628 +	need.</para>
  18.629 +
  18.630 +      <para>When you generate a key pair, it's usually
  18.631 +	<emphasis>highly</emphasis> advisable to protect it with a
  18.632 +	passphrase.  (The only time that you might not want to do this
  18.633 +	is when you're using the ssh protocol for automated tasks on a
  18.634 +	secure network.)</para>
  18.635 +
  18.636 +      <para>Simply generating a key pair isn't enough, however.
  18.637 +	You'll need to add the public key to the set of authorised
  18.638 +	keys for whatever user you're logging in remotely as.  For
  18.639 +	servers using OpenSSH (the vast majority), this will mean
  18.640 +	adding the public key to a list in a file called <filename
  18.641 +	  role="special">authorized_keys</filename> in their <filename
  18.642 +	  role="special" class="directory">.ssh</filename>
  18.643 +	directory.</para>
  18.644 +
  18.645 +      <para>On a Unix-like system, your public key will have a
  18.646 +	<filename>.pub</filename> extension.  If you're using
  18.647 +	<command>puttygen</command> on Windows, you can save the
  18.648 +	public key to a file of your choosing, or paste it from the
  18.649 +	window it's displayed in straight into the <filename
  18.650 +	  role="special">authorized_keys</filename> file.</para>
  18.651 +
  18.652 +    </sect2>
  18.653 +    <sect2>
  18.654 +      <title>Using an authentication agent</title>
  18.655 +
  18.656 +      <para>An authentication agent is a daemon that stores
  18.657 +	passphrases in memory (so it will forget passphrases if you
  18.658 +	log out and log back in again). An ssh client will notice if
  18.659 +	it's running, and query it for a passphrase.  If there's no
  18.660 +	authentication agent running, or the agent doesn't store the
  18.661 +	necessary passphrase, you'll have to type your passphrase
  18.662 +	every time Mercurial tries to communicate with a server on
  18.663 +	your behalf (e.g. whenever you pull or push changes).</para>
  18.664 +
  18.665 +      <para>The downside of storing passphrases in an agent is that
  18.666 +	it's possible for a well-prepared attacker to recover the
  18.667 +	plain text of your passphrases, in some cases even if your
  18.668 +	system has been power-cycled. You should make your own
  18.669 +	judgment as to whether this is an acceptable risk.  It
  18.670 +	certainly saves a lot of repeated typing.</para>
  18.671 +
  18.672 +      <para>On Unix-like systems, the agent is called
  18.673 +	<command>ssh-agent</command>, and it's often run automatically
  18.674 +	for you when you log in.  You'll need to use the
  18.675 +	<command>ssh-add</command> command to add passphrases to the
  18.676 +	agent's store.  On Windows, if you're using PuTTY, the
  18.677 +	<command>pageant</command> command acts as the agent.  It adds
  18.678 +	an icon to your system tray that will let you manage stored
  18.679 +	passphrases.</para>
  18.680 +
  18.681 +    </sect2>
  18.682 +    <sect2>
  18.683 +      <title>Configuring the server side properly</title>
  18.684 +
  18.685 +      <para>Because ssh can be fiddly to set up if you're new to it,
  18.686 +	there's a variety of things that can go wrong.  Add Mercurial
  18.687 +	on top, and there's plenty more scope for head-scratching.
  18.688 +	Most of these potential problems occur on the server side, not
  18.689 +	the client side.  The good news is that once you've gotten a
  18.690 +	configuration working, it will usually continue to work
  18.691 +	indefinitely.</para>
  18.692 +
  18.693 +      <para>Before you try using Mercurial to talk to an ssh server,
  18.694 +	it's best to make sure that you can use the normal
  18.695 +	<command>ssh</command> or <command>putty</command> command to
  18.696 +	talk to the server first.  If you run into problems with using
  18.697 +	these commands directly, Mercurial surely won't work.  Worse,
  18.698 +	it will obscure the underlying problem.  Any time you want to
  18.699 +	debug ssh-related Mercurial problems, you should drop back to
  18.700 +	making sure that plain ssh client commands work first,
  18.701 +	<emphasis>before</emphasis> you worry about whether there's a
  18.702 +	problem with Mercurial.</para>
  18.703 +
  18.704 +      <para>The first thing to be sure of on the server side is that
  18.705 +	you can actually log in from another machine at all.  If you
  18.706 +	can't use <command>ssh</command> or <command>putty</command>
  18.707 +	to log in, the error message you get may give you a few hints
  18.708 +	as to what's wrong.  The most common problems are as
  18.709 +	follows.</para>
  18.710 +      <itemizedlist>
  18.711 +	<listitem><para>If you get a <quote>connection refused</quote>
  18.712 +	    error, either there isn't an SSH daemon running on the
  18.713 +	    server at all, or it's inaccessible due to firewall
  18.714 +	    configuration.</para>
  18.715 +	</listitem>
  18.716 +	<listitem><para>If you get a <quote>no route to host</quote>
  18.717 +	    error, you either have an incorrect address for the server
  18.718 +	    or a seriously locked down firewall that won't admit its
  18.719 +	    existence at all.</para>
  18.720 +	</listitem>
  18.721 +	<listitem><para>If you get a <quote>permission denied</quote>
  18.722 +	    error, you may have mistyped the username on the server,
  18.723 +	    or you could have mistyped your key's passphrase or the
  18.724 +	    remote user's password.</para>
  18.725 +	</listitem></itemizedlist>
  18.726 +      <para>In summary, if you're having trouble talking to the
  18.727 +	server's ssh daemon, first make sure that one is running at
  18.728 +	all.  On many systems it will be installed, but disabled, by
  18.729 +	default.  Once you're done with this step, you should then
  18.730 +	check that the server's firewall is configured to allow
  18.731 +	incoming connections on the port the ssh daemon is listening
  18.732 +	on (usually 22).  Don't worry about more exotic possibilities
  18.733 +	for misconfiguration until you've checked these two
  18.734 +	first.</para>
  18.735 +
  18.736 +      <para>If you're using an authentication agent on the client side
  18.737 +	to store passphrases for your keys, you ought to be able to
  18.738 +	log into the server without being prompted for a passphrase or
  18.739 +	a password.  If you're prompted for a passphrase, there are a
  18.740 +	few possible culprits.</para>
  18.741 +      <itemizedlist>
  18.742 +	<listitem><para>You might have forgotten to use
  18.743 +	    <command>ssh-add</command> or <command>pageant</command>
  18.744 +	    to store the passphrase.</para>
  18.745 +	</listitem>
  18.746 +	<listitem><para>You might have stored the passphrase for the
  18.747 +	    wrong key.</para>
  18.748 +	</listitem></itemizedlist>
  18.749 +      <para>If you're being prompted for the remote user's password,
  18.750 +	there are another few possible problems to check.</para>
  18.751 +      <itemizedlist>
  18.752 +	<listitem><para>Either the user's home directory or their
  18.753 +	    <filename role="special" class="directory">.ssh</filename>
  18.754 +	    directory might have excessively liberal permissions.  As
  18.755 +	    a result, the ssh daemon will not trust or read their
  18.756 +	    <filename role="special">authorized_keys</filename> file.
  18.757 +	    For example, a group-writable home or <filename
  18.758 +	      role="special" class="directory">.ssh</filename>
  18.759 +	    directory will often cause this symptom.</para>
  18.760 +	</listitem>
  18.761 +	<listitem><para>The user's <filename
  18.762 +	      role="special">authorized_keys</filename> file may have
  18.763 +	    a problem. If anyone other than the user owns or can write
  18.764 +	    to that file, the ssh daemon will not trust or read
  18.765 +	    it.</para>
  18.766 +	</listitem></itemizedlist>
  18.767 +
  18.768 +      <para>In the ideal world, you should be able to run the
  18.769 +	following command successfully, and it should print exactly
  18.770 +	one line of output, the current date and time.</para>
  18.771 +      <programlisting>ssh myserver date</programlisting>
  18.772 +
  18.773 +      <para>If, on your server, you have login scripts that print
  18.774 +	banners or other junk even when running non-interactive
  18.775 +	commands like this, you should fix them before you continue,
  18.776 +	so that they only print output if they're run interactively.
  18.777 +	Otherwise these banners will at least clutter up Mercurial's
  18.778 +	output.  Worse, they could potentially cause problems with
  18.779 +	running Mercurial commands remotely.  Mercurial makes tries to
  18.780 +	detect and ignore banners in non-interactive
  18.781 +	<command>ssh</command> sessions, but it is not foolproof.  (If
  18.782 +	you're editing your login scripts on your server, the usual
  18.783 +	way to see if a login script is running in an interactive
  18.784 +	shell is to check the return code from the command
  18.785 +	<literal>tty -s</literal>.)</para>
  18.786 +
  18.787 +      <para>Once you've verified that plain old ssh is working with
  18.788 +	your server, the next step is to ensure that Mercurial runs on
  18.789 +	the server.  The following command should run
  18.790 +	successfully:</para>
  18.791 +
  18.792 +      <programlisting>ssh myserver hg version</programlisting>
  18.793 +
  18.794 +      <para>If you see an error message instead of normal <command
  18.795 +	  role="hg-cmd">hg version</command> output, this is usually
  18.796 +	because you haven't installed Mercurial to <filename
  18.797 +	  class="directory">/usr/bin</filename>.  Don't worry if this
  18.798 +	is the case; you don't need to do that.  But you should check
  18.799 +	for a few possible problems.</para>
  18.800 +      <itemizedlist>
  18.801 +	<listitem><para>Is Mercurial really installed on the server at
  18.802 +	    all?  I know this sounds trivial, but it's worth
  18.803 +	    checking!</para>
  18.804 +	</listitem>
  18.805 +	<listitem><para>Maybe your shell's search path (usually set
  18.806 +	    via the <envar>PATH</envar> environment variable) is
  18.807 +	    simply misconfigured.</para>
  18.808 +	</listitem>
  18.809 +	<listitem><para>Perhaps your <envar>PATH</envar> environment
  18.810 +	    variable is only being set to point to the location of the
  18.811 +	    <command>hg</command> executable if the login session is
  18.812 +	    interactive.  This can happen if you're setting the path
  18.813 +	    in the wrong shell login script.  See your shell's
  18.814 +	    documentation for details.</para>
  18.815 +	</listitem>
  18.816 +	<listitem><para>The <envar>PYTHONPATH</envar> environment
  18.817 +	    variable may need to contain the path to the Mercurial
  18.818 +	    Python modules.  It might not be set at all; it could be
  18.819 +	    incorrect; or it may be set only if the login is
  18.820 +	    interactive.</para>
  18.821 +	</listitem></itemizedlist>
  18.822 +
  18.823 +      <para>If you can run <command role="hg-cmd">hg version</command>
  18.824 +	over an ssh connection, well done! You've got the server and
  18.825 +	client sorted out.  You should now be able to use Mercurial to
  18.826 +	access repositories hosted by that username on that server.
  18.827 +	If you run into problems with Mercurial and ssh at this point,
  18.828 +	try using the <option role="hg-opt-global">--debug</option>
  18.829 +	option to get a clearer picture of what's going on.</para>
  18.830 +
  18.831 +    </sect2>
  18.832 +    <sect2>
  18.833 +      <title>Using compression with ssh</title>
  18.834 +
  18.835 +      <para>Mercurial does not compress data when it uses the ssh
  18.836 +	protocol, because the ssh protocol can transparently compress
  18.837 +	data.  However, the default behaviour of ssh clients is
  18.838 +	<emphasis>not</emphasis> to request compression.</para>
  18.839 +
  18.840 +      <para>Over any network other than a fast LAN (even a wireless
  18.841 +	network), using compression is likely to significantly speed
  18.842 +	up Mercurial's network operations.  For example, over a WAN,
  18.843 +	someone measured compression as reducing the amount of time
  18.844 +	required to clone a particularly large repository from 51
  18.845 +	minutes to 17 minutes.</para>
  18.846 +
  18.847 +      <para>Both <command>ssh</command> and <command>plink</command>
  18.848 +	accept a <option role="cmd-opt-ssh">-C</option> option which
  18.849 +	turns on compression.  You can easily edit your <filename
  18.850 +	  role="special">~/.hgrc</filename> to enable compression for
  18.851 +	all of Mercurial's uses of the ssh protocol.</para>
  18.852 +      <programlisting>[ui]
  18.853 +ssh = ssh -C</programlisting>
  18.854 +
  18.855 +      <para>If you use <command>ssh</command>, you can configure it to
  18.856 +	always use compression when talking to your server.  To do
  18.857 +	this, edit your <filename
  18.858 +	  role="special">.ssh/config</filename> file (which may not
  18.859 +	yet exist), as follows.</para>
  18.860 +      <programlisting>Host hg
  18.861 +  Compression yes
  18.862 +  HostName hg.example.com</programlisting>
  18.863 +      <para>This defines an alias, <literal>hg</literal>.  When you
  18.864 +	use it on the <command>ssh</command> command line or in a
  18.865 +	Mercurial <literal>ssh</literal>-protocol URL, it will cause
  18.866 +	<command>ssh</command> to connect to
  18.867 +	<literal>hg.example.com</literal> and use compression.  This
  18.868 +	gives you both a shorter name to type and compression, each of
  18.869 +	which is a good thing in its own right.</para>
  18.870 +
  18.871 +    </sect2>
  18.872 +  </sect1>
  18.873 +  <sect1 id="sec.collab.cgi">
  18.874 +    <title>Serving over HTTP using CGI</title>
  18.875 +
  18.876 +    <para>Depending on how ambitious you are, configuring Mercurial's
  18.877 +      CGI interface can take anything from a few moments to several
  18.878 +      hours.</para>
  18.879 +
  18.880 +    <para>We'll begin with the simplest of examples, and work our way
  18.881 +      towards a more complex configuration.  Even for the most basic
  18.882 +      case, you're almost certainly going to need to read and modify
  18.883 +      your web server's configuration.</para>
  18.884 +
  18.885 +    <note>
  18.886 +      <para>  Configuring a web server is a complex, fiddly, and
  18.887 +	highly system-dependent activity.  I can't possibly give you
  18.888 +	instructions that will cover anything like all of the cases
  18.889 +	you will encounter. Please use your discretion and judgment in
  18.890 +	following the sections below.  Be prepared to make plenty of
  18.891 +	mistakes, and to spend a lot of time reading your server's
  18.892 +	error logs.</para>
  18.893 +    </note>
  18.894 +
  18.895 +    <sect2>
  18.896 +      <title>Web server configuration checklist</title>
  18.897 +
  18.898 +      <para>Before you continue, do take a few moments to check a few
  18.899 +	aspects of your system's setup.</para>
  18.900 +
  18.901 +      <orderedlist>
  18.902 +	<listitem><para>Do you have a web server installed at all?
  18.903 +	    Mac OS X ships with Apache, but many other systems may not
  18.904 +	    have a web server installed.</para>
  18.905 +	</listitem>
  18.906 +	<listitem><para>If you have a web server installed, is it
  18.907 +	    actually running?  On most systems, even if one is
  18.908 +	    present, it will be disabled by default.</para>
  18.909 +	</listitem>
  18.910 +	<listitem><para>Is your server configured to allow you to run
  18.911 +	    CGI programs in the directory where you plan to do so?
  18.912 +	    Most servers default to explicitly disabling the ability
  18.913 +	    to run CGI programs.</para>
  18.914 +	</listitem></orderedlist>
  18.915 +
  18.916 +      <para>If you don't have a web server installed, and don't have
  18.917 +	substantial experience configuring Apache, you should consider
  18.918 +	using the <literal>lighttpd</literal> web server instead of
  18.919 +	Apache.  Apache has a well-deserved reputation for baroque and
  18.920 +	confusing configuration. While <literal>lighttpd</literal> is
  18.921 +	less capable in some ways than Apache, most of these
  18.922 +	capabilities are not relevant to serving Mercurial
  18.923 +	repositories.  And <literal>lighttpd</literal> is undeniably
  18.924 +	<emphasis>much</emphasis> easier to get started with than
  18.925 +	Apache.</para>
  18.926 +
  18.927 +    </sect2>
  18.928 +    <sect2>
  18.929 +      <title>Basic CGI configuration</title>
  18.930 +
  18.931 +      <para>On Unix-like systems, it's common for users to have a
  18.932 +	subdirectory named something like <filename
  18.933 +	  class="directory">public_html</filename> in their home
  18.934 +	directory, from which they can serve up web pages.  A file
  18.935 +	named <filename>foo</filename> in this directory will be
  18.936 +	accessible at a URL of the form
  18.937 +	<literal>http://www.example.com/username/foo</literal>.</para>
  18.938 +
  18.939 +      <para>To get started, find the <filename
  18.940 +	  role="special">hgweb.cgi</filename> script that should be
  18.941 +	present in your Mercurial installation.  If you can't quickly
  18.942 +	find a local copy on your system, simply download one from the
  18.943 +	master Mercurial repository at <ulink
  18.944 +	  url="http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi">http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi</ulink>.</para>
  18.945 +
  18.946 +      <para>You'll need to copy this script into your <filename
  18.947 +	  class="directory">public_html</filename> directory, and
  18.948 +	ensure that it's executable.</para>
  18.949 +      <programlisting>cp .../hgweb.cgi ~/public_html
  18.950 +chmod 755 ~/public_html/hgweb.cgi</programlisting>
  18.951 +      <para>The <literal>755</literal> argument to
  18.952 +	<command>chmod</command> is a little more general than just
  18.953 +	making the script executable: it ensures that the script is
  18.954 +	executable by anyone, and that <quote>group</quote> and
  18.955 +	<quote>other</quote> write permissions are
  18.956 +	<emphasis>not</emphasis> set.  If you were to leave those
  18.957 +	write permissions enabled, Apache's <literal>suexec</literal>
  18.958 +	subsystem would likely refuse to execute the script.  In fact,
  18.959 +	<literal>suexec</literal> also insists that the
  18.960 +	<emphasis>directory</emphasis> in which the script resides
  18.961 +	must not be writable by others.</para>
  18.962 +      <programlisting>chmod 755 ~/public_html</programlisting>
  18.963 +
  18.964 +      <sect3 id="sec.collab.wtf">
  18.965 +	<title>What could <emphasis>possibly</emphasis> go
  18.966 +	  wrong?</title>
  18.967 +
  18.968 +	<para>Once you've copied the CGI script into place, go into a
  18.969 +	  web browser, and try to open the URL <ulink
  18.970 +	    url="http://myhostname/
  18.971 +	    myuser/hgweb.cgi">http://myhostname/
  18.972 +	    myuser/hgweb.cgi</ulink>, <emphasis>but</emphasis> brace
  18.973 +	  yourself for instant failure.  There's a high probability
  18.974 +	  that trying to visit this URL will fail, and there are many
  18.975 +	  possible reasons for this.  In fact, you're likely to
  18.976 +	  stumble over almost every one of the possible errors below,
  18.977 +	  so please read carefully.  The following are all of the
  18.978 +	  problems I ran into on a system running Fedora 7, with a
  18.979 +	  fresh installation of Apache, and a user account that I
  18.980 +	  created specially to perform this exercise.</para>
  18.981 +
  18.982 +	<para>Your web server may have per-user directories disabled.
  18.983 +	  If you're using Apache, search your config file for a
  18.984 +	  <literal>UserDir</literal> directive.  If there's none
  18.985 +	  present, per-user directories will be disabled.  If one
  18.986 +	  exists, but its value is <literal>disabled</literal>, then
  18.987 +	  per-user directories will be disabled.  Otherwise, the
  18.988 +	  string after <literal>UserDir</literal> gives the name of
  18.989 +	  the subdirectory that Apache will look in under your home
  18.990 +	  directory, for example <filename
  18.991 +	    class="directory">public_html</filename>.</para>
  18.992 +
  18.993 +	<para>Your file access permissions may be too restrictive.
  18.994 +	  The web server must be able to traverse your home directory
  18.995 +	  and directories under your <filename
  18.996 +	    class="directory">public_html</filename> directory, and
  18.997 +	  read files under the latter too.  Here's a quick recipe to
  18.998 +	  help you to make your permissions more appropriate.</para>
  18.999 +	<programlisting>chmod 755 ~
 18.1000 +find ~/public_html -type d -print0 | xargs -0r chmod 755
 18.1001 +find ~/public_html -type f -print0 | xargs -0r chmod 644</programlisting>
 18.1002 +
 18.1003 +	<para>The other possibility with permissions is that you might
 18.1004 +	  get a completely empty window when you try to load the
 18.1005 +	  script.  In this case, it's likely that your access
 18.1006 +	  permissions are <emphasis>too permissive</emphasis>.  Apache's
 18.1007 +	  <literal>suexec</literal> subsystem won't execute a script
 18.1008 +	  that's group- or world-writable, for example.</para>
 18.1009 +
 18.1010 +	<para>Your web server may be configured to disallow execution
 18.1011 +	  of CGI programs in your per-user web directory.  Here's
 18.1012 +	  Apache's default per-user configuration from my Fedora
 18.1013 +	  system.</para>
 18.1014 +
 18.1015 +	<programlisting><![CDATA[&ch06-apache-config.lst;]]></programlisting>
 18.1016 +
 18.1017 +	<para>If you find a similar-looking
 18.1018 +	  <literal>Directory</literal> group in your Apache
 18.1019 +	  configuration, the directive to look at inside it is
 18.1020 +	  <literal>Options</literal>. Add <literal>ExecCGI</literal>
 18.1021 +	  to the end of this list if it's missing, and restart the web
 18.1022 +	  server.</para>
 18.1023 +
 18.1024 +	<para>If you find that Apache serves you the text of the CGI
 18.1025 +	  script instead of executing it, you may need to either
 18.1026 +	  uncomment (if already present) or add a directive like
 18.1027 +	  this.</para>
 18.1028 +	<programlisting>AddHandler cgi-script .cgi</programlisting>
 18.1029 +
 18.1030 +	<para>The next possibility is that you might be served with a
 18.1031 +	  colourful Python backtrace claiming that it can't import a
 18.1032 +	  <literal>mercurial</literal>-related module.  This is
 18.1033 +	  actually progress!  The server is now capable of executing
 18.1034 +	  your CGI script.  This error is only likely to occur if
 18.1035 +	  you're running a private installation of Mercurial, instead
 18.1036 +	  of a system-wide version.  Remember that the web server runs
 18.1037 +	  the CGI program without any of the environment variables
 18.1038 +	  that you take for granted in an interactive session.  If
 18.1039 +	  this error happens to you, edit your copy of <filename
 18.1040 +	    role="special">hgweb.cgi</filename> and follow the
 18.1041 +	  directions inside it to correctly set your
 18.1042 +	  <envar>PYTHONPATH</envar> environment variable.</para>
 18.1043 +
 18.1044 +	<para>Finally, you are <emphasis>certain</emphasis> to by
 18.1045 +	  served with another colourful Python backtrace: this one
 18.1046 +	  will complain that it can't find <filename
 18.1047 +	    class="directory">/path/to/repository</filename>.  Edit
 18.1048 +	  your <filename role="special">hgweb.cgi</filename> script
 18.1049 +	  and replace the <filename
 18.1050 +	    class="directory">/path/to/repository</filename> string
 18.1051 +	  with the complete path to the repository you want to serve
 18.1052 +	  up.</para>
 18.1053 +
 18.1054 +	<para>At this point, when you try to reload the page, you
 18.1055 +	  should be presented with a nice HTML view of your
 18.1056 +	  repository's history.  Whew!</para>
 18.1057 +
 18.1058 +      </sect3>
 18.1059 +      <sect3>
 18.1060 +	<title>Configuring lighttpd</title>
 18.1061 +
 18.1062 +	<para>To be exhaustive in my experiments, I tried configuring
 18.1063 +	  the increasingly popular <literal>lighttpd</literal> web
 18.1064 +	  server to serve the same repository as I described with
 18.1065 +	  Apache above.  I had already overcome all of the problems I
 18.1066 +	  outlined with Apache, many of which are not server-specific.
 18.1067 +	  As a result, I was fairly sure that my file and directory
 18.1068 +	  permissions were good, and that my <filename
 18.1069 +	    role="special">hgweb.cgi</filename> script was properly
 18.1070 +	  edited.</para>
 18.1071 +
 18.1072 +	<para>Once I had Apache running, getting
 18.1073 +	  <literal>lighttpd</literal> to serve the repository was a
 18.1074 +	  snap (in other words, even if you're trying to use
 18.1075 +	  <literal>lighttpd</literal>, you should read the Apache
 18.1076 +	  section).  I first had to edit the
 18.1077 +	  <literal>mod_access</literal> section of its config file to
 18.1078 +	  enable <literal>mod_cgi</literal> and
 18.1079 +	  <literal>mod_userdir</literal>, both of which were disabled
 18.1080 +	  by default on my system.  I then added a few lines to the
 18.1081 +	  end of the config file, to configure these modules.</para>
 18.1082 +	<programlisting>userdir.path = "public_html"
 18.1083 +cgi.assign = (".cgi" =&gt; "" )</programlisting>
 18.1084 +	<para>With this done, <literal>lighttpd</literal> ran
 18.1085 +	  immediately for me.  If I had configured
 18.1086 +	  <literal>lighttpd</literal> before Apache, I'd almost
 18.1087 +	  certainly have run into many of the same system-level
 18.1088 +	  configuration problems as I did with Apache.  However, I
 18.1089 +	  found <literal>lighttpd</literal> to be noticeably easier to
 18.1090 +	  configure than Apache, even though I've used Apache for over
 18.1091 +	  a decade, and this was my first exposure to
 18.1092 +	  <literal>lighttpd</literal>.</para>
 18.1093 +
 18.1094 +      </sect3>
 18.1095 +    </sect2>
 18.1096 +    <sect2>
 18.1097 +      <title>Sharing multiple repositories with one CGI script</title>
 18.1098 +
 18.1099 +      <para>The <filename role="special">hgweb.cgi</filename> script
 18.1100 +	only lets you publish a single repository, which is an
 18.1101 +	annoying restriction.  If you want to publish more than one
 18.1102 +	without wracking yourself with multiple copies of the same
 18.1103 +	script, each with different names, a better choice is to use
 18.1104 +	the <filename role="special">hgwebdir.cgi</filename>
 18.1105 +	script.</para>
 18.1106 +
 18.1107 +      <para>The procedure to configure <filename
 18.1108 +	  role="special">hgwebdir.cgi</filename> is only a little more
 18.1109 +	involved than for <filename
 18.1110 +	  role="special">hgweb.cgi</filename>.  First, you must obtain
 18.1111 +	a copy of the script.  If you don't have one handy, you can
 18.1112 +	download a copy from the master Mercurial repository at <ulink
 18.1113 +	  url="http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi">http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi</ulink>.</para>
 18.1114 +
 18.1115 +      <para>You'll need to copy this script into your <filename
 18.1116 +	  class="directory">public_html</filename> directory, and
 18.1117 +	ensure that it's executable.</para>
 18.1118 +      <programlisting>cp .../hgwebdir.cgi ~/public_html
 18.1119 +chmod 755 ~/public_html ~/public_html/hgwebdir.cgi</programlisting>
 18.1120 +      <para>With basic configuration out of the way, try to visit
 18.1121 +	<ulink url="http://myhostname/
 18.1122 +	  myuser/hgwebdir.cgi">http://myhostname/
 18.1123 +	  myuser/hgwebdir.cgi</ulink> in your browser.  It should
 18.1124 +	display an empty list of repositories.  If you get a blank
 18.1125 +	window or error message, try walking through the list of
 18.1126 +	potential problems in section <xref
 18.1127 +	  linkend="sec.collab.wtf"/>.</para>
 18.1128 +
 18.1129 +      <para>The <filename role="special">hgwebdir.cgi</filename>
 18.1130 +	script relies on an external configuration file.  By default,
 18.1131 +	it searches for a file named <filename
 18.1132 +	  role="special">hgweb.config</filename> in the same directory
 18.1133 +	as itself.  You'll need to create this file, and make it
 18.1134 +	world-readable.  The format of the file is similar to a
 18.1135 +	Windows <quote>ini</quote> file, as understood by Python's
 18.1136 +	<literal>ConfigParser</literal>
 18.1137 +	<citation>web:configparser</citation> module.</para>
 18.1138 +
 18.1139 +      <para>The easiest way to configure <filename
 18.1140 +	  role="special">hgwebdir.cgi</filename> is with a section
 18.1141 +	named <literal>collections</literal>.  This will automatically
 18.1142 +	publish <emphasis>every</emphasis> repository under the
 18.1143 +	directories you name.  The section should look like
 18.1144 +	this:</para>
 18.1145 +      <programlisting>[collections]
 18.1146 +/my/root = /my/root</programlisting>
 18.1147 +      <para>Mercurial interprets this by looking at the directory name
 18.1148 +	on the <emphasis>right</emphasis> hand side of the
 18.1149 +	<quote><literal>=</literal></quote> sign; finding repositories
 18.1150 +	in that directory hierarchy; and using the text on the
 18.1151 +	<emphasis>left</emphasis> to strip off matching text from the
 18.1152 +	names it will actually list in the web interface.  The
 18.1153 +	remaining component of a path after this stripping has
 18.1154 +	occurred is called a <quote>virtual path</quote>.</para>
 18.1155 +
 18.1156 +      <para>Given the example above, if we have a repository whose
 18.1157 +	local path is <filename
 18.1158 +	  class="directory">/my/root/this/repo</filename>, the CGI
 18.1159 +	script will strip the leading <filename
 18.1160 +	  class="directory">/my/root</filename> from the name, and
 18.1161 +	publish the repository with a virtual path of <filename
 18.1162 +	  class="directory">this/repo</filename>.  If the base URL for
 18.1163 +	our CGI script is <ulink url="http://myhostname/
 18.1164 +	  myuser/hgwebdir.cgi">http://myhostname/
 18.1165 +	  myuser/hgwebdir.cgi</ulink>, the complete URL for that
 18.1166 +	repository will be <ulink url="http://myhostname/
 18.1167 +	  myuser/hgwebdir.cgi/this/repo">http://myhostname/
 18.1168 +	  myuser/hgwebdir.cgi/this/repo</ulink>.</para>
 18.1169 +
 18.1170 +      <para>If we replace <filename
 18.1171 +	  class="directory">/my/root</filename> on the left hand side
 18.1172 +	of this example with <filename
 18.1173 +	  class="directory">/my</filename>, then <filename
 18.1174 +	  role="special">hgwebdir.cgi</filename> will only strip off
 18.1175 +	<filename class="directory">/my</filename> from the repository
 18.1176 +	name, and will give us a virtual path of <filename
 18.1177 +	  class="directory">root/this/repo</filename> instead of
 18.1178 +	<filename class="directory">this/repo</filename>.</para>
 18.1179 +
 18.1180 +      <para>The <filename role="special">hgwebdir.cgi</filename>
 18.1181 +	script will recursively search each directory listed in the
 18.1182 +	<literal>collections</literal> section of its configuration
 18.1183 +	file, but it will <literal>not</literal> recurse into the
 18.1184 +	repositories it finds.</para>
 18.1185 +
 18.1186 +      <para>The <literal>collections</literal> mechanism makes it easy
 18.1187 +	to publish many repositories in a <quote>fire and
 18.1188 +	  forget</quote> manner.  You only need to set up the CGI
 18.1189 +	script and configuration file one time.  Afterwards, you can
 18.1190 +	publish or unpublish a repository at any time by simply moving
 18.1191 +	it into, or out of, the directory hierarchy in which you've
 18.1192 +	configured <filename role="special">hgwebdir.cgi</filename> to
 18.1193 +	look.</para>
 18.1194 +
 18.1195 +      <sect3>
 18.1196 +	<title>Explicitly specifying which repositories to
 18.1197 +	  publish</title>
 18.1198 +
 18.1199 +	<para>In addition to the <literal>collections</literal>
 18.1200 +	  mechanism, the <filename
 18.1201 +	    role="special">hgwebdir.cgi</filename> script allows you
 18.1202 +	  to publish a specific list of repositories.  To do so,
 18.1203 +	  create a <literal>paths</literal> section, with contents of
 18.1204 +	  the following form.</para>
 18.1205 +	<programlisting>[paths]
 18.1206 +repo1 = /my/path/to/some/repo
 18.1207 +repo2 = /some/path/to/another</programlisting>
 18.1208 +	<para>In this case, the virtual path (the component that will
 18.1209 +	  appear in a URL) is on the left hand side of each
 18.1210 +	  definition, while the path to the repository is on the
 18.1211 +	  right.  Notice that there does not need to be any
 18.1212 +	  relationship between the virtual path you choose and the
 18.1213 +	  location of a repository in your filesystem.</para>
 18.1214 +
 18.1215 +	<para>If you wish, you can use both the
 18.1216 +	  <literal>collections</literal> and <literal>paths</literal>
 18.1217 +	  mechanisms simultaneously in a single configuration
 18.1218 +	  file.</para>
 18.1219 +
 18.1220 +	<note>
 18.1221 +	  <para>  If multiple repositories have the same virtual path,
 18.1222 +	    <filename role="special">hgwebdir.cgi</filename> will not
 18.1223 +	    report an error.  Instead, it will behave
 18.1224 +	    unpredictably.</para>
 18.1225 +	</note>
 18.1226 +
 18.1227 +      </sect3>
 18.1228 +    </sect2>
 18.1229 +    <sect2>
 18.1230 +      <title>Downloading source archives</title>
 18.1231 +
 18.1232 +      <para>Mercurial's web interface lets users download an archive
 18.1233 +	of any revision.  This archive will contain a snapshot of the
 18.1234 +	working directory as of that revision, but it will not contain
 18.1235 +	a copy of the repository data.</para>
 18.1236 +
 18.1237 +      <para>By default, this feature is not enabled.  To enable it,
 18.1238 +	you'll need to add an <envar
 18.1239 +	  role="rc-item-web">allow_archive</envar> item to the
 18.1240 +	<literal role="rc-web">web</literal> section of your <filename
 18.1241 +	  role="special">~/.hgrc</filename>.</para>
 18.1242 +
 18.1243 +    </sect2>
 18.1244 +    <sect2>
 18.1245 +      <title>Web configuration options</title>
 18.1246 +
 18.1247 +      <para>Mercurial's web interfaces (the <command role="hg-cmd">hg
 18.1248 +	  serve</command> command, and the <filename
 18.1249 +	  role="special">hgweb.cgi</filename> and <filename
 18.1250 +	  role="special">hgwebdir.cgi</filename> scripts) have a
 18.1251 +	number of configuration options that you can set.  These
 18.1252 +	belong in a section named <literal
 18.1253 +	  role="rc-web">web</literal>.</para>
 18.1254 +      <itemizedlist>
 18.1255 +	<listitem><para><envar
 18.1256 +	      role="rc-item-web">allow_archive</envar>: Determines
 18.1257 +	    which (if any) archive download mechanisms Mercurial
 18.1258 +	    supports.  If you enable this feature, users of the web
 18.1259 +	    interface will be able to download an archive of whatever
 18.1260 +	    revision of a repository they are viewing. To enable the
 18.1261 +	    archive feature, this item must take the form of a
 18.1262 +	    sequence of words drawn from the list below.</para>
 18.1263 +	  <itemizedlist>
 18.1264 +	    <listitem><para><literal>bz2</literal>: A
 18.1265 +		<command>tar</command> archive, compressed using
 18.1266 +		<literal>bzip2</literal> compression.  This has the
 18.1267 +		best compression ratio, but uses the most CPU time on
 18.1268 +		the server.</para>
 18.1269 +	    </listitem>
 18.1270 +	    <listitem><para><literal>gz</literal>: A
 18.1271 +		<command>tar</command> archive, compressed using
 18.1272 +		<literal>gzip</literal> compression.</para>
 18.1273 +	    </listitem>
 18.1274 +	    <listitem><para><literal>zip</literal>: A
 18.1275 +		<command>zip</command> archive, compressed using LZW
 18.1276 +		compression.  This format has the worst compression
 18.1277 +		ratio, but is widely used in the Windows world.</para>
 18.1278 +	    </listitem>
 18.1279 +	  </itemizedlist>
 18.1280 +	  <para>  If you provide an empty list, or don't have an
 18.1281 +	    <envar role="rc-item-web">allow_archive</envar> entry at
 18.1282 +	    all, this feature will be disabled.  Here is an example of
 18.1283 +	    how to enable all three supported formats.</para>
 18.1284 +	  <programlisting>[web]
 18.1285 +allow_archive = bz2 gz zip</programlisting>
 18.1286 +	</listitem>
 18.1287 +	<listitem><para><envar role="rc-item-web">allowpull</envar>:
 18.1288 +	    Boolean.  Determines whether the web interface allows
 18.1289 +	    remote users to <command role="hg-cmd">hg pull</command>
 18.1290 +	    and <command role="hg-cmd">hg clone</command> this
 18.1291 +	    repository over HTTP.  If set to <literal>no</literal> or
 18.1292 +	    <literal>false</literal>, only the
 18.1293 +	    <quote>human-oriented</quote> portion of the web interface
 18.1294 +	    is available.</para>
 18.1295 +	</listitem>
 18.1296 +	<listitem><para><envar role="rc-item-web">contact</envar>:
 18.1297 +	    String.  A free-form (but preferably brief) string
 18.1298 +	    identifying the person or group in charge of the
 18.1299 +	    repository.  This often contains the name and email
 18.1300 +	    address of a person or mailing list.  It often makes sense
 18.1301 +	    to place this entry in a repository's own <filename
 18.1302 +	      role="special">.hg/hgrc</filename> file, but it can make
 18.1303 +	    sense to use in a global <filename
 18.1304 +	      role="special">~/.hgrc</filename> if every repository
 18.1305 +	    has a single maintainer.</para>
 18.1306 +	</listitem>
 18.1307 +	<listitem><para><envar role="rc-item-web">maxchanges</envar>:
 18.1308 +	    Integer.  The default maximum number of changesets to
 18.1309 +	    display in a single page of output.</para>
 18.1310 +	</listitem>
 18.1311 +	<listitem><para><envar role="rc-item-web">maxfiles</envar>:
 18.1312 +	    Integer.  The default maximum number of modified files to
 18.1313 +	    display in a single page of output.</para>
 18.1314 +	</listitem>
 18.1315 +	<listitem><para><envar role="rc-item-web">stripes</envar>:
 18.1316 +	    Integer.  If the web interface displays alternating
 18.1317 +	    <quote>stripes</quote> to make it easier to visually align
 18.1318 +	    rows when you are looking at a table, this number controls
 18.1319 +	    the number of rows in each stripe.</para>
 18.1320 +	</listitem>
 18.1321 +	<listitem><para><envar role="rc-item-web">style</envar>:
 18.1322 +	    Controls the template Mercurial uses to display the web
 18.1323 +	    interface.  Mercurial ships with two web templates, named
 18.1324 +	    <literal>default</literal> and <literal>gitweb</literal>
 18.1325 +	    (the latter is much more visually attractive).  You can
 18.1326 +	    also specify a custom template of your own; see chapter
 18.1327 +	    <xref linkend="chap.template"/> for details.
 18.1328 +	    Here, you can see how to enable the
 18.1329 +	    <literal>gitweb</literal> style.</para>
 18.1330 +	  <programlisting>[web]
 18.1331 +style = gitweb</programlisting>
 18.1332 +	</listitem>
 18.1333 +	<listitem><para><envar role="rc-item-web">templates</envar>:
 18.1334 +	    Path.  The directory in which to search for template
 18.1335 +	    files.  By default, Mercurial searches in the directory in
 18.1336 +	    which it was installed.</para>
 18.1337 +	</listitem></itemizedlist>
 18.1338 +      <para>If you are using <filename
 18.1339 +	  role="special">hgwebdir.cgi</filename>, you can place a few
 18.1340 +	configuration items in a <literal role="rc-web">web</literal>
 18.1341 +	section of the <filename
 18.1342 +	  role="special">hgweb.config</filename> file instead of a
 18.1343 +	<filename role="special">~/.hgrc</filename> file, for
 18.1344 +	convenience.  These items are <envar
 18.1345 +	  role="rc-item-web">motd</envar> and <envar
 18.1346 +	  role="rc-item-web">style</envar>.</para>
 18.1347 +
 18.1348 +      <sect3>
 18.1349 +	<title>Options specific to an individual repository</title>
 18.1350 +
 18.1351 +	<para>A few <literal role="rc-web">web</literal> configuration
 18.1352 +	  items ought to be placed in a repository's local <filename
 18.1353 +	    role="special">.hg/hgrc</filename>, rather than a user's
 18.1354 +	  or global <filename role="special">~/.hgrc</filename>.</para>
 18.1355 +	<itemizedlist>
 18.1356 +	  <listitem><para><envar
 18.1357 +		role="rc-item-web">description</envar>: String.  A
 18.1358 +	      free-form (but preferably brief) string that describes
 18.1359 +	      the contents or purpose of the repository.</para>
 18.1360 +	  </listitem>
 18.1361 +	  <listitem><para><envar role="rc-item-web">name</envar>:
 18.1362 +	      String.  The name to use for the repository in the web
 18.1363 +	      interface.  This overrides the default name, which is
 18.1364 +	      the last component of the repository's path.</para>
 18.1365 +	  </listitem></itemizedlist>
 18.1366 +
 18.1367 +      </sect3>
 18.1368 +      <sect3>
 18.1369 +	<title>Options specific to the <command role="hg-cmd">hg
 18.1370 +	    serve</command> command</title>
 18.1371 +
 18.1372 +	<para>Some of the items in the <literal
 18.1373 +	    role="rc-web">web</literal> section of a <filename
 18.1374 +	    role="special">~/.hgrc</filename> file are only for use
 18.1375 +	  with the <command role="hg-cmd">hg serve</command>
 18.1376 +	  command.</para>
 18.1377 +	<itemizedlist>
 18.1378 +	  <listitem><para><envar role="rc-item-web">accesslog</envar>:
 18.1379 +	      Path.  The name of a file into which to write an access
 18.1380 +	      log.  By default, the <command role="hg-cmd">hg
 18.1381 +		serve</command> command writes this information to
 18.1382 +	      standard output, not to a file.  Log entries are written
 18.1383 +	      in the standard <quote>combined</quote> file format used
 18.1384 +	      by almost all web servers.</para>
 18.1385 +	  </listitem>
 18.1386 +	  <listitem><para><envar role="rc-item-web">address</envar>:
 18.1387 +	      String.  The local address on which the server should
 18.1388 +	      listen for incoming connections.  By default, the server
 18.1389 +	      listens on all addresses.</para>
 18.1390 +	  </listitem>
 18.1391 +	  <listitem><para><envar role="rc-item-web">errorlog</envar>:
 18.1392 +	      Path.  The name of a file into which to write an error
 18.1393 +	      log.  By default, the <command role="hg-cmd">hg
 18.1394 +		serve</command> command writes this information to
 18.1395 +	      standard error, not to a file.</para>
 18.1396 +	  </listitem>
 18.1397 +	  <listitem><para><envar role="rc-item-web">ipv6</envar>:
 18.1398 +	      Boolean.  Whether to use the IPv6 protocol. By default,
 18.1399 +	      IPv6 is not used.</para>
 18.1400 +	  </listitem>
 18.1401 +	  <listitem><para><envar role="rc-item-web">port</envar>:
 18.1402 +	      Integer.  The TCP port number on which the server should
 18.1403 +	      listen.  The default port number used is 8000.</para>
 18.1404 +	  </listitem></itemizedlist>
 18.1405 +
 18.1406 +      </sect3>
 18.1407 +      <sect3>
 18.1408 +	<title>Choosing the right <filename
 18.1409 +	    role="special">~/.hgrc</filename> file to add <literal
 18.1410 +	    role="rc-web">web</literal> items to</title>
 18.1411 +
 18.1412 +	<para>It is important to remember that a web server like
 18.1413 +	  Apache or <literal>lighttpd</literal> will run under a user
 18.1414 +	  ID that is different to yours. CGI scripts run by your
 18.1415 +	  server, such as <filename
 18.1416 +	    role="special">hgweb.cgi</filename>, will usually also run
 18.1417 +	  under that user ID.</para>
 18.1418 +
 18.1419 +	<para>If you add <literal role="rc-web">web</literal> items to
 18.1420 +	  your own personal <filename role="special">~/.hgrc</filename> file, CGI scripts won't read that
 18.1421 +	  <filename role="special">~/.hgrc</filename> file.  Those
 18.1422 +	  settings will thus only affect the behaviour of the <command
 18.1423 +	    role="hg-cmd">hg serve</command> command when you run it.
 18.1424 +	  To cause CGI scripts to see your settings, either create a
 18.1425 +	  <filename role="special">~/.hgrc</filename> file in the
 18.1426 +	  home directory of the user ID that runs your web server, or
 18.1427 +	  add those settings to a system-wide <filename
 18.1428 +	    role="special">~/.hgrc</filename> file.</para>
 18.1429 +
 18.1430 +
 18.1431 +      </sect3>
 18.1432 +    </sect2>
 18.1433 +  </sect1>
 18.1434 +</chapter>
 18.1435 +
 18.1436 +<!--
 18.1437 +local variables: 
 18.1438 +sgml-parent-document: ("00book.xml" "book" "chapter")
 18.1439 +end:
 18.1440 +-->
    19.1 --- a/en/ch05-daily.xml	Fri Mar 20 15:40:06 2009 +0800
    19.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.3 @@ -1,544 +0,0 @@
    19.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    19.5 -
    19.6 -<chapter id="chap.daily">
    19.7 -  <?dbhtml filename="mercurial-in-daily-use.html"?>
    19.8 -  <title>Mercurial in daily use</title>
    19.9 -
   19.10 -  <sect1>
   19.11 -    <title>Telling Mercurial which files to track</title>
   19.12 -
   19.13 -    <para>Mercurial does not work with files in your repository unless
   19.14 -      you tell it to manage them.  The <command role="hg-cmd">hg
   19.15 -	status</command> command will tell you which files Mercurial
   19.16 -      doesn't know about; it uses a
   19.17 -      <quote><literal>?</literal></quote> to display such
   19.18 -      files.</para>
   19.19 -
   19.20 -    <para>To tell Mercurial to track a file, use the <command
   19.21 -	role="hg-cmd">hg add</command> command.  Once you have added a
   19.22 -      file, the entry in the output of <command role="hg-cmd">hg
   19.23 -	status</command> for that file changes from
   19.24 -      <quote><literal>?</literal></quote> to
   19.25 -      <quote><literal>A</literal></quote>.</para>
   19.26 -
   19.27 -      &interaction.daily.files.add;
   19.28 -
   19.29 -    <para>After you run a <command role="hg-cmd">hg commit</command>,
   19.30 -      the files that you added before the commit will no longer be
   19.31 -      listed in the output of <command role="hg-cmd">hg
   19.32 -	status</command>.  The reason for this is that <command
   19.33 -	role="hg-cmd">hg status</command> only tells you about
   19.34 -      <quote>interesting</quote> files&emdash;those that you have
   19.35 -      modified or told Mercurial to do something with&emdash;by
   19.36 -      default.  If you have a repository that contains thousands of
   19.37 -      files, you will rarely want to know about files that Mercurial
   19.38 -      is tracking, but that have not changed.  (You can still get this
   19.39 -      information; we'll return to this later.)</para>
   19.40 -
   19.41 -    <para>Once you add a file, Mercurial doesn't do anything with it
   19.42 -      immediately.  Instead, it will take a snapshot of the file's
   19.43 -      state the next time you perform a commit.  It will then continue
   19.44 -      to track the changes you make to the file every time you commit,
   19.45 -      until you remove the file.</para>
   19.46 -
   19.47 -    <sect2>
   19.48 -      <title>Explicit versus implicit file naming</title>
   19.49 -
   19.50 -      <para>A useful behaviour that Mercurial has is that if you pass
   19.51 -	the name of a directory to a command, every Mercurial command
   19.52 -	will treat this as <quote>I want to operate on every file in
   19.53 -	  this directory and its subdirectories</quote>.</para>
   19.54 -
   19.55 -      &interaction.daily.files.add-dir;
   19.56 -
   19.57 -      <para>Notice in this example that Mercurial printed the names of
   19.58 -	the files it added, whereas it didn't do so when we added the
   19.59 -	file named <filename>a</filename> in the earlier
   19.60 -	example.</para>
   19.61 -
   19.62 -      <para>What's going on is that in the former case, we explicitly
   19.63 -	named the file to add on the command line, so the assumption
   19.64 -	that Mercurial makes in such cases is that you know what you
   19.65 -	were doing, and it doesn't print any output.</para>
   19.66 -
   19.67 -      <para>However, when we <emphasis>imply</emphasis> the names of
   19.68 -	files by giving the name of a directory, Mercurial takes the
   19.69 -	extra step of printing the name of each file that it does
   19.70 -	something with.  This makes it more clear what is happening,
   19.71 -	and reduces the likelihood of a silent and nasty surprise.
   19.72 -	This behaviour is common to most Mercurial commands.</para>
   19.73 -
   19.74 -    </sect2>
   19.75 -    <sect2>
   19.76 -      <title>Aside: Mercurial tracks files, not directories</title>
   19.77 -
   19.78 -      <para>Mercurial does not track directory information.  Instead,
   19.79 -	it tracks the path to a file.  Before creating a file, it
   19.80 -	first creates any missing directory components of the path.
   19.81 -	After it deletes a file, it then deletes any empty directories
   19.82 -	that were in the deleted file's path.  This sounds like a
   19.83 -	trivial distinction, but it has one minor practical
   19.84 -	consequence: it is not possible to represent a completely
   19.85 -	empty directory in Mercurial.</para>
   19.86 -
   19.87 -      <para>Empty directories are rarely useful, and there are
   19.88 -	unintrusive workarounds that you can use to achieve an
   19.89 -	appropriate effect.  The developers of Mercurial thus felt
   19.90 -	that the complexity that would be required to manage empty
   19.91 -	directories was not worth the limited benefit this feature
   19.92 -	would bring.</para>
   19.93 -
   19.94 -      <para>If you need an empty directory in your repository, there
   19.95 -	are a few ways to achieve this. One is to create a directory,
   19.96 -	then <command role="hg-cmd">hg add</command> a
   19.97 -	<quote>hidden</quote> file to that directory.  On Unix-like
   19.98 -	systems, any file name that begins with a period
   19.99 -	(<quote><literal>.</literal></quote>) is treated as hidden by
  19.100 -	most commands and GUI tools.  This approach is illustrated
  19.101 -	below.</para>
  19.102 -
  19.103 -&interaction.daily.files.hidden;
  19.104 -
  19.105 -      <para>Another way to tackle a need for an empty directory is to
  19.106 -	simply create one in your automated build scripts before they
  19.107 -	will need it.</para>
  19.108 -
  19.109 -    </sect2>
  19.110 -  </sect1>
  19.111 -  <sect1>
  19.112 -    <title>How to stop tracking a file</title>
  19.113 -
  19.114 -    <para>Once you decide that a file no longer belongs in your
  19.115 -      repository, use the <command role="hg-cmd">hg remove</command>
  19.116 -      command; this deletes the file, and tells Mercurial to stop
  19.117 -      tracking it.  A removed file is represented in the output of
  19.118 -      <command role="hg-cmd">hg status</command> with a
  19.119 -      <quote><literal>R</literal></quote>.</para>
  19.120 -
  19.121 -    &interaction.daily.files.remove;
  19.122 -
  19.123 -    <para>After you <command role="hg-cmd">hg remove</command> a file,
  19.124 -      Mercurial will no longer track changes to that file, even if you
  19.125 -      recreate a file with the same name in your working directory.
  19.126 -      If you do recreate a file with the same name and want Mercurial
  19.127 -      to track the new file, simply <command role="hg-cmd">hg
  19.128 -	add</command> it. Mercurial will know that the newly added
  19.129 -      file is not related to the old file of the same name.</para>
  19.130 -
  19.131 -    <sect2>
  19.132 -      <title>Removing a file does not affect its history</title>
  19.133 -
  19.134 -      <para>It is important to understand that removing a file has
  19.135 -	only two effects.</para>
  19.136 -      <itemizedlist>
  19.137 -	<listitem><para>It removes the current version of the file
  19.138 -	    from the working directory.</para>
  19.139 -	</listitem>
  19.140 -	<listitem><para>It stops Mercurial from tracking changes to
  19.141 -	    the file, from the time of the next commit.</para>
  19.142 -	</listitem></itemizedlist>
  19.143 -      <para>Removing a file <emphasis>does not</emphasis> in any way
  19.144 -	alter the <emphasis>history</emphasis> of the file.</para>
  19.145 -
  19.146 -      <para>If you update the working directory to a changeset in
  19.147 -	which a file that you have removed was still tracked, it will
  19.148 -	reappear in the working directory, with the contents it had
  19.149 -	when you committed that changeset.  If you then update the
  19.150 -	working directory to a later changeset, in which the file had
  19.151 -	been removed, Mercurial will once again remove the file from
  19.152 -	the working directory.</para>
  19.153 -
  19.154 -    </sect2>
  19.155 -    <sect2>
  19.156 -      <title>Missing files</title>
  19.157 -
  19.158 -      <para>Mercurial considers a file that you have deleted, but not
  19.159 -	used <command role="hg-cmd">hg remove</command> to delete, to
  19.160 -	be <emphasis>missing</emphasis>.  A missing file is
  19.161 -	represented with <quote><literal>!</literal></quote> in the
  19.162 -	output of <command role="hg-cmd">hg status</command>.
  19.163 -	Mercurial commands will not generally do anything with missing
  19.164 -	files.</para>
  19.165 -
  19.166 -      &interaction.daily.files.missing;
  19.167 -
  19.168 -      <para>If your repository contains a file that <command
  19.169 -	  role="hg-cmd">hg status</command> reports as missing, and
  19.170 -	you want the file to stay gone, you can run <command
  19.171 -	  role="hg-cmd">hg remove <option
  19.172 -	    role="hg-opt-remove">--after</option></command> at any
  19.173 -	time later on, to tell Mercurial that you really did mean to
  19.174 -	remove the file.</para>
  19.175 -
  19.176 -      &interaction.daily.files.remove-after;
  19.177 -
  19.178 -      <para>On the other hand, if you deleted the missing file by
  19.179 -	accident, give <command role="hg-cmd">hg revert</command> the
  19.180 -	name of the file to recover.  It will reappear, in unmodified
  19.181 -	form.</para>
  19.182 -
  19.183 -&interaction.daily.files.recover-missing;
  19.184 -
  19.185 -    </sect2>
  19.186 -    <sect2>
  19.187 -      <title>Aside: why tell Mercurial explicitly to remove a
  19.188 -	file?</title>
  19.189 -
  19.190 -      <para>You might wonder why Mercurial requires you to explicitly
  19.191 -	tell it that you are deleting a file.  Early during the
  19.192 -	development of Mercurial, it let you delete a file however you
  19.193 -	pleased; Mercurial would notice the absence of the file
  19.194 -	automatically when you next ran a <command role="hg-cmd">hg
  19.195 -	  commit</command>, and stop tracking the file.  In practice,
  19.196 -	this made it too easy to accidentally remove a file without
  19.197 -	noticing.</para>
  19.198 -
  19.199 -    </sect2>
  19.200 -    <sect2>
  19.201 -      <title>Useful shorthand&emdash;adding and removing files in one
  19.202 -	step</title>
  19.203 -
  19.204 -      <para>Mercurial offers a combination command, <command
  19.205 -	  role="hg-cmd">hg addremove</command>, that adds untracked
  19.206 -	files and marks missing files as removed.</para>
  19.207 -
  19.208 -      &interaction.daily.files.addremove;
  19.209 -
  19.210 -      <para>The <command role="hg-cmd">hg commit</command> command
  19.211 -	also provides a <option role="hg-opt-commit">-A</option>
  19.212 -	option that performs this same add-and-remove, immediately
  19.213 -	followed by a commit.</para>
  19.214 -
  19.215 -      &interaction.daily.files.commit-addremove;
  19.216 -
  19.217 -    </sect2>
  19.218 -  </sect1>
  19.219 -  <sect1>
  19.220 -    <title>Copying files</title>
  19.221 -
  19.222 -    <para>Mercurial provides a <command role="hg-cmd">hg
  19.223 -	copy</command> command that lets you make a new copy of a
  19.224 -      file.  When you copy a file using this command, Mercurial makes
  19.225 -      a record of the fact that the new file is a copy of the original
  19.226 -      file.  It treats these copied files specially when you merge
  19.227 -      your work with someone else's.</para>
  19.228 -
  19.229 -    <sect2>
  19.230 -      <title>The results of copying during a merge</title>
  19.231 -
  19.232 -      <para>What happens during a merge is that changes
  19.233 -	<quote>follow</quote> a copy.  To best illustrate what this
  19.234 -	means, let's create an example.  We'll start with the usual
  19.235 -	tiny repository that contains a single file.</para>
  19.236 -
  19.237 -      &interaction.daily.copy.init;
  19.238 -
  19.239 -      <para>We need to do some work in
  19.240 -	parallel, so that we'll have something to merge.  So let's
  19.241 -	clone our repository.</para>
  19.242 -
  19.243 -      &interaction.daily.copy.clone;
  19.244 -
  19.245 -      <para>Back in our initial repository, let's use the <command
  19.246 -	  role="hg-cmd">hg copy</command> command to make a copy of
  19.247 -	the first file we created.</para>
  19.248 -
  19.249 -      &interaction.daily.copy.copy;
  19.250 -
  19.251 -      <para>If we look at the output of the <command role="hg-cmd">hg
  19.252 -	  status</command> command afterwards, the copied file looks
  19.253 -	just like a normal added file.</para>
  19.254 -
  19.255 -      &interaction.daily.copy.status;
  19.256 -
  19.257 -      <para>But if we pass the <option
  19.258 -	  role="hg-opt-status">-C</option> option to <command
  19.259 -	  role="hg-cmd">hg status</command>, it prints another line of
  19.260 -	output: this is the file that our newly-added file was copied
  19.261 -	<emphasis>from</emphasis>.</para>
  19.262 -
  19.263 -      &interaction.daily.copy.status-copy;
  19.264 -
  19.265 -      <para>Now, back in the repository we cloned, let's make a change
  19.266 -	in parallel.  We'll add a line of content to the original file
  19.267 -	that we created.</para>
  19.268 -
  19.269 -      &interaction.daily.copy.other;
  19.270 -
  19.271 -      <para>Now we have a modified <filename>file</filename> in this
  19.272 -	repository.  When we pull the changes from the first
  19.273 -	repository, and merge the two heads, Mercurial will propagate
  19.274 -	the changes that we made locally to <filename>file</filename>
  19.275 -	into its copy, <filename>new-file</filename>.</para>
  19.276 -
  19.277 -      &interaction.daily.copy.merge;
  19.278 -
  19.279 -    </sect2>
  19.280 -    <sect2 id="sec.daily.why-copy">
  19.281 -      <title>Why should changes follow copies?</title>
  19.282 -
  19.283 -      <para>This behaviour, of changes to a file propagating out to
  19.284 -	copies of the file, might seem esoteric, but in most cases
  19.285 -	it's highly desirable.</para>
  19.286 -
  19.287 -      <para>First of all, remember that this propagation
  19.288 -	<emphasis>only</emphasis> happens when you merge.  So if you
  19.289 -	<command role="hg-cmd">hg copy</command> a file, and
  19.290 -	subsequently modify the original file during the normal course
  19.291 -	of your work, nothing will happen.</para>
  19.292 -
  19.293 -      <para>The second thing to know is that modifications will only
  19.294 -	propagate across a copy as long as the repository that you're
  19.295 -	pulling changes from <emphasis>doesn't know</emphasis> about
  19.296 -	the copy.</para>
  19.297 -
  19.298 -      <para>The reason that Mercurial does this is as follows.  Let's
  19.299 -	say I make an important bug fix in a source file, and commit
  19.300 -	my changes. Meanwhile, you've decided to <command
  19.301 -	  role="hg-cmd">hg copy</command> the file in your repository,
  19.302 -	without knowing about the bug or having seen the fix, and you
  19.303 -	have started hacking on your copy of the file.</para>
  19.304 -
  19.305 -      <para>If you pulled and merged my changes, and Mercurial
  19.306 -	<emphasis>didn't</emphasis> propagate changes across copies,
  19.307 -	your source file would now contain the bug, and unless you
  19.308 -	remembered to propagate the bug fix by hand, the bug would
  19.309 -	<emphasis>remain</emphasis> in your copy of the file.</para>
  19.310 -
  19.311 -      <para>By automatically propagating the change that fixed the bug
  19.312 -	from the original file to the copy, Mercurial prevents this
  19.313 -	class of problem. To my knowledge, Mercurial is the
  19.314 -	<emphasis>only</emphasis> revision control system that
  19.315 -	propagates changes across copies like this.</para>
  19.316 -
  19.317 -      <para>Once your change history has a record that the copy and
  19.318 -	subsequent merge occurred, there's usually no further need to
  19.319 -	propagate changes from the original file to the copied file,
  19.320 -	and that's why Mercurial only propagates changes across copies
  19.321 -	until this point, and no further.</para>
  19.322 -
  19.323 -    </sect2>
  19.324 -    <sect2>
  19.325 -      <title>How to make changes <emphasis>not</emphasis> follow a
  19.326 -	copy</title>
  19.327 -
  19.328 -      <para>If, for some reason, you decide that this business of
  19.329 -	automatically propagating changes across copies is not for
  19.330 -	you, simply use your system's normal file copy command (on
  19.331 -	Unix-like systems, that's <command>cp</command>) to make a
  19.332 -	copy of a file, then <command role="hg-cmd">hg add</command>
  19.333 -	the new copy by hand.  Before you do so, though, please do
  19.334 -	reread section <xref linkend="sec.daily.why-copy"/>, and make
  19.335 -	an informed
  19.336 -	decision that this behaviour is not appropriate to your
  19.337 -	specific case.</para>
  19.338 -
  19.339 -    </sect2>
  19.340 -    <sect2>
  19.341 -      <title>Behaviour of the <command role="hg-cmd">hg copy</command>
  19.342 -	command</title>
  19.343 -
  19.344 -      <para>When you use the <command role="hg-cmd">hg copy</command>
  19.345 -	command, Mercurial makes a copy of each source file as it
  19.346 -	currently stands in the working directory.  This means that if
  19.347 -	you make some modifications to a file, then <command
  19.348 -	  role="hg-cmd">hg copy</command> it without first having
  19.349 -	committed those changes, the new copy will also contain the
  19.350 -	modifications you have made up until that point.  (I find this
  19.351 -	behaviour a little counterintuitive, which is why I mention it
  19.352 -	here.)</para>
  19.353 -
  19.354 -      <para>The <command role="hg-cmd">hg copy</command> command acts
  19.355 -	similarly to the Unix <command>cp</command> command (you can
  19.356 -	use the <command role="hg-cmd">hg cp</command> alias if you
  19.357 -	prefer).  The last argument is the
  19.358 -	<emphasis>destination</emphasis>, and all prior arguments are
  19.359 -	<emphasis>sources</emphasis>.  If you pass it a single file as
  19.360 -	the source, and the destination does not exist, it creates a
  19.361 -	new file with that name.</para>
  19.362 -
  19.363 -      &interaction.daily.copy.simple;
  19.364 -      
  19.365 -      <para>If the destination is a directory, Mercurial copies its
  19.366 -	sources into that directory.</para>
  19.367 -
  19.368 -      &interaction.daily.copy.dir-dest;
  19.369 -
  19.370 -      <para>Copying a directory is
  19.371 -	recursive, and preserves the directory structure of the
  19.372 -	source.</para>
  19.373 -
  19.374 -      &interaction.daily.copy.dir-src;
  19.375 -
  19.376 -      <para>If the source and destination are both directories, the
  19.377 -	source tree is recreated in the destination directory.</para>
  19.378 -
  19.379 -	&interaction.daily.copy.dir-src-dest;
  19.380 -
  19.381 -      <para>As with the <command role="hg-cmd">hg rename</command>
  19.382 -	command, if you copy a file manually and then want Mercurial
  19.383 -	to know that you've copied the file, simply use the <option
  19.384 -	  role="hg-opt-copy">--after</option> option to <command
  19.385 -	  role="hg-cmd">hg copy</command>.</para>
  19.386 -
  19.387 -      &interaction.daily.copy.after;
  19.388 -
  19.389 -    </sect2>
  19.390 -  </sect1>
  19.391 -  <sect1>
  19.392 -    <title>Renaming files</title>
  19.393 -
  19.394 -    <para>It's rather more common to need to rename a file than to
  19.395 -      make a copy of it.  The reason I discussed the <command
  19.396 -	role="hg-cmd">hg copy</command> command before talking about
  19.397 -      renaming files is that Mercurial treats a rename in essentially
  19.398 -      the same way as a copy.  Therefore, knowing what Mercurial does
  19.399 -      when you copy a file tells you what to expect when you rename a
  19.400 -      file.</para>
  19.401 -
  19.402 -    <para>When you use the <command role="hg-cmd">hg rename</command>
  19.403 -      command, Mercurial makes a copy of each source file, then
  19.404 -      deletes it and marks the file as removed.</para>
  19.405 -
  19.406 -      &interaction.daily.rename.rename;
  19.407 -
  19.408 -    <para>The <command role="hg-cmd">hg status</command> command shows
  19.409 -      the newly copied file as added, and the copied-from file as
  19.410 -      removed.</para>
  19.411 -
  19.412 -    &interaction.daily.rename.status;
  19.413 -
  19.414 -    <para>As with the results of a <command role="hg-cmd">hg
  19.415 -	copy</command>, we must use the <option
  19.416 -	role="hg-opt-status">-C</option> option to <command
  19.417 -	role="hg-cmd">hg status</command> to see that the added file
  19.418 -      is really being tracked by Mercurial as a copy of the original,
  19.419 -      now removed, file.</para>
  19.420 -
  19.421 -    &interaction.daily.rename.status-copy;
  19.422 -
  19.423 -    <para>As with <command role="hg-cmd">hg remove</command> and
  19.424 -      <command role="hg-cmd">hg copy</command>, you can tell Mercurial
  19.425 -      about a rename after the fact using the <option
  19.426 -	role="hg-opt-rename">--after</option> option.  In most other
  19.427 -      respects, the behaviour of the <command role="hg-cmd">hg
  19.428 -	rename</command> command, and the options it accepts, are
  19.429 -      similar to the <command role="hg-cmd">hg copy</command>
  19.430 -      command.</para>
  19.431 -
  19.432 -    <sect2>
  19.433 -      <title>Renaming files and merging changes</title>
  19.434 -
  19.435 -      <para>Since Mercurial's rename is implemented as
  19.436 -	copy-and-remove, the same propagation of changes happens when
  19.437 -	you merge after a rename as after a copy.</para>
  19.438 -
  19.439 -      <para>If I modify a file, and you rename it to a new name, and
  19.440 -	then we merge our respective changes, my modifications to the
  19.441 -	file under its original name will be propagated into the file
  19.442 -	under its new name. (This is something you might expect to
  19.443 -	<quote>simply work,</quote> but not all revision control
  19.444 -	systems actually do this.)</para>
  19.445 -
  19.446 -      <para>Whereas having changes follow a copy is a feature where
  19.447 -	you can perhaps nod and say <quote>yes, that might be
  19.448 -	  useful,</quote> it should be clear that having them follow a
  19.449 -	rename is definitely important.  Without this facility, it
  19.450 -	would simply be too easy for changes to become orphaned when
  19.451 -	files are renamed.</para>
  19.452 -
  19.453 -    </sect2>
  19.454 -    <sect2>
  19.455 -      <title>Divergent renames and merging</title>
  19.456 -
  19.457 -      <para>The case of diverging names occurs when two developers
  19.458 -	start with a file&emdash;let's call it
  19.459 -	<filename>foo</filename>&emdash;in their respective
  19.460 -	repositories.</para>
  19.461 -
  19.462 -      &interaction.rename.divergent.clone;
  19.463 -
  19.464 -      <para>Anne renames the file to <filename>bar</filename>.</para>
  19.465 -
  19.466 -      &interaction.rename.divergent.rename.anne;
  19.467 -
  19.468 -      <para>Meanwhile, Bob renames it to
  19.469 -	<filename>quux</filename>.</para>
  19.470 -
  19.471 -	&interaction.rename.divergent.rename.bob;
  19.472 -
  19.473 -      <para>I like to think of this as a conflict because each
  19.474 -	developer has expressed different intentions about what the
  19.475 -	file ought to be named.</para>
  19.476 -
  19.477 -      <para>What do you think should happen when they merge their
  19.478 -	work? Mercurial's actual behaviour is that it always preserves
  19.479 -	<emphasis>both</emphasis> names when it merges changesets that
  19.480 -	contain divergent renames.</para>
  19.481 -
  19.482 -      &interaction.rename.divergent.merge;
  19.483 -
  19.484 -      <para>Notice that Mercurial does warn about the divergent
  19.485 -	renames, but it leaves it up to you to do something about the
  19.486 -	divergence after the merge.</para>
  19.487 -
  19.488 -    </sect2>
  19.489 -    <sect2>
  19.490 -      <title>Convergent renames and merging</title>
  19.491 -
  19.492 -      <para>Another kind of rename conflict occurs when two people
  19.493 -	choose to rename different <emphasis>source</emphasis> files
  19.494 -	to the same <emphasis>destination</emphasis>. In this case,
  19.495 -	Mercurial runs its normal merge machinery, and lets you guide
  19.496 -	it to a suitable resolution.</para>
  19.497 -
  19.498 -    </sect2>
  19.499 -    <sect2>
  19.500 -      <title>Other name-related corner cases</title>
  19.501 -
  19.502 -      <para>Mercurial has a longstanding bug in which it fails to
  19.503 -	handle a merge where one side has a file with a given name,
  19.504 -	while another has a directory with the same name.  This is
  19.505 -	documented as <ulink role="hg-bug"
  19.506 -	  url="http://www.selenic.com/mercurial/bts/issue29">issue
  19.507 -	  29</ulink>.</para>
  19.508 -
  19.509 -      &interaction.issue29.go;
  19.510 -
  19.511 -    </sect2>
  19.512 -  </sect1>
  19.513 -  <sect1>
  19.514 -    <title>Recovering from mistakes</title>
  19.515 -
  19.516 -    <para>Mercurial has some useful commands that will help you to
  19.517 -      recover from some common mistakes.</para>
  19.518 -
  19.519 -    <para>The <command role="hg-cmd">hg revert</command> command lets
  19.520 -      you undo changes that you have made to your working directory.
  19.521 -      For example, if you <command role="hg-cmd">hg add</command> a
  19.522 -      file by accident, just run <command role="hg-cmd">hg
  19.523 -	revert</command> with the name of the file you added, and
  19.524 -      while the file won't be touched in any way, it won't be tracked
  19.525 -      for adding by Mercurial any longer, either.  You can also use
  19.526 -      <command role="hg-cmd">hg revert</command> to get rid of
  19.527 -      erroneous changes to a file.</para>
  19.528 -
  19.529 -    <para>It's useful to remember that the <command role="hg-cmd">hg
  19.530 -	revert</command> command is useful for changes that you have
  19.531 -      not yet committed.  Once you've committed a change, if you
  19.532 -      decide it was a mistake, you can still do something about it,
  19.533 -      though your options may be more limited.</para>
  19.534 -
  19.535 -    <para>For more information about the <command role="hg-cmd">hg
  19.536 -	revert</command> command, and details about how to deal with
  19.537 -      changes you have already committed, see chapter <xref
  19.538 -	linkend="chap.undo"/>.</para>
  19.539 -
  19.540 -  </sect1>
  19.541 -</chapter>
  19.542 -
  19.543 -<!--
  19.544 -local variables: 
  19.545 -sgml-parent-document: ("00book.xml" "book" "chapter")
  19.546 -end:
  19.547 --->
    20.1 --- a/en/ch06-collab.xml	Fri Mar 20 15:40:06 2009 +0800
    20.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.3 @@ -1,1437 +0,0 @@
    20.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    20.5 -
    20.6 -<chapter id="cha.collab">
    20.7 -  <?dbhtml filename="collaborating-with-other-people.html"?>
    20.8 -  <title>Collaborating with other people</title>
    20.9 -
   20.10 -  <para>As a completely decentralised tool, Mercurial doesn't impose
   20.11 -    any policy on how people ought to work with each other.  However,
   20.12 -    if you're new to distributed revision control, it helps to have
   20.13 -    some tools and examples in mind when you're thinking about
   20.14 -    possible workflow models.</para>
   20.15 -
   20.16 -  <sect1>
   20.17 -    <title>Mercurial's web interface</title>
   20.18 -
   20.19 -    <para>Mercurial has a powerful web interface that provides several
   20.20 -      useful capabilities.</para>
   20.21 -
   20.22 -    <para>For interactive use, the web interface lets you browse a
   20.23 -      single repository or a collection of repositories.  You can view
   20.24 -      the history of a repository, examine each change (comments and
   20.25 -      diffs), and view the contents of each directory and file.</para>
   20.26 -
   20.27 -    <para>Also for human consumption, the web interface provides an
   20.28 -      RSS feed of the changes in a repository.  This lets you
   20.29 -      <quote>subscribe</quote> to a repository using your favourite
   20.30 -      feed reader, and be automatically notified of activity in that
   20.31 -      repository as soon as it happens.  I find this capability much
   20.32 -      more convenient than the model of subscribing to a mailing list
   20.33 -      to which notifications are sent, as it requires no additional
   20.34 -      configuration on the part of whoever is serving the
   20.35 -      repository.</para>
   20.36 -
   20.37 -    <para>The web interface also lets remote users clone a repository,
   20.38 -      pull changes from it, and (when the server is configured to
   20.39 -      permit it) push changes back to it.  Mercurial's HTTP tunneling
   20.40 -      protocol aggressively compresses data, so that it works
   20.41 -      efficiently even over low-bandwidth network connections.</para>
   20.42 -
   20.43 -    <para>The easiest way to get started with the web interface is to
   20.44 -      use your web browser to visit an existing repository, such as
   20.45 -      the master Mercurial repository at <ulink
   20.46 -	url="http://www.selenic.com/repo/hg?style=gitweb">http://www.selenic.com/repo/hg?style=gitweb</ulink>.</para>
   20.47 -
   20.48 -    <para>If you're interested in providing a web interface to your
   20.49 -      own repositories, Mercurial provides two ways to do this.  The
   20.50 -      first is using the <command role="hg-cmd">hg serve</command>
   20.51 -      command, which is best suited to short-term
   20.52 -      <quote>lightweight</quote> serving.  See section <xref
   20.53 -	linkend="sec.collab.serve"/> below for details of how to use
   20.54 -      this command.  If you have a long-lived repository that you'd
   20.55 -      like to make permanently available, Mercurial has built-in
   20.56 -      support for the CGI (Common Gateway Interface) standard, which
   20.57 -      all common web servers support.  See section <xref
   20.58 -	linkend="sec.collab.cgi"/> for details of CGI
   20.59 -      configuration.</para>
   20.60 -
   20.61 -  </sect1>
   20.62 -  <sect1>
   20.63 -    <title>Collaboration models</title>
   20.64 -
   20.65 -    <para>With a suitably flexible tool, making decisions about
   20.66 -      workflow is much more of a social engineering challenge than a
   20.67 -      technical one. Mercurial imposes few limitations on how you can
   20.68 -      structure the flow of work in a project, so it's up to you and
   20.69 -      your group to set up and live with a model that matches your own
   20.70 -      particular needs.</para>
   20.71 -
   20.72 -    <sect2>
   20.73 -      <title>Factors to keep in mind</title>
   20.74 -
   20.75 -      <para>The most important aspect of any model that you must keep
   20.76 -	in mind is how well it matches the needs and capabilities of
   20.77 -	the people who will be using it.  This might seem
   20.78 -	self-evident; even so, you still can't afford to forget it for
   20.79 -	a moment.</para>
   20.80 -
   20.81 -      <para>I once put together a workflow model that seemed to make
   20.82 -	perfect sense to me, but that caused a considerable amount of
   20.83 -	consternation and strife within my development team.  In spite
   20.84 -	of my attempts to explain why we needed a complex set of
   20.85 -	branches, and how changes ought to flow between them, a few
   20.86 -	team members revolted.  Even though they were smart people,
   20.87 -	they didn't want to pay attention to the constraints we were
   20.88 -	operating under, or face the consequences of those constraints
   20.89 -	in the details of the model that I was advocating.</para>
   20.90 -
   20.91 -      <para>Don't sweep foreseeable social or technical problems under
   20.92 -	the rug. Whatever scheme you put into effect, you should plan
   20.93 -	for mistakes and problem scenarios.  Consider adding automated
   20.94 -	machinery to prevent, or quickly recover from, trouble that
   20.95 -	you can anticipate.  As an example, if you intend to have a
   20.96 -	branch with not-for-release changes in it, you'd do well to
   20.97 -	think early about the possibility that someone might
   20.98 -	accidentally merge those changes into a release branch.  You
   20.99 -	could avoid this particular problem by writing a hook that
  20.100 -	prevents changes from being merged from an inappropriate
  20.101 -	branch.</para>
  20.102 -
  20.103 -    </sect2>
  20.104 -    <sect2>
  20.105 -      <title>Informal anarchy</title>
  20.106 -
  20.107 -      <para>I wouldn't suggest an <quote>anything goes</quote>
  20.108 -	approach as something sustainable, but it's a model that's
  20.109 -	easy to grasp, and it works perfectly well in a few unusual
  20.110 -	situations.</para>
  20.111 -
  20.112 -      <para>As one example, many projects have a loose-knit group of
  20.113 -	collaborators who rarely physically meet each other.  Some
  20.114 -	groups like to overcome the isolation of working at a distance
  20.115 -	by organising occasional <quote>sprints</quote>.  In a sprint,
  20.116 -	a number of people get together in a single location (a
  20.117 -	company's conference room, a hotel meeting room, that kind of
  20.118 -	place) and spend several days more or less locked in there,
  20.119 -	hacking intensely on a handful of projects.</para>
  20.120 -
  20.121 -      <para>A sprint is the perfect place to use the <command
  20.122 -	  role="hg-cmd">hg serve</command> command, since <command
  20.123 -	  role="hg-cmd">hg serve</command> does not require any fancy
  20.124 -	server infrastructure.  You can get started with <command
  20.125 -	  role="hg-cmd">hg serve</command> in moments, by reading
  20.126 -	section <xref linkend="sec.collab.serve"/> below.  Then simply
  20.127 -	tell
  20.128 -	the person next to you that you're running a server, send the
  20.129 -	URL to them in an instant message, and you immediately have a
  20.130 -	quick-turnaround way to work together.  They can type your URL
  20.131 -	into their web browser and quickly review your changes; or
  20.132 -	they can pull a bugfix from you and verify it; or they can
  20.133 -	clone a branch containing a new feature and try it out.</para>
  20.134 -
  20.135 -      <para>The charm, and the problem, with doing things in an ad hoc
  20.136 -	fashion like this is that only people who know about your
  20.137 -	changes, and where they are, can see them.  Such an informal
  20.138 -	approach simply doesn't scale beyond a handful people, because
  20.139 -	each individual needs to know about $n$ different repositories
  20.140 -	to pull from.</para>
  20.141 -
  20.142 -    </sect2>
  20.143 -    <sect2>
  20.144 -      <title>A single central repository</title>
  20.145 -
  20.146 -      <para>For smaller projects migrating from a centralised revision
  20.147 -	control tool, perhaps the easiest way to get started is to
  20.148 -	have changes flow through a single shared central repository.
  20.149 -	This is also the most common <quote>building block</quote> for
  20.150 -	more ambitious workflow schemes.</para>
  20.151 -
  20.152 -      <para>Contributors start by cloning a copy of this repository.
  20.153 -	They can pull changes from it whenever they need to, and some
  20.154 -	(perhaps all) developers have permission to push a change back
  20.155 -	when they're ready for other people to see it.</para>
  20.156 -
  20.157 -      <para>Under this model, it can still often make sense for people
  20.158 -	to pull changes directly from each other, without going
  20.159 -	through the central repository.  Consider a case in which I
  20.160 -	have a tentative bug fix, but I am worried that if I were to
  20.161 -	publish it to the central repository, it might subsequently
  20.162 -	break everyone else's trees as they pull it.  To reduce the
  20.163 -	potential for damage, I can ask you to clone my repository
  20.164 -	into a temporary repository of your own and test it.  This
  20.165 -	lets us put off publishing the potentially unsafe change until
  20.166 -	it has had a little testing.</para>
  20.167 -
  20.168 -      <para>In this kind of scenario, people usually use the
  20.169 -	<command>ssh</command> protocol to securely push changes to
  20.170 -	the central repository, as documented in section <xref
  20.171 -	  linkend="sec.collab.ssh"/>.  It's also
  20.172 -	usual to publish a read-only copy of the repository over HTTP
  20.173 -	using CGI, as in section <xref linkend="sec.collab.cgi"/>.
  20.174 -	Publishing over HTTP
  20.175 -	satisfies the needs of people who don't have push access, and
  20.176 -	those who want to use web browsers to browse the repository's
  20.177 -	history.</para>
  20.178 -
  20.179 -    </sect2>
  20.180 -    <sect2>
  20.181 -      <title>Working with multiple branches</title>
  20.182 -
  20.183 -      <para>Projects of any significant size naturally tend to make
  20.184 -	progress on several fronts simultaneously.  In the case of
  20.185 -	software, it's common for a project to go through periodic
  20.186 -	official releases.  A release might then go into
  20.187 -	<quote>maintenance mode</quote> for a while after its first
  20.188 -	publication; maintenance releases tend to contain only bug
  20.189 -	fixes, not new features.  In parallel with these maintenance
  20.190 -	releases, one or more future releases may be under
  20.191 -	development.  People normally use the word
  20.192 -	<quote>branch</quote> to refer to one of these many slightly
  20.193 -	different directions in which development is
  20.194 -	proceeding.</para>
  20.195 -
  20.196 -      <para>Mercurial is particularly well suited to managing a number
  20.197 -	of simultaneous, but not identical, branches.  Each
  20.198 -	<quote>development direction</quote> can live in its own
  20.199 -	central repository, and you can merge changes from one to
  20.200 -	another as the need arises.  Because repositories are
  20.201 -	independent of each other, unstable changes in a development
  20.202 -	branch will never affect a stable branch unless someone
  20.203 -	explicitly merges those changes in.</para>
  20.204 -
  20.205 -      <para>Here's an example of how this can work in practice.  Let's
  20.206 -	say you have one <quote>main branch</quote> on a central
  20.207 -	server.</para>
  20.208 -
  20.209 -      &interaction.branching.init;
  20.210 -
  20.211 -      <para>People clone it, make changes locally, test them, and push
  20.212 -	them back.</para>
  20.213 -
  20.214 -      <para>Once the main branch reaches a release milestone, you can
  20.215 -	use the <command role="hg-cmd">hg tag</command> command to
  20.216 -	give a permanent name to the milestone revision.</para>
  20.217 -
  20.218 -	&interaction.branching.tag;
  20.219 -
  20.220 -      <para>Let's say some ongoing
  20.221 -	development occurs on the main branch.</para>
  20.222 -
  20.223 -      &interaction.branching.main;
  20.224 -
  20.225 -      <para>Using the tag that was recorded at the milestone, people
  20.226 -	who clone that repository at any time in the future can use
  20.227 -	<command role="hg-cmd">hg update</command> to get a copy of
  20.228 -	the working directory exactly as it was when that tagged
  20.229 -	revision was committed.</para>
  20.230 -
  20.231 -      &interaction.branching.update;
  20.232 -
  20.233 -      <para>In addition, immediately after the main branch is tagged,
  20.234 -	someone can then clone the main branch on the server to a new
  20.235 -	<quote>stable</quote> branch, also on the server.</para>
  20.236 -
  20.237 -      &interaction.branching.clone;
  20.238 -
  20.239 -      <para>Someone who needs to make a change to the stable branch
  20.240 -	can then clone <emphasis>that</emphasis> repository, make
  20.241 -	their changes, commit, and push their changes back there.</para>
  20.242 -
  20.243 -      &interaction.branching.stable;
  20.244 -
  20.245 -      <para>Because Mercurial repositories are independent, and
  20.246 -	Mercurial doesn't move changes around automatically, the
  20.247 -	stable and main branches are <emphasis>isolated</emphasis>
  20.248 -	from each other.  The changes that you made on the main branch
  20.249 -	don't <quote>leak</quote> to the stable branch, and vice
  20.250 -	versa.</para>
  20.251 -
  20.252 -      <para>You'll often want all of your bugfixes on the stable
  20.253 -	branch to show up on the main branch, too.  Rather than
  20.254 -	rewrite a bugfix on the main branch, you can simply pull and
  20.255 -	merge changes from the stable to the main branch, and
  20.256 -	Mercurial will bring those bugfixes in for you.</para>
  20.257 -
  20.258 -	&interaction.branching.merge;
  20.259 -
  20.260 -      <para>The main branch will still contain changes that are not on
  20.261 -	the stable branch, but it will also contain all of the
  20.262 -	bugfixes from the stable branch.  The stable branch remains
  20.263 -	unaffected by these changes.</para>
  20.264 -
  20.265 -    </sect2>
  20.266 -    <sect2>
  20.267 -      <title>Feature branches</title>
  20.268 -
  20.269 -      <para>For larger projects, an effective way to manage change is
  20.270 -	to break up a team into smaller groups.  Each group has a
  20.271 -	shared branch of its own, cloned from a single
  20.272 -	<quote>master</quote> branch used by the entire project.
  20.273 -	People working on an individual branch are typically quite
  20.274 -	isolated from developments on other branches.</para>
  20.275 -
  20.276 -      <informalfigure id="fig.collab.feature-branches">
  20.277 -        <mediaobject>
  20.278 -          <imageobject><imagedata fileref="images/feature-branches.png"/>
  20.279 -          </imageobject>
  20.280 -          <textobject><phrase>XXX add text</phrase></textobject>
  20.281 -          <caption><para id="fig.collab.feature-branches.caption">Feature
  20.282 -            branches</para></caption>
  20.283 -        </mediaobject>
  20.284 -      </informalfigure>
  20.285 -
  20.286 -      <para>When a particular feature is deemed to be in suitable
  20.287 -	shape, someone on that feature team pulls and merges from the
  20.288 -	master branch into the feature branch, then pushes back up to
  20.289 -	the master branch.</para>
  20.290 -
  20.291 -    </sect2>
  20.292 -    <sect2>
  20.293 -      <title>The release train</title>
  20.294 -
  20.295 -      <para>Some projects are organised on a <quote>train</quote>
  20.296 -	basis: a release is scheduled to happen every few months, and
  20.297 -	whatever features are ready when the <quote>train</quote> is
  20.298 -	ready to leave are allowed in.</para>
  20.299 -
  20.300 -      <para>This model resembles working with feature branches.  The
  20.301 -	difference is that when a feature branch misses a train,
  20.302 -	someone on the feature team pulls and merges the changes that
  20.303 -	went out on that train release into the feature branch, and
  20.304 -	the team continues its work on top of that release so that
  20.305 -	their feature can make the next release.</para>
  20.306 -
  20.307 -    </sect2>
  20.308 -    <sect2>
  20.309 -      <title>The Linux kernel model</title>
  20.310 -
  20.311 -      <para>The development of the Linux kernel has a shallow
  20.312 -	hierarchical structure, surrounded by a cloud of apparent
  20.313 -	chaos.  Because most Linux developers use
  20.314 -	<command>git</command>, a distributed revision control tool
  20.315 -	with capabilities similar to Mercurial, it's useful to
  20.316 -	describe the way work flows in that environment; if you like
  20.317 -	the ideas, the approach translates well across tools.</para>
  20.318 -
  20.319 -      <para>At the center of the community sits Linus Torvalds, the
  20.320 -	creator of Linux.  He publishes a single source repository
  20.321 -	that is considered the <quote>authoritative</quote> current
  20.322 -	tree by the entire developer community. Anyone can clone
  20.323 -	Linus's tree, but he is very choosy about whose trees he pulls
  20.324 -	from.</para>
  20.325 -
  20.326 -      <para>Linus has a number of <quote>trusted lieutenants</quote>.
  20.327 -	As a general rule, he pulls whatever changes they publish, in
  20.328 -	most cases without even reviewing those changes.  Some of
  20.329 -	those lieutenants are generally agreed to be
  20.330 -	<quote>maintainers</quote>, responsible for specific
  20.331 -	subsystems within the kernel.  If a random kernel hacker wants
  20.332 -	to make a change to a subsystem that they want to end up in
  20.333 -	Linus's tree, they must find out who the subsystem's
  20.334 -	maintainer is, and ask that maintainer to take their change.
  20.335 -	If the maintainer reviews their changes and agrees to take
  20.336 -	them, they'll pass them along to Linus in due course.</para>
  20.337 -
  20.338 -      <para>Individual lieutenants have their own approaches to
  20.339 -	reviewing, accepting, and publishing changes; and for deciding
  20.340 -	when to feed them to Linus.  In addition, there are several
  20.341 -	well known branches that people use for different purposes.
  20.342 -	For example, a few people maintain <quote>stable</quote>
  20.343 -	repositories of older versions of the kernel, to which they
  20.344 -	apply critical fixes as needed.  Some maintainers publish
  20.345 -	multiple trees: one for experimental changes; one for changes
  20.346 -	that they are about to feed upstream; and so on.  Others just
  20.347 -	publish a single tree.</para>
  20.348 -
  20.349 -      <para>This model has two notable features.  The first is that
  20.350 -	it's <quote>pull only</quote>.  You have to ask, convince, or
  20.351 -	beg another developer to take a change from you, because there
  20.352 -	are almost no trees to which more than one person can push,
  20.353 -	and there's no way to push changes into a tree that someone
  20.354 -	else controls.</para>
  20.355 -
  20.356 -      <para>The second is that it's based on reputation and acclaim.
  20.357 -	If you're an unknown, Linus will probably ignore changes from
  20.358 -	you without even responding.  But a subsystem maintainer will
  20.359 -	probably review them, and will likely take them if they pass
  20.360 -	their criteria for suitability. The more <quote>good</quote>
  20.361 -	changes you contribute to a maintainer, the more likely they
  20.362 -	are to trust your judgment and accept your changes.  If you're
  20.363 -	well-known and maintain a long-lived branch for something
  20.364 -	Linus hasn't yet accepted, people with similar interests may
  20.365 -	pull your changes regularly to keep up with your work.</para>
  20.366 -
  20.367 -      <para>Reputation and acclaim don't necessarily cross subsystem
  20.368 -	or <quote>people</quote> boundaries.  If you're a respected
  20.369 -	but specialised storage hacker, and you try to fix a
  20.370 -	networking bug, that change will receive a level of scrutiny
  20.371 -	from a network maintainer comparable to a change from a
  20.372 -	complete stranger.</para>
  20.373 -
  20.374 -      <para>To people who come from more orderly project backgrounds,
  20.375 -	the comparatively chaotic Linux kernel development process
  20.376 -	often seems completely insane.  It's subject to the whims of
  20.377 -	individuals; people make sweeping changes whenever they deem
  20.378 -	it appropriate; and the pace of development is astounding.
  20.379 -	And yet Linux is a highly successful, well-regarded piece of
  20.380 -	software.</para>
  20.381 -
  20.382 -    </sect2>
  20.383 -    <sect2>
  20.384 -      <title>Pull-only versus shared-push collaboration</title>
  20.385 -
  20.386 -      <para>A perpetual source of heat in the open source community is
  20.387 -	whether a development model in which people only ever pull
  20.388 -	changes from others is <quote>better than</quote> one in which
  20.389 -	multiple people can push changes to a shared
  20.390 -	repository.</para>
  20.391 -
  20.392 -      <para>Typically, the backers of the shared-push model use tools
  20.393 -	that actively enforce this approach.  If you're using a
  20.394 -	centralised revision control tool such as Subversion, there's
  20.395 -	no way to make a choice over which model you'll use: the tool
  20.396 -	gives you shared-push, and if you want to do anything else,
  20.397 -	you'll have to roll your own approach on top (such as applying
  20.398 -	a patch by hand).</para>
  20.399 -
  20.400 -      <para>A good distributed revision control tool, such as
  20.401 -	Mercurial, will support both models.  You and your
  20.402 -	collaborators can then structure how you work together based
  20.403 -	on your own needs and preferences, not on what contortions
  20.404 -	your tools force you into.</para>
  20.405 -
  20.406 -    </sect2>
  20.407 -    <sect2>
  20.408 -      <title>Where collaboration meets branch management</title>
  20.409 -
  20.410 -      <para>Once you and your team set up some shared repositories and
  20.411 -	start propagating changes back and forth between local and
  20.412 -	shared repos, you begin to face a related, but slightly
  20.413 -	different challenge: that of managing the multiple directions
  20.414 -	in which your team may be moving at once.  Even though this
  20.415 -	subject is intimately related to how your team collaborates,
  20.416 -	it's dense enough to merit treatment of its own, in chapter
  20.417 -	<xref linkend="chap.branch"/>.</para>
  20.418 -
  20.419 -    </sect2>
  20.420 -  </sect1>
  20.421 -  <sect1>
  20.422 -    <title>The technical side of sharing</title>
  20.423 -
  20.424 -    <para>The remainder of this chapter is devoted to the question of
  20.425 -      serving data to your collaborators.</para>
  20.426 -
  20.427 -  </sect1>
  20.428 -  <sect1 id="sec.collab.serve">
  20.429 -    <title>Informal sharing with <command role="hg-cmd">hg
  20.430 -	serve</command></title>
  20.431 -
  20.432 -    <para>Mercurial's <command role="hg-cmd">hg serve</command>
  20.433 -      command is wonderfully suited to small, tight-knit, and
  20.434 -      fast-paced group environments.  It also provides a great way to
  20.435 -      get a feel for using Mercurial commands over a network.</para>
  20.436 -
  20.437 -    <para>Run <command role="hg-cmd">hg serve</command> inside a
  20.438 -      repository, and in under a second it will bring up a specialised
  20.439 -      HTTP server; this will accept connections from any client, and
  20.440 -      serve up data for that repository until you terminate it.
  20.441 -      Anyone who knows the URL of the server you just started, and can
  20.442 -      talk to your computer over the network, can then use a web
  20.443 -      browser or Mercurial to read data from that repository.  A URL
  20.444 -      for a <command role="hg-cmd">hg serve</command> instance running
  20.445 -      on a laptop is likely to look something like
  20.446 -      <literal>http://my-laptop.local:8000/</literal>.</para>
  20.447 -
  20.448 -    <para>The <command role="hg-cmd">hg serve</command> command is
  20.449 -      <emphasis>not</emphasis> a general-purpose web server. It can do
  20.450 -      only two things:</para>
  20.451 -    <itemizedlist>
  20.452 -      <listitem><para>Allow people to browse the history of the
  20.453 -	  repository it's serving, from their normal web
  20.454 -	  browsers.</para>
  20.455 -      </listitem>
  20.456 -      <listitem><para>Speak Mercurial's wire protocol, so that people
  20.457 -	  can <command role="hg-cmd">hg clone</command> or <command
  20.458 -	    role="hg-cmd">hg pull</command> changes from that
  20.459 -	  repository.</para>
  20.460 -      </listitem></itemizedlist>
  20.461 -    <para>In particular, <command role="hg-cmd">hg serve</command>
  20.462 -      won't allow remote users to <emphasis>modify</emphasis> your
  20.463 -      repository.  It's intended for read-only use.</para>
  20.464 -
  20.465 -    <para>If you're getting started with Mercurial, there's nothing to
  20.466 -      prevent you from using <command role="hg-cmd">hg serve</command>
  20.467 -      to serve up a repository on your own computer, then use commands
  20.468 -      like <command role="hg-cmd">hg clone</command>, <command
  20.469 -	role="hg-cmd">hg incoming</command>, and so on to talk to that
  20.470 -      server as if the repository was hosted remotely. This can help
  20.471 -      you to quickly get acquainted with using commands on
  20.472 -      network-hosted repositories.</para>
  20.473 -
  20.474 -    <sect2>
  20.475 -      <title>A few things to keep in mind</title>
  20.476 -
  20.477 -      <para>Because it provides unauthenticated read access to all
  20.478 -	clients, you should only use <command role="hg-cmd">hg
  20.479 -	  serve</command> in an environment where you either don't
  20.480 -	care, or have complete control over, who can access your
  20.481 -	network and pull data from your repository.</para>
  20.482 -
  20.483 -      <para>The <command role="hg-cmd">hg serve</command> command
  20.484 -	knows nothing about any firewall software you might have
  20.485 -	installed on your system or network.  It cannot detect or
  20.486 -	control your firewall software.  If other people are unable to
  20.487 -	talk to a running <command role="hg-cmd">hg serve</command>
  20.488 -	instance, the second thing you should do
  20.489 -	(<emphasis>after</emphasis> you make sure that they're using
  20.490 -	the correct URL) is check your firewall configuration.</para>
  20.491 -
  20.492 -      <para>By default, <command role="hg-cmd">hg serve</command>
  20.493 -	listens for incoming connections on port 8000.  If another
  20.494 -	process is already listening on the port you want to use, you
  20.495 -	can specify a different port to listen on using the <option
  20.496 -	  role="hg-opt-serve">-p</option> option.</para>
  20.497 -
  20.498 -      <para>Normally, when <command role="hg-cmd">hg serve</command>
  20.499 -	starts, it prints no output, which can be a bit unnerving.  If
  20.500 -	you'd like to confirm that it is indeed running correctly, and
  20.501 -	find out what URL you should send to your collaborators, start
  20.502 -	it with the <option role="hg-opt-global">-v</option>
  20.503 -	option.</para>
  20.504 -
  20.505 -    </sect2>
  20.506 -  </sect1>
  20.507 -  <sect1 id="sec.collab.ssh">
  20.508 -    <title>Using the Secure Shell (ssh) protocol</title>
  20.509 -
  20.510 -    <para>You can pull and push changes securely over a network
  20.511 -      connection using the Secure Shell (<literal>ssh</literal>)
  20.512 -      protocol.  To use this successfully, you may have to do a little
  20.513 -      bit of configuration on the client or server sides.</para>
  20.514 -
  20.515 -    <para>If you're not familiar with ssh, it's a network protocol
  20.516 -      that lets you securely communicate with another computer.  To
  20.517 -      use it with Mercurial, you'll be setting up one or more user
  20.518 -      accounts on a server so that remote users can log in and execute
  20.519 -      commands.</para>
  20.520 -
  20.521 -    <para>(If you <emphasis>are</emphasis> familiar with ssh, you'll
  20.522 -      probably find some of the material that follows to be elementary
  20.523 -      in nature.)</para>
  20.524 -
  20.525 -    <sect2>
  20.526 -      <title>How to read and write ssh URLs</title>
  20.527 -
  20.528 -      <para>An ssh URL tends to look like this:</para>
  20.529 -      <programlisting>ssh://bos@hg.serpentine.com:22/hg/hgbook</programlisting>
  20.530 -      <orderedlist>
  20.531 -	<listitem><para>The <quote><literal>ssh://</literal></quote>
  20.532 -	    part tells Mercurial to use the ssh protocol.</para>
  20.533 -	</listitem>
  20.534 -	<listitem><para>The <quote><literal>bos@</literal></quote>
  20.535 -	    component indicates what username to log into the server
  20.536 -	    as.  You can leave this out if the remote username is the
  20.537 -	    same as your local username.</para>
  20.538 -	</listitem>
  20.539 -	<listitem><para>The
  20.540 -	    <quote><literal>hg.serpentine.com</literal></quote> gives
  20.541 -	    the hostname of the server to log into.</para>
  20.542 -	</listitem>
  20.543 -	<listitem><para>The <quote>:22</quote> identifies the port
  20.544 -	    number to connect to the server on.  The default port is
  20.545 -	    22, so you only need to specify a colon and port number if
  20.546 -	    you're <emphasis>not</emphasis> using port 22.</para>
  20.547 -	</listitem>
  20.548 -	<listitem><para>The remainder of the URL is the local path to
  20.549 -	    the repository on the server.</para>
  20.550 -	</listitem></orderedlist>
  20.551 -
  20.552 -      <para>There's plenty of scope for confusion with the path
  20.553 -	component of ssh URLs, as there is no standard way for tools
  20.554 -	to interpret it.  Some programs behave differently than others
  20.555 -	when dealing with these paths. This isn't an ideal situation,
  20.556 -	but it's unlikely to change.  Please read the following
  20.557 -	paragraphs carefully.</para>
  20.558 -
  20.559 -      <para>Mercurial treats the path to a repository on the server as
  20.560 -	relative to the remote user's home directory.  For example, if
  20.561 -	user <literal>foo</literal> on the server has a home directory
  20.562 -	of <filename class="directory">/home/foo</filename>, then an
  20.563 -	ssh URL that contains a path component of <filename
  20.564 -	  class="directory">bar</filename> <emphasis>really</emphasis>
  20.565 -	refers to the directory <filename
  20.566 -	  class="directory">/home/foo/bar</filename>.</para>
  20.567 -
  20.568 -      <para>If you want to specify a path relative to another user's
  20.569 -	home directory, you can use a path that starts with a tilde
  20.570 -	character followed by the user's name (let's call them
  20.571 -	<literal>otheruser</literal>), like this.</para>
  20.572 -      <programlisting>ssh://server/~otheruser/hg/repo</programlisting>
  20.573 -
  20.574 -      <para>And if you really want to specify an
  20.575 -	<emphasis>absolute</emphasis> path on the server, begin the
  20.576 -	path component with two slashes, as in this example.</para>
  20.577 -      <programlisting>ssh://server//absolute/path</programlisting>
  20.578 -
  20.579 -    </sect2>
  20.580 -    <sect2>
  20.581 -      <title>Finding an ssh client for your system</title>
  20.582 -
  20.583 -      <para>Almost every Unix-like system comes with OpenSSH
  20.584 -	preinstalled.  If you're using such a system, run
  20.585 -	<literal>which ssh</literal> to find out if the
  20.586 -	<command>ssh</command> command is installed (it's usually in
  20.587 -	<filename class="directory">/usr/bin</filename>).  In the
  20.588 -	unlikely event that it isn't present, take a look at your
  20.589 -	system documentation to figure out how to install it.</para>
  20.590 -
  20.591 -      <para>On Windows, you'll first need to download a suitable ssh
  20.592 -	client.  There are two alternatives.</para>
  20.593 -      <itemizedlist>
  20.594 -	<listitem><para>Simon Tatham's excellent PuTTY package
  20.595 -	    <citation>web:putty</citation> provides a complete suite
  20.596 -	    of ssh client commands.</para>
  20.597 -	</listitem>
  20.598 -	<listitem><para>If you have a high tolerance for pain, you can
  20.599 -	    use the Cygwin port of OpenSSH.</para>
  20.600 -	</listitem></itemizedlist>
  20.601 -      <para>In either case, you'll need to edit your <filename
  20.602 -      role="special">hg.ini</filename> file to
  20.603 -	tell Mercurial where to find the actual client command.  For
  20.604 -	example, if you're using PuTTY, you'll need to use the
  20.605 -	<command>plink</command> command as a command-line ssh
  20.606 -	client.</para>
  20.607 -      <programlisting>[ui]
  20.608 -ssh = C:/path/to/plink.exe -ssh -i "C:/path/to/my/private/key"</programlisting>
  20.609 -
  20.610 -      <note>
  20.611 -	<para>  The path to <command>plink</command> shouldn't contain
  20.612 -	  any whitespace characters, or Mercurial may not be able to
  20.613 -	  run it correctly (so putting it in <filename
  20.614 -	    class="directory">C:\Program Files</filename> is probably
  20.615 -	  not a good idea).</para>
  20.616 -      </note>
  20.617 -
  20.618 -    </sect2>
  20.619 -    <sect2>
  20.620 -      <title>Generating a key pair</title>
  20.621 -
  20.622 -      <para>To avoid the need to repetitively type a password every
  20.623 -	time you need to use your ssh client, I recommend generating a
  20.624 -	key pair.  On a Unix-like system, the
  20.625 -	<command>ssh-keygen</command> command will do the trick. On
  20.626 -	Windows, if you're using PuTTY, the
  20.627 -	<command>puttygen</command> command is what you'll
  20.628 -	need.</para>
  20.629 -
  20.630 -      <para>When you generate a key pair, it's usually
  20.631 -	<emphasis>highly</emphasis> advisable to protect it with a
  20.632 -	passphrase.  (The only time that you might not want to do this
  20.633 -	is when you're using the ssh protocol for automated tasks on a
  20.634 -	secure network.)</para>
  20.635 -
  20.636 -      <para>Simply generating a key pair isn't enough, however.
  20.637 -	You'll need to add the public key to the set of authorised
  20.638 -	keys for whatever user you're logging in remotely as.  For
  20.639 -	servers using OpenSSH (the vast majority), this will mean
  20.640 -	adding the public key to a list in a file called <filename
  20.641 -	  role="special">authorized_keys</filename> in their <filename
  20.642 -	  role="special" class="directory">.ssh</filename>
  20.643 -	directory.</para>
  20.644 -
  20.645 -      <para>On a Unix-like system, your public key will have a
  20.646 -	<filename>.pub</filename> extension.  If you're using
  20.647 -	<command>puttygen</command> on Windows, you can save the
  20.648 -	public key to a file of your choosing, or paste it from the
  20.649 -	window it's displayed in straight into the <filename
  20.650 -	  role="special">authorized_keys</filename> file.</para>
  20.651 -
  20.652 -    </sect2>
  20.653 -    <sect2>
  20.654 -      <title>Using an authentication agent</title>
  20.655 -
  20.656 -      <para>An authentication agent is a daemon that stores
  20.657 -	passphrases in memory (so it will forget passphrases if you
  20.658 -	log out and log back in again). An ssh client will notice if
  20.659 -	it's running, and query it for a passphrase.  If there's no
  20.660 -	authentication agent running, or the agent doesn't store the
  20.661 -	necessary passphrase, you'll have to type your passphrase
  20.662 -	every time Mercurial tries to communicate with a server on
  20.663 -	your behalf (e.g. whenever you pull or push changes).</para>
  20.664 -
  20.665 -      <para>The downside of storing passphrases in an agent is that
  20.666 -	it's possible for a well-prepared attacker to recover the
  20.667 -	plain text of your passphrases, in some cases even if your
  20.668 -	system has been power-cycled. You should make your own
  20.669 -	judgment as to whether this is an acceptable risk.  It
  20.670 -	certainly saves a lot of repeated typing.</para>
  20.671 -
  20.672 -      <para>On Unix-like systems, the agent is called
  20.673 -	<command>ssh-agent</command>, and it's often run automatically
  20.674 -	for you when you log in.  You'll need to use the
  20.675 -	<command>ssh-add</command> command to add passphrases to the
  20.676 -	agent's store.  On Windows, if you're using PuTTY, the
  20.677 -	<command>pageant</command> command acts as the agent.  It adds
  20.678 -	an icon to your system tray that will let you manage stored
  20.679 -	passphrases.</para>
  20.680 -
  20.681 -    </sect2>
  20.682 -    <sect2>
  20.683 -      <title>Configuring the server side properly</title>
  20.684 -
  20.685 -      <para>Because ssh can be fiddly to set up if you're new to it,
  20.686 -	there's a variety of things that can go wrong.  Add Mercurial
  20.687 -	on top, and there's plenty more scope for head-scratching.
  20.688 -	Most of these potential problems occur on the server side, not
  20.689 -	the client side.  The good news is that once you've gotten a
  20.690 -	configuration working, it will usually continue to work
  20.691 -	indefinitely.</para>
  20.692 -
  20.693 -      <para>Before you try using Mercurial to talk to an ssh server,
  20.694 -	it's best to make sure that you can use the normal
  20.695 -	<command>ssh</command> or <command>putty</command> command to
  20.696 -	talk to the server first.  If you run into problems with using
  20.697 -	these commands directly, Mercurial surely won't work.  Worse,
  20.698 -	it will obscure the underlying problem.  Any time you want to
  20.699 -	debug ssh-related Mercurial problems, you should drop back to
  20.700 -	making sure that plain ssh client commands work first,
  20.701 -	<emphasis>before</emphasis> you worry about whether there's a
  20.702 -	problem with Mercurial.</para>
  20.703 -
  20.704 -      <para>The first thing to be sure of on the server side is that
  20.705 -	you can actually log in from another machine at all.  If you
  20.706 -	can't use <command>ssh</command> or <command>putty</command>
  20.707 -	to log in, the error message you get may give you a few hints
  20.708 -	as to what's wrong.  The most common problems are as
  20.709 -	follows.</para>
  20.710 -      <itemizedlist>
  20.711 -	<listitem><para>If you get a <quote>connection refused</quote>
  20.712 -	    error, either there isn't an SSH daemon running on the
  20.713 -	    server at all, or it's inaccessible due to firewall
  20.714 -	    configuration.</para>
  20.715 -	</listitem>
  20.716 -	<listitem><para>If you get a <quote>no route to host</quote>
  20.717 -	    error, you either have an incorrect address for the server
  20.718 -	    or a seriously locked down firewall that won't admit its
  20.719 -	    existence at all.</para>
  20.720 -	</listitem>
  20.721 -	<listitem><para>If you get a <quote>permission denied</quote>
  20.722 -	    error, you may have mistyped the username on the server,
  20.723 -	    or you could have mistyped your key's passphrase or the
  20.724 -	    remote user's password.</para>
  20.725 -	</listitem></itemizedlist>
  20.726 -      <para>In summary, if you're having trouble talking to the
  20.727 -	server's ssh daemon, first make sure that one is running at
  20.728 -	all.  On many systems it will be installed, but disabled, by
  20.729 -	default.  Once you're done with this step, you should then
  20.730 -	check that the server's firewall is configured to allow
  20.731 -	incoming connections on the port the ssh daemon is listening
  20.732 -	on (usually 22).  Don't worry about more exotic possibilities
  20.733 -	for misconfiguration until you've checked these two
  20.734 -	first.</para>
  20.735 -
  20.736 -      <para>If you're using an authentication agent on the client side
  20.737 -	to store passphrases for your keys, you ought to be able to
  20.738 -	log into the server without being prompted for a passphrase or
  20.739 -	a password.  If you're prompted for a passphrase, there are a
  20.740 -	few possible culprits.</para>
  20.741 -      <itemizedlist>
  20.742 -	<listitem><para>You might have forgotten to use
  20.743 -	    <command>ssh-add</command> or <command>pageant</command>
  20.744 -	    to store the passphrase.</para>
  20.745 -	</listitem>
  20.746 -	<listitem><para>You might have stored the passphrase for the
  20.747 -	    wrong key.</para>
  20.748 -	</listitem></itemizedlist>
  20.749 -      <para>If you're being prompted for the remote user's password,
  20.750 -	there are another few possible problems to check.</para>
  20.751 -      <itemizedlist>
  20.752 -	<listitem><para>Either the user's home directory or their
  20.753 -	    <filename role="special" class="directory">.ssh</filename>
  20.754 -	    directory might have excessively liberal permissions.  As
  20.755 -	    a result, the ssh daemon will not trust or read their
  20.756 -	    <filename role="special">authorized_keys</filename> file.
  20.757 -	    For example, a group-writable home or <filename
  20.758 -	      role="special" class="directory">.ssh</filename>
  20.759 -	    directory will often cause this symptom.</para>
  20.760 -	</listitem>
  20.761 -	<listitem><para>The user's <filename
  20.762 -	      role="special">authorized_keys</filename> file may have
  20.763 -	    a problem. If anyone other than the user owns or can write
  20.764 -	    to that file, the ssh daemon will not trust or read
  20.765 -	    it.</para>
  20.766 -	</listitem></itemizedlist>
  20.767 -
  20.768 -      <para>In the ideal world, you should be able to run the
  20.769 -	following command successfully, and it should print exactly
  20.770 -	one line of output, the current date and time.</para>
  20.771 -      <programlisting>ssh myserver date</programlisting>
  20.772 -
  20.773 -      <para>If, on your server, you have login scripts that print
  20.774 -	banners or other junk even when running non-interactive
  20.775 -	commands like this, you should fix them before you continue,
  20.776 -	so that they only print output if they're run interactively.
  20.777 -	Otherwise these banners will at least clutter up Mercurial's
  20.778 -	output.  Worse, they could potentially cause problems with
  20.779 -	running Mercurial commands remotely.  Mercurial makes tries to
  20.780 -	detect and ignore banners in non-interactive
  20.781 -	<command>ssh</command> sessions, but it is not foolproof.  (If
  20.782 -	you're editing your login scripts on your server, the usual
  20.783 -	way to see if a login script is running in an interactive
  20.784 -	shell is to check the return code from the command
  20.785 -	<literal>tty -s</literal>.)</para>
  20.786 -
  20.787 -      <para>Once you've verified that plain old ssh is working with
  20.788 -	your server, the next step is to ensure that Mercurial runs on
  20.789 -	the server.  The following command should run
  20.790 -	successfully:</para>
  20.791 -
  20.792 -      <programlisting>ssh myserver hg version</programlisting>
  20.793 -
  20.794 -      <para>If you see an error message instead of normal <command
  20.795 -	  role="hg-cmd">hg version</command> output, this is usually
  20.796 -	because you haven't installed Mercurial to <filename
  20.797 -	  class="directory">/usr/bin</filename>.  Don't worry if this
  20.798 -	is the case; you don't need to do that.  But you should check
  20.799 -	for a few possible problems.</para>
  20.800 -      <itemizedlist>
  20.801 -	<listitem><para>Is Mercurial really installed on the server at
  20.802 -	    all?  I know this sounds trivial, but it's worth
  20.803 -	    checking!</para>
  20.804 -	</listitem>
  20.805 -	<listitem><para>Maybe your shell's search path (usually set
  20.806 -	    via the <envar>PATH</envar> environment variable) is
  20.807 -	    simply misconfigured.</para>
  20.808 -	</listitem>
  20.809 -	<listitem><para>Perhaps your <envar>PATH</envar> environment
  20.810 -	    variable is only being set to point to the location of the
  20.811 -	    <command>hg</command> executable if the login session is
  20.812 -	    interactive.  This can happen if you're setting the path
  20.813 -	    in the wrong shell login script.  See your shell's
  20.814 -	    documentation for details.</para>
  20.815 -	</listitem>
  20.816 -	<listitem><para>The <envar>PYTHONPATH</envar> environment
  20.817 -	    variable may need to contain the path to the Mercurial
  20.818 -	    Python modules.  It might not be set at all; it could be
  20.819 -	    incorrect; or it may be set only if the login is
  20.820 -	    interactive.</para>
  20.821 -	</listitem></itemizedlist>
  20.822 -
  20.823 -      <para>If you can run <command role="hg-cmd">hg version</command>
  20.824 -	over an ssh connection, well done! You've got the server and
  20.825 -	client sorted out.  You should now be able to use Mercurial to
  20.826 -	access repositories hosted by that username on that server.
  20.827 -	If you run into problems with Mercurial and ssh at this point,
  20.828 -	try using the <option role="hg-opt-global">--debug</option>
  20.829 -	option to get a clearer picture of what's going on.</para>
  20.830 -
  20.831 -    </sect2>
  20.832 -    <sect2>
  20.833 -      <title>Using compression with ssh</title>
  20.834 -
  20.835 -      <para>Mercurial does not compress data when it uses the ssh
  20.836 -	protocol, because the ssh protocol can transparently compress
  20.837 -	data.  However, the default behaviour of ssh clients is
  20.838 -	<emphasis>not</emphasis> to request compression.</para>
  20.839 -
  20.840 -      <para>Over any network other than a fast LAN (even a wireless
  20.841 -	network), using compression is likely to significantly speed
  20.842 -	up Mercurial's network operations.  For example, over a WAN,
  20.843 -	someone measured compression as reducing the amount of time
  20.844 -	required to clone a particularly large repository from 51
  20.845 -	minutes to 17 minutes.</para>
  20.846 -
  20.847 -      <para>Both <command>ssh</command> and <command>plink</command>
  20.848 -	accept a <option role="cmd-opt-ssh">-C</option> option which
  20.849 -	turns on compression.  You can easily edit your <filename
  20.850 -	  role="special">~/.hgrc</filename> to enable compression for
  20.851 -	all of Mercurial's uses of the ssh protocol.</para>
  20.852 -      <programlisting>[ui]
  20.853 -ssh = ssh -C</programlisting>
  20.854 -
  20.855 -      <para>If you use <command>ssh</command>, you can configure it to
  20.856 -	always use compression when talking to your server.  To do
  20.857 -	this, edit your <filename
  20.858 -	  role="special">.ssh/config</filename> file (which may not
  20.859 -	yet exist), as follows.</para>
  20.860 -      <programlisting>Host hg
  20.861 -  Compression yes
  20.862 -  HostName hg.example.com</programlisting>
  20.863 -      <para>This defines an alias, <literal>hg</literal>.  When you
  20.864 -	use it on the <command>ssh</command> command line or in a
  20.865 -	Mercurial <literal>ssh</literal>-protocol URL, it will cause
  20.866 -	<command>ssh</command> to connect to
  20.867 -	<literal>hg.example.com</literal> and use compression.  This
  20.868 -	gives you both a shorter name to type and compression, each of
  20.869 -	which is a good thing in its own right.</para>
  20.870 -
  20.871 -    </sect2>
  20.872 -  </sect1>
  20.873 -  <sect1 id="sec.collab.cgi">
  20.874 -    <title>Serving over HTTP using CGI</title>
  20.875 -
  20.876 -    <para>Depending on how ambitious you are, configuring Mercurial's
  20.877 -      CGI interface can take anything from a few moments to several
  20.878 -      hours.</para>
  20.879 -
  20.880 -    <para>We'll begin with the simplest of examples, and work our way
  20.881 -      towards a more complex configuration.  Even for the most basic
  20.882 -      case, you're almost certainly going to need to read and modify
  20.883 -      your web server's configuration.</para>
  20.884 -
  20.885 -    <note>
  20.886 -      <para>  Configuring a web server is a complex, fiddly, and
  20.887 -	highly system-dependent activity.  I can't possibly give you
  20.888 -	instructions that will cover anything like all of the cases
  20.889 -	you will encounter. Please use your discretion and judgment in
  20.890 -	following the sections below.  Be prepared to make plenty of
  20.891 -	mistakes, and to spend a lot of time reading your server's
  20.892 -	error logs.</para>
  20.893 -    </note>
  20.894 -
  20.895 -    <sect2>
  20.896 -      <title>Web server configuration checklist</title>
  20.897 -
  20.898 -      <para>Before you continue, do take a few moments to check a few
  20.899 -	aspects of your system's setup.</para>
  20.900 -
  20.901 -      <orderedlist>
  20.902 -	<listitem><para>Do you have a web server installed at all?
  20.903 -	    Mac OS X ships with Apache, but many other systems may not
  20.904 -	    have a web server installed.</para>
  20.905 -	</listitem>
  20.906 -	<listitem><para>If you have a web server installed, is it
  20.907 -	    actually running?  On most systems, even if one is
  20.908 -	    present, it will be disabled by default.</para>
  20.909 -	</listitem>
  20.910 -	<listitem><para>Is your server configured to allow you to run
  20.911 -	    CGI programs in the directory where you plan to do so?
  20.912 -	    Most servers default to explicitly disabling the ability
  20.913 -	    to run CGI programs.</para>
  20.914 -	</listitem></orderedlist>
  20.915 -
  20.916 -      <para>If you don't have a web server installed, and don't have
  20.917 -	substantial experience configuring Apache, you should consider
  20.918 -	using the <literal>lighttpd</literal> web server instead of
  20.919 -	Apache.  Apache has a well-deserved reputation for baroque and
  20.920 -	confusing configuration. While <literal>lighttpd</literal> is
  20.921 -	less capable in some ways than Apache, most of these
  20.922 -	capabilities are not relevant to serving Mercurial
  20.923 -	repositories.  And <literal>lighttpd</literal> is undeniably
  20.924 -	<emphasis>much</emphasis> easier to get started with than
  20.925 -	Apache.</para>
  20.926 -
  20.927 -    </sect2>
  20.928 -    <sect2>
  20.929 -      <title>Basic CGI configuration</title>
  20.930 -
  20.931 -      <para>On Unix-like systems, it's common for users to have a
  20.932 -	subdirectory named something like <filename
  20.933 -	  class="directory">public_html</filename> in their home
  20.934 -	directory, from which they can serve up web pages.  A file
  20.935 -	named <filename>foo</filename> in this directory will be
  20.936 -	accessible at a URL of the form
  20.937 -	<literal>http://www.example.com/username/foo</literal>.</para>
  20.938 -
  20.939 -      <para>To get started, find the <filename
  20.940 -	  role="special">hgweb.cgi</filename> script that should be
  20.941 -	present in your Mercurial installation.  If you can't quickly
  20.942 -	find a local copy on your system, simply download one from the
  20.943 -	master Mercurial repository at <ulink
  20.944 -	  url="http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi">http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi</ulink>.</para>
  20.945 -
  20.946 -      <para>You'll need to copy this script into your <filename
  20.947 -	  class="directory">public_html</filename> directory, and
  20.948 -	ensure that it's executable.</para>
  20.949 -      <programlisting>cp .../hgweb.cgi ~/public_html
  20.950 -chmod 755 ~/public_html/hgweb.cgi</programlisting>
  20.951 -      <para>The <literal>755</literal> argument to
  20.952 -	<command>chmod</command> is a little more general than just
  20.953 -	making the script executable: it ensures that the script is
  20.954 -	executable by anyone, and that <quote>group</quote> and
  20.955 -	<quote>other</quote> write permissions are
  20.956 -	<emphasis>not</emphasis> set.  If you were to leave those
  20.957 -	write permissions enabled, Apache's <literal>suexec</literal>
  20.958 -	subsystem would likely refuse to execute the script.  In fact,
  20.959 -	<literal>suexec</literal> also insists that the
  20.960 -	<emphasis>directory</emphasis> in which the script resides
  20.961 -	must not be writable by others.</para>
  20.962 -      <programlisting>chmod 755 ~/public_html</programlisting>
  20.963 -
  20.964 -      <sect3 id="sec.collab.wtf">
  20.965 -	<title>What could <emphasis>possibly</emphasis> go
  20.966 -	  wrong?</title>
  20.967 -
  20.968 -	<para>Once you've copied the CGI script into place, go into a
  20.969 -	  web browser, and try to open the URL <ulink
  20.970 -	    url="http://myhostname/
  20.971 -	    myuser/hgweb.cgi">http://myhostname/
  20.972 -	    myuser/hgweb.cgi</ulink>, <emphasis>but</emphasis> brace
  20.973 -	  yourself for instant failure.  There's a high probability
  20.974 -	  that trying to visit this URL will fail, and there are many
  20.975 -	  possible reasons for this.  In fact, you're likely to
  20.976 -	  stumble over almost every one of the possible errors below,
  20.977 -	  so please read carefully.  The following are all of the
  20.978 -	  problems I ran into on a system running Fedora 7, with a
  20.979 -	  fresh installation of Apache, and a user account that I
  20.980 -	  created specially to perform this exercise.</para>
  20.981 -
  20.982 -	<para>Your web server may have per-user directories disabled.
  20.983 -	  If you're using Apache, search your config file for a
  20.984 -	  <literal>UserDir</literal> directive.  If there's none
  20.985 -	  present, per-user directories will be disabled.  If one
  20.986 -	  exists, but its value is <literal>disabled</literal>, then
  20.987 -	  per-user directories will be disabled.  Otherwise, the
  20.988 -	  string after <literal>UserDir</literal> gives the name of
  20.989 -	  the subdirectory that Apache will look in under your home
  20.990 -	  directory, for example <filename
  20.991 -	    class="directory">public_html</filename>.</para>
  20.992 -
  20.993 -	<para>Your file access permissions may be too restrictive.
  20.994 -	  The web server must be able to traverse your home directory
  20.995 -	  and directories under your <filename
  20.996 -	    class="directory">public_html</filename> directory, and
  20.997 -	  read files under the latter too.  Here's a quick recipe to
  20.998 -	  help you to make your permissions more appropriate.</para>
  20.999 -	<programlisting>chmod 755 ~
 20.1000 -find ~/public_html -type d -print0 | xargs -0r chmod 755
 20.1001 -find ~/public_html -type f -print0 | xargs -0r chmod 644</programlisting>
 20.1002 -
 20.1003 -	<para>The other possibility with permissions is that you might
 20.1004 -	  get a completely empty window when you try to load the
 20.1005 -	  script.  In this case, it's likely that your access
 20.1006 -	  permissions are <emphasis>too permissive</emphasis>.  Apache's
 20.1007 -	  <literal>suexec</literal> subsystem won't execute a script
 20.1008 -	  that's group- or world-writable, for example.</para>
 20.1009 -
 20.1010 -	<para>Your web server may be configured to disallow execution
 20.1011 -	  of CGI programs in your per-user web directory.  Here's
 20.1012 -	  Apache's default per-user configuration from my Fedora
 20.1013 -	  system.</para>
 20.1014 -
 20.1015 -	<programlisting><![CDATA[&ch06-apache-config.lst;]]></programlisting>
 20.1016 -
 20.1017 -	<para>If you find a similar-looking
 20.1018 -	  <literal>Directory</literal> group in your Apache
 20.1019 -	  configuration, the directive to look at inside it is
 20.1020 -	  <literal>Options</literal>. Add <literal>ExecCGI</literal>
 20.1021 -	  to the end of this list if it's missing, and restart the web
 20.1022 -	  server.</para>
 20.1023 -
 20.1024 -	<para>If you find that Apache serves you the text of the CGI
 20.1025 -	  script instead of executing it, you may need to either
 20.1026 -	  uncomment (if already present) or add a directive like
 20.1027 -	  this.</para>
 20.1028 -	<programlisting>AddHandler cgi-script .cgi</programlisting>
 20.1029 -
 20.1030 -	<para>The next possibility is that you might be served with a
 20.1031 -	  colourful Python backtrace claiming that it can't import a
 20.1032 -	  <literal>mercurial</literal>-related module.  This is
 20.1033 -	  actually progress!  The server is now capable of executing
 20.1034 -	  your CGI script.  This error is only likely to occur if
 20.1035 -	  you're running a private installation of Mercurial, instead
 20.1036 -	  of a system-wide version.  Remember that the web server runs
 20.1037 -	  the CGI program without any of the environment variables
 20.1038 -	  that you take for granted in an interactive session.  If
 20.1039 -	  this error happens to you, edit your copy of <filename
 20.1040 -	    role="special">hgweb.cgi</filename> and follow the
 20.1041 -	  directions inside it to correctly set your
 20.1042 -	  <envar>PYTHONPATH</envar> environment variable.</para>
 20.1043 -
 20.1044 -	<para>Finally, you are <emphasis>certain</emphasis> to by
 20.1045 -	  served with another colourful Python backtrace: this one
 20.1046 -	  will complain that it can't find <filename
 20.1047 -	    class="directory">/path/to/repository</filename>.  Edit
 20.1048 -	  your <filename role="special">hgweb.cgi</filename> script
 20.1049 -	  and replace the <filename
 20.1050 -	    class="directory">/path/to/repository</filename> string
 20.1051 -	  with the complete path to the repository you want to serve
 20.1052 -	  up.</para>
 20.1053 -
 20.1054 -	<para>At this point, when you try to reload the page, you
 20.1055 -	  should be presented with a nice HTML view of your
 20.1056 -	  repository's history.  Whew!</para>
 20.1057 -
 20.1058 -      </sect3>
 20.1059 -      <sect3>
 20.1060 -	<title>Configuring lighttpd</title>
 20.1061 -
 20.1062 -	<para>To be exhaustive in my experiments, I tried configuring
 20.1063 -	  the increasingly popular <literal>lighttpd</literal> web
 20.1064 -	  server to serve the same repository as I described with
 20.1065 -	  Apache above.  I had already overcome all of the problems I
 20.1066 -	  outlined with Apache, many of which are not server-specific.
 20.1067 -	  As a result, I was fairly sure that my file and directory
 20.1068 -	  permissions were good, and that my <filename
 20.1069 -	    role="special">hgweb.cgi</filename> script was properly
 20.1070 -	  edited.</para>
 20.1071 -
 20.1072 -	<para>Once I had Apache running, getting
 20.1073 -	  <literal>lighttpd</literal> to serve the repository was a
 20.1074 -	  snap (in other words, even if you're trying to use
 20.1075 -	  <literal>lighttpd</literal>, you should read the Apache
 20.1076 -	  section).  I first had to edit the
 20.1077 -	  <literal>mod_access</literal> section of its config file to
 20.1078 -	  enable <literal>mod_cgi</literal> and
 20.1079 -	  <literal>mod_userdir</literal>, both of which were disabled
 20.1080 -	  by default on my system.  I then added a few lines to the
 20.1081 -	  end of the config file, to configure these modules.</para>
 20.1082 -	<programlisting>userdir.path = "public_html"
 20.1083 -cgi.assign = (".cgi" =&gt; "" )</programlisting>
 20.1084 -	<para>With this done, <literal>lighttpd</literal> ran
 20.1085 -	  immediately for me.  If I had configured
 20.1086 -	  <literal>lighttpd</literal> before Apache, I'd almost
 20.1087 -	  certainly have run into many of the same system-level
 20.1088 -	  configuration problems as I did with Apache.  However, I
 20.1089 -	  found <literal>lighttpd</literal> to be noticeably easier to
 20.1090 -	  configure than Apache, even though I've used Apache for over
 20.1091 -	  a decade, and this was my first exposure to
 20.1092 -	  <literal>lighttpd</literal>.</para>
 20.1093 -
 20.1094 -      </sect3>
 20.1095 -    </sect2>
 20.1096 -    <sect2>
 20.1097 -      <title>Sharing multiple repositories with one CGI script</title>
 20.1098 -
 20.1099 -      <para>The <filename role="special">hgweb.cgi</filename> script
 20.1100 -	only lets you publish a single repository, which is an
 20.1101 -	annoying restriction.  If you want to publish more than one
 20.1102 -	without wracking yourself with multiple copies of the same
 20.1103 -	script, each with different names, a better choice is to use
 20.1104 -	the <filename role="special">hgwebdir.cgi</filename>
 20.1105 -	script.</para>
 20.1106 -
 20.1107 -      <para>The procedure to configure <filename
 20.1108 -	  role="special">hgwebdir.cgi</filename> is only a little more
 20.1109 -	involved than for <filename
 20.1110 -	  role="special">hgweb.cgi</filename>.  First, you must obtain
 20.1111 -	a copy of the script.  If you don't have one handy, you can
 20.1112 -	download a copy from the master Mercurial repository at <ulink
 20.1113 -	  url="http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi">http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi</ulink>.</para>
 20.1114 -
 20.1115 -      <para>You'll need to copy this script into your <filename
 20.1116 -	  class="directory">public_html</filename> directory, and
 20.1117 -	ensure that it's executable.</para>
 20.1118 -      <programlisting>cp .../hgwebdir.cgi ~/public_html
 20.1119 -chmod 755 ~/public_html ~/public_html/hgwebdir.cgi</programlisting>
 20.1120 -      <para>With basic configuration out of the way, try to visit
 20.1121 -	<ulink url="http://myhostname/
 20.1122 -	  myuser/hgwebdir.cgi">http://myhostname/
 20.1123 -	  myuser/hgwebdir.cgi</ulink> in your browser.  It should
 20.1124 -	display an empty list of repositories.  If you get a blank
 20.1125 -	window or error message, try walking through the list of
 20.1126 -	potential problems in section <xref
 20.1127 -	  linkend="sec.collab.wtf"/>.</para>
 20.1128 -
 20.1129 -      <para>The <filename role="special">hgwebdir.cgi</filename>
 20.1130 -	script relies on an external configuration file.  By default,
 20.1131 -	it searches for a file named <filename
 20.1132 -	  role="special">hgweb.config</filename> in the same directory
 20.1133 -	as itself.  You'll need to create this file, and make it
 20.1134 -	world-readable.  The format of the file is similar to a
 20.1135 -	Windows <quote>ini</quote> file, as understood by Python's
 20.1136 -	<literal>ConfigParser</literal>
 20.1137 -	<citation>web:configparser</citation> module.</para>
 20.1138 -
 20.1139 -      <para>The easiest way to configure <filename
 20.1140 -	  role="special">hgwebdir.cgi</filename> is with a section
 20.1141 -	named <literal>collections</literal>.  This will automatically
 20.1142 -	publish <emphasis>every</emphasis> repository under the
 20.1143 -	directories you name.  The section should look like
 20.1144 -	this:</para>
 20.1145 -      <programlisting>[collections]
 20.1146 -/my/root = /my/root</programlisting>
 20.1147 -      <para>Mercurial interprets this by looking at the directory name
 20.1148 -	on the <emphasis>right</emphasis> hand side of the
 20.1149 -	<quote><literal>=</literal></quote> sign; finding repositories
 20.1150 -	in that directory hierarchy; and using the text on the
 20.1151 -	<emphasis>left</emphasis> to strip off matching text from the
 20.1152 -	names it will actually list in the web interface.  The
 20.1153 -	remaining component of a path after this stripping has
 20.1154 -	occurred is called a <quote>virtual path</quote>.</para>
 20.1155 -
 20.1156 -      <para>Given the example above, if we have a repository whose
 20.1157 -	local path is <filename
 20.1158 -	  class="directory">/my/root/this/repo</filename>, the CGI
 20.1159 -	script will strip the leading <filename
 20.1160 -	  class="directory">/my/root</filename> from the name, and
 20.1161 -	publish the repository with a virtual path of <filename
 20.1162 -	  class="directory">this/repo</filename>.  If the base URL for
 20.1163 -	our CGI script is <ulink url="http://myhostname/
 20.1164 -	  myuser/hgwebdir.cgi">http://myhostname/
 20.1165 -	  myuser/hgwebdir.cgi</ulink>, the complete URL for that
 20.1166 -	repository will be <ulink url="http://myhostname/
 20.1167 -	  myuser/hgwebdir.cgi/this/repo">http://myhostname/
 20.1168 -	  myuser/hgwebdir.cgi/this/repo</ulink>.</para>
 20.1169 -
 20.1170 -      <para>If we replace <filename
 20.1171 -	  class="directory">/my/root</filename> on the left hand side
 20.1172 -	of this example with <filename
 20.1173 -	  class="directory">/my</filename>, then <filename
 20.1174 -	  role="special">hgwebdir.cgi</filename> will only strip off
 20.1175 -	<filename class="directory">/my</filename> from the repository
 20.1176 -	name, and will give us a virtual path of <filename
 20.1177 -	  class="directory">root/this/repo</filename> instead of
 20.1178 -	<filename class="directory">this/repo</filename>.</para>
 20.1179 -
 20.1180 -      <para>The <filename role="special">hgwebdir.cgi</filename>
 20.1181 -	script will recursively search each directory listed in the
 20.1182 -	<literal>collections</literal> section of its configuration
 20.1183 -	file, but it will <literal>not</literal> recurse into the
 20.1184 -	repositories it finds.</para>
 20.1185 -
 20.1186 -      <para>The <literal>collections</literal> mechanism makes it easy
 20.1187 -	to publish many repositories in a <quote>fire and
 20.1188 -	  forget</quote> manner.  You only need to set up the CGI
 20.1189 -	script and configuration file one time.  Afterwards, you can
 20.1190 -	publish or unpublish a repository at any time by simply moving
 20.1191 -	it into, or out of, the directory hierarchy in which you've
 20.1192 -	configured <filename role="special">hgwebdir.cgi</filename> to
 20.1193 -	look.</para>
 20.1194 -
 20.1195 -      <sect3>
 20.1196 -	<title>Explicitly specifying which repositories to
 20.1197 -	  publish</title>
 20.1198 -
 20.1199 -	<para>In addition to the <literal>collections</literal>
 20.1200 -	  mechanism, the <filename
 20.1201 -	    role="special">hgwebdir.cgi</filename> script allows you
 20.1202 -	  to publish a specific list of repositories.  To do so,
 20.1203 -	  create a <literal>paths</literal> section, with contents of
 20.1204 -	  the following form.</para>
 20.1205 -	<programlisting>[paths]
 20.1206 -repo1 = /my/path/to/some/repo
 20.1207 -repo2 = /some/path/to/another</programlisting>
 20.1208 -	<para>In this case, the virtual path (the component that will
 20.1209 -	  appear in a URL) is on the left hand side of each
 20.1210 -	  definition, while the path to the repository is on the
 20.1211 -	  right.  Notice that there does not need to be any
 20.1212 -	  relationship between the virtual path you choose and the
 20.1213 -	  location of a repository in your filesystem.</para>
 20.1214 -
 20.1215 -	<para>If you wish, you can use both the
 20.1216 -	  <literal>collections</literal> and <literal>paths</literal>
 20.1217 -	  mechanisms simultaneously in a single configuration
 20.1218 -	  file.</para>
 20.1219 -
 20.1220 -	<note>
 20.1221 -	  <para>  If multiple repositories have the same virtual path,
 20.1222 -	    <filename role="special">hgwebdir.cgi</filename> will not
 20.1223 -	    report an error.  Instead, it will behave
 20.1224 -	    unpredictably.</para>
 20.1225 -	</note>
 20.1226 -
 20.1227 -      </sect3>
 20.1228 -    </sect2>
 20.1229 -    <sect2>
 20.1230 -      <title>Downloading source archives</title>
 20.1231 -
 20.1232 -      <para>Mercurial's web interface lets users download an archive
 20.1233 -	of any revision.  This archive will contain a snapshot of the
 20.1234 -	working directory as of that revision, but it will not contain
 20.1235 -	a copy of the repository data.</para>
 20.1236 -
 20.1237 -      <para>By default, this feature is not enabled.  To enable it,
 20.1238 -	you'll need to add an <envar
 20.1239 -	  role="rc-item-web">allow_archive</envar> item to the
 20.1240 -	<literal role="rc-web">web</literal> section of your <filename
 20.1241 -	  role="special">~/.hgrc</filename>.</para>
 20.1242 -
 20.1243 -    </sect2>
 20.1244 -    <sect2>
 20.1245 -      <title>Web configuration options</title>
 20.1246 -
 20.1247 -      <para>Mercurial's web interfaces (the <command role="hg-cmd">hg
 20.1248 -	  serve</command> command, and the <filename
 20.1249 -	  role="special">hgweb.cgi</filename> and <filename
 20.1250 -	  role="special">hgwebdir.cgi</filename> scripts) have a
 20.1251 -	number of configuration options that you can set.  These
 20.1252 -	belong in a section named <literal
 20.1253 -	  role="rc-web">web</literal>.</para>
 20.1254 -      <itemizedlist>
 20.1255 -	<listitem><para><envar
 20.1256 -	      role="rc-item-web">allow_archive</envar>: Determines
 20.1257 -	    which (if any) archive download mechanisms Mercurial
 20.1258 -	    supports.  If you enable this feature, users of the web
 20.1259 -	    interface will be able to download an archive of whatever
 20.1260 -	    revision of a repository they are viewing. To enable the
 20.1261 -	    archive feature, this item must take the form of a
 20.1262 -	    sequence of words drawn from the list below.</para>
 20.1263 -	  <itemizedlist>
 20.1264 -	    <listitem><para><literal>bz2</literal>: A
 20.1265 -		<command>tar</command> archive, compressed using
 20.1266 -		<literal>bzip2</literal> compression.  This has the
 20.1267 -		best compression ratio, but uses the most CPU time on
 20.1268 -		the server.</para>
 20.1269 -	    </listitem>
 20.1270 -	    <listitem><para><literal>gz</literal>: A
 20.1271 -		<command>tar</command> archive, compressed using
 20.1272 -		<literal>gzip</literal> compression.</para>
 20.1273 -	    </listitem>
 20.1274 -	    <listitem><para><literal>zip</literal>: A
 20.1275 -		<command>zip</command> archive, compressed using LZW
 20.1276 -		compression.  This format has the worst compression
 20.1277 -		ratio, but is widely used in the Windows world.</para>
 20.1278 -	    </listitem>
 20.1279 -	  </itemizedlist>
 20.1280 -	  <para>  If you provide an empty list, or don't have an
 20.1281 -	    <envar role="rc-item-web">allow_archive</envar> entry at
 20.1282 -	    all, this feature will be disabled.  Here is an example of
 20.1283 -	    how to enable all three supported formats.</para>
 20.1284 -	  <programlisting>[web]
 20.1285 -allow_archive = bz2 gz zip</programlisting>
 20.1286 -	</listitem>
 20.1287 -	<listitem><para><envar role="rc-item-web">allowpull</envar>:
 20.1288 -	    Boolean.  Determines whether the web interface allows
 20.1289 -	    remote users to <command role="hg-cmd">hg pull</command>
 20.1290 -	    and <command role="hg-cmd">hg clone</command> this
 20.1291 -	    repository over HTTP.  If set to <literal>no</literal> or
 20.1292 -	    <literal>false</literal>, only the
 20.1293 -	    <quote>human-oriented</quote> portion of the web interface
 20.1294 -	    is available.</para>
 20.1295 -	</listitem>
 20.1296 -	<listitem><para><envar role="rc-item-web">contact</envar>:
 20.1297 -	    String.  A free-form (but preferably brief) string
 20.1298 -	    identifying the person or group in charge of the
 20.1299 -	    repository.  This often contains the name and email
 20.1300 -	    address of a person or mailing list.  It often makes sense
 20.1301 -	    to place this entry in a repository's own <filename
 20.1302 -	      role="special">.hg/hgrc</filename> file, but it can make
 20.1303 -	    sense to use in a global <filename
 20.1304 -	      role="special">~/.hgrc</filename> if every repository
 20.1305 -	    has a single maintainer.</para>
 20.1306 -	</listitem>
 20.1307 -	<listitem><para><envar role="rc-item-web">maxchanges</envar>:
 20.1308 -	    Integer.  The default maximum number of changesets to
 20.1309 -	    display in a single page of output.</para>
 20.1310 -	</listitem>
 20.1311 -	<listitem><para><envar role="rc-item-web">maxfiles</envar>:
 20.1312 -	    Integer.  The default maximum number of modified files to
 20.1313 -	    display in a single page of output.</para>
 20.1314 -	</listitem>
 20.1315 -	<listitem><para><envar role="rc-item-web">stripes</envar>:
 20.1316 -	    Integer.  If the web interface displays alternating
 20.1317 -	    <quote>stripes</quote> to make it easier to visually align
 20.1318 -	    rows when you are looking at a table, this number controls
 20.1319 -	    the number of rows in each stripe.</para>
 20.1320 -	</listitem>
 20.1321 -	<listitem><para><envar role="rc-item-web">style</envar>:
 20.1322 -	    Controls the template Mercurial uses to display the web
 20.1323 -	    interface.  Mercurial ships with two web templates, named
 20.1324 -	    <literal>default</literal> and <literal>gitweb</literal>
 20.1325 -	    (the latter is much more visually attractive).  You can
 20.1326 -	    also specify a custom template of your own; see chapter
 20.1327 -	    <xref linkend="chap.template"/> for details.
 20.1328 -	    Here, you can see how to enable the
 20.1329 -	    <literal>gitweb</literal> style.</para>
 20.1330 -	  <programlisting>[web]
 20.1331 -style = gitweb</programlisting>
 20.1332 -	</listitem>
 20.1333 -	<listitem><para><envar role="rc-item-web">templates</envar>:
 20.1334 -	    Path.  The directory in which to search for template
 20.1335 -	    files.  By default, Mercurial searches in the directory in
 20.1336 -	    which it was installed.</para>
 20.1337 -	</listitem></itemizedlist>
 20.1338 -      <para>If you are using <filename
 20.1339 -	  role="special">hgwebdir.cgi</filename>, you can place a few
 20.1340 -	configuration items in a <literal role="rc-web">web</literal>
 20.1341 -	section of the <filename
 20.1342 -	  role="special">hgweb.config</filename> file instead of a
 20.1343 -	<filename role="special">~/.hgrc</filename> file, for
 20.1344 -	convenience.  These items are <envar
 20.1345 -	  role="rc-item-web">motd</envar> and <envar
 20.1346 -	  role="rc-item-web">style</envar>.</para>
 20.1347 -
 20.1348 -      <sect3>
 20.1349 -	<title>Options specific to an individual repository</title>
 20.1350 -
 20.1351 -	<para>A few <literal role="rc-web">web</literal> configuration
 20.1352 -	  items ought to be placed in a repository's local <filename
 20.1353 -	    role="special">.hg/hgrc</filename>, rather than a user's
 20.1354 -	  or global <filename role="special">~/.hgrc</filename>.</para>
 20.1355 -	<itemizedlist>
 20.1356 -	  <listitem><para><envar
 20.1357 -		role="rc-item-web">description</envar>: String.  A
 20.1358 -	      free-form (but preferably brief) string that describes
 20.1359 -	      the contents or purpose of the repository.</para>
 20.1360 -	  </listitem>
 20.1361 -	  <listitem><para><envar role="rc-item-web">name</envar>:
 20.1362 -	      String.  The name to use for the repository in the web
 20.1363 -	      interface.  This overrides the default name, which is
 20.1364 -	      the last component of the repository's path.</para>
 20.1365 -	  </listitem></itemizedlist>
 20.1366 -
 20.1367 -      </sect3>
 20.1368 -      <sect3>
 20.1369 -	<title>Options specific to the <command role="hg-cmd">hg
 20.1370 -	    serve</command> command</title>
 20.1371 -
 20.1372 -	<para>Some of the items in the <literal
 20.1373 -	    role="rc-web">web</literal> section of a <filename
 20.1374 -	    role="special">~/.hgrc</filename> file are only for use
 20.1375 -	  with the <command role="hg-cmd">hg serve</command>
 20.1376 -	  command.</para>
 20.1377 -	<itemizedlist>
 20.1378 -	  <listitem><para><envar role="rc-item-web">accesslog</envar>:
 20.1379 -	      Path.  The name of a file into which to write an access
 20.1380 -	      log.  By default, the <command role="hg-cmd">hg
 20.1381 -		serve</command> command writes this information to
 20.1382 -	      standard output, not to a file.  Log entries are written
 20.1383 -	      in the standard <quote>combined</quote> file format used
 20.1384 -	      by almost all web servers.</para>
 20.1385 -	  </listitem>
 20.1386 -	  <listitem><para><envar role="rc-item-web">address</envar>:
 20.1387 -	      String.  The local address on which the server should
 20.1388 -	      listen for incoming connections.  By default, the server
 20.1389 -	      listens on all addresses.</para>
 20.1390 -	  </listitem>
 20.1391 -	  <listitem><para><envar role="rc-item-web">errorlog</envar>:
 20.1392 -	      Path.  The name of a file into which to write an error
 20.1393 -	      log.  By default, the <command role="hg-cmd">hg
 20.1394 -		serve</command> command writes this information to
 20.1395 -	      standard error, not to a file.</para>
 20.1396 -	  </listitem>
 20.1397 -	  <listitem><para><envar role="rc-item-web">ipv6</envar>:
 20.1398 -	      Boolean.  Whether to use the IPv6 protocol. By default,
 20.1399 -	      IPv6 is not used.</para>
 20.1400 -	  </listitem>
 20.1401 -	  <listitem><para><envar role="rc-item-web">port</envar>:
 20.1402 -	      Integer.  The TCP port number on which the server should
 20.1403 -	      listen.  The default port number used is 8000.</para>
 20.1404 -	  </listitem></itemizedlist>
 20.1405 -
 20.1406 -      </sect3>
 20.1407 -      <sect3>
 20.1408 -	<title>Choosing the right <filename
 20.1409 -	    role="special">~/.hgrc</filename> file to add <literal
 20.1410 -	    role="rc-web">web</literal> items to</title>
 20.1411 -
 20.1412 -	<para>It is important to remember that a web server like
 20.1413 -	  Apache or <literal>lighttpd</literal> will run under a user
 20.1414 -	  ID that is different to yours. CGI scripts run by your
 20.1415 -	  server, such as <filename
 20.1416 -	    role="special">hgweb.cgi</filename>, will usually also run
 20.1417 -	  under that user ID.</para>
 20.1418 -
 20.1419 -	<para>If you add <literal role="rc-web">web</literal> items to
 20.1420 -	  your own personal <filename role="special">~/.hgrc</filename> file, CGI scripts won't read that
 20.1421 -	  <filename role="special">~/.hgrc</filename> file.  Those
 20.1422 -	  settings will thus only affect the behaviour of the <command
 20.1423 -	    role="hg-cmd">hg serve</command> command when you run it.
 20.1424 -	  To cause CGI scripts to see your settings, either create a
 20.1425 -	  <filename role="special">~/.hgrc</filename> file in the
 20.1426 -	  home directory of the user ID that runs your web server, or
 20.1427 -	  add those settings to a system-wide <filename
 20.1428 -	    role="special">~/.hgrc</filename> file.</para>
 20.1429 -
 20.1430 -
 20.1431 -      </sect3>
 20.1432 -    </sect2>
 20.1433 -  </sect1>
 20.1434 -</chapter>
 20.1435 -
 20.1436 -<!--
 20.1437 -local variables: 
 20.1438 -sgml-parent-document: ("00book.xml" "book" "chapter")
 20.1439 -end:
 20.1440 --->
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/en/ch06-filenames.xml	Fri Mar 20 16:43:35 2009 +0800
    21.3 @@ -0,0 +1,408 @@
    21.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    21.5 +
    21.6 +<chapter id="chap.names">
    21.7 +  <?dbhtml filename="file-names-and-pattern-matching.html"?>
    21.8 +  <title>File names and pattern matching</title>
    21.9 +
   21.10 +  <para id="x_543">Mercurial provides mechanisms that let you work with file
   21.11 +    names in a consistent and expressive way.</para>
   21.12 +
   21.13 +  <sect1>
   21.14 +    <title>Simple file naming</title>
   21.15 +
   21.16 +    <para id="x_544">Mercurial uses a unified piece of machinery <quote>under the
   21.17 +	hood</quote> to handle file names.  Every command behaves
   21.18 +      uniformly with respect to file names.  The way in which commands
   21.19 +      work with file names is as follows.</para>
   21.20 +
   21.21 +    <para id="x_545">If you explicitly name real files on the command line,
   21.22 +      Mercurial works with exactly those files, as you would expect.
   21.23 +      &interaction.filenames.files;</para>
   21.24 +
   21.25 +    <para id="x_546">When you provide a directory name, Mercurial will interpret
   21.26 +      this as <quote>operate on every file in this directory and its
   21.27 +	subdirectories</quote>. Mercurial traverses the files and
   21.28 +      subdirectories in a directory in alphabetical order.  When it
   21.29 +      encounters a subdirectory, it will traverse that subdirectory
   21.30 +      before continuing with the current directory.</para>
   21.31 +
   21.32 +      &interaction.filenames.dirs;
   21.33 +
   21.34 +  </sect1>
   21.35 +  <sect1>
   21.36 +    <title>Running commands without any file names</title>
   21.37 +
   21.38 +    <para id="x_547">Mercurial's commands that work with file names have useful
   21.39 +      default behaviours when you invoke them without providing any
   21.40 +      file names or patterns.  What kind of behaviour you should
   21.41 +      expect depends on what the command does.  Here are a few rules
   21.42 +      of thumb you can use to predict what a command is likely to do
   21.43 +      if you don't give it any names to work with.</para>
   21.44 +    <itemizedlist>
   21.45 +      <listitem><para id="x_548">Most commands will operate on the entire working
   21.46 +	  directory. This is what the <command role="hg-cmd">hg
   21.47 +	    add</command> command does, for example.</para>
   21.48 +      </listitem>
   21.49 +      <listitem><para id="x_549">If the command has effects that are difficult or
   21.50 +	  impossible to reverse, it will force you to explicitly
   21.51 +	  provide at least one name or pattern (see below).  This
   21.52 +	  protects you from accidentally deleting files by running
   21.53 +	  <command role="hg-cmd">hg remove</command> with no
   21.54 +	  arguments, for example.</para>
   21.55 +      </listitem></itemizedlist>
   21.56 +
   21.57 +    <para id="x_54a">It's easy to work around these default behaviours if they
   21.58 +      don't suit you.  If a command normally operates on the whole
   21.59 +      working directory, you can invoke it on just the current
   21.60 +      directory and its subdirectories by giving it the name
   21.61 +      <quote><filename class="directory">.</filename></quote>.</para>
   21.62 +
   21.63 +    &interaction.filenames.wdir-subdir;
   21.64 +
   21.65 +    <para id="x_54b">Along the same lines, some commands normally print file
   21.66 +      names relative to the root of the repository, even if you're
   21.67 +      invoking them from a subdirectory.  Such a command will print
   21.68 +      file names relative to your subdirectory if you give it explicit
   21.69 +      names.  Here, we're going to run <command role="hg-cmd">hg
   21.70 +	status</command> from a subdirectory, and get it to operate on
   21.71 +      the entire working directory while printing file names relative
   21.72 +      to our subdirectory, by passing it the output of the <command
   21.73 +	role="hg-cmd">hg root</command> command.</para>
   21.74 +
   21.75 +      &interaction.filenames.wdir-relname;
   21.76 +
   21.77 +  </sect1>
   21.78 +  <sect1>
   21.79 +    <title>Telling you what's going on</title>
   21.80 +
   21.81 +    <para id="x_54c">The <command role="hg-cmd">hg add</command> example in the
   21.82 +      preceding section illustrates something else that's helpful
   21.83 +      about Mercurial commands.  If a command operates on a file that
   21.84 +      you didn't name explicitly on the command line, it will usually
   21.85 +      print the name of the file, so that you will not be surprised
   21.86 +      what's going on.</para>
   21.87 +
   21.88 +    <para id="x_54d">The principle here is of <emphasis>least
   21.89 +	surprise</emphasis>.  If you've exactly named a file on the
   21.90 +      command line, there's no point in repeating it back at you.  If
   21.91 +      Mercurial is acting on a file <emphasis>implicitly</emphasis>,
   21.92 +      because you provided no names, or a directory, or a pattern (see
   21.93 +      below), it's safest to tell you what it's doing.</para>
   21.94 +
   21.95 +    <para id="x_54e">For commands that behave this way, you can silence them
   21.96 +      using the <option role="hg-opt-global">-q</option> option.  You
   21.97 +      can also get them to print the name of every file, even those
   21.98 +      you've named explicitly, using the <option
   21.99 +	role="hg-opt-global">-v</option> option.</para>
  21.100 +
  21.101 +  </sect1>
  21.102 +  <sect1>
  21.103 +    <title>Using patterns to identify files</title>
  21.104 +
  21.105 +    <para id="x_54f">In addition to working with file and directory names,
  21.106 +      Mercurial lets you use <emphasis>patterns</emphasis> to identify
  21.107 +      files.  Mercurial's pattern handling is expressive.</para>
  21.108 +
  21.109 +    <para id="x_550">On Unix-like systems (Linux, MacOS, etc.), the job of
  21.110 +      matching file names to patterns normally falls to the shell.  On
  21.111 +      these systems, you must explicitly tell Mercurial that a name is
  21.112 +      a pattern.  On Windows, the shell does not expand patterns, so
  21.113 +      Mercurial will automatically identify names that are patterns,
  21.114 +      and expand them for you.</para>
  21.115 +
  21.116 +    <para id="x_551">To provide a pattern in place of a regular name on the
  21.117 +      command line, the mechanism is simple:</para>
  21.118 +    <programlisting>syntax:patternbody</programlisting>
  21.119 +    <para id="x_552">That is, a pattern is identified by a short text string that
  21.120 +      says what kind of pattern this is, followed by a colon, followed
  21.121 +      by the actual pattern.</para>
  21.122 +
  21.123 +    <para id="x_553">Mercurial supports two kinds of pattern syntax.  The most
  21.124 +      frequently used is called <literal>glob</literal>; this is the
  21.125 +      same kind of pattern matching used by the Unix shell, and should
  21.126 +      be familiar to Windows command prompt users, too.</para>
  21.127 +
  21.128 +    <para id="x_554">When Mercurial does automatic pattern matching on Windows,
  21.129 +      it uses <literal>glob</literal> syntax.  You can thus omit the
  21.130 +      <quote><literal>glob:</literal></quote> prefix on Windows, but
  21.131 +      it's safe to use it, too.</para>
  21.132 +
  21.133 +    <para id="x_555">The <literal>re</literal> syntax is more powerful; it lets
  21.134 +      you specify patterns using regular expressions, also known as
  21.135 +      regexps.</para>
  21.136 +
  21.137 +    <para id="x_556">By the way, in the examples that follow, notice that I'm
  21.138 +      careful to wrap all of my patterns in quote characters, so that
  21.139 +      they won't get expanded by the shell before Mercurial sees
  21.140 +      them.</para>
  21.141 +
  21.142 +    <sect2>
  21.143 +      <title>Shell-style <literal>glob</literal> patterns</title>
  21.144 +
  21.145 +      <para id="x_557">This is an overview of the kinds of patterns you can use
  21.146 +	when you're matching on glob patterns.</para>
  21.147 +
  21.148 +      <para id="x_558">The <quote><literal>*</literal></quote> character matches
  21.149 +	any string, within a single directory.</para>
  21.150 +
  21.151 +      &interaction.filenames.glob.star;
  21.152 +
  21.153 +      <para id="x_559">The <quote><literal>**</literal></quote> pattern matches
  21.154 +	any string, and crosses directory boundaries.  It's not a
  21.155 +	standard Unix glob token, but it's accepted by several popular
  21.156 +	Unix shells, and is very useful.</para>
  21.157 +
  21.158 +      &interaction.filenames.glob.starstar;
  21.159 +
  21.160 +      <para id="x_55a">The <quote><literal>?</literal></quote> pattern matches
  21.161 +	any single character.</para>
  21.162 +
  21.163 +      &interaction.filenames.glob.question;
  21.164 +
  21.165 +      <para id="x_55b">The <quote><literal>[</literal></quote> character begins a
  21.166 +	<emphasis>character class</emphasis>.  This matches any single
  21.167 +	character within the class.  The class ends with a
  21.168 +	<quote><literal>]</literal></quote> character.  A class may
  21.169 +	contain multiple <emphasis>range</emphasis>s of the form
  21.170 +	<quote><literal>a-f</literal></quote>, which is shorthand for
  21.171 +	<quote><literal>abcdef</literal></quote>.</para>
  21.172 +
  21.173 +	&interaction.filenames.glob.range;
  21.174 +
  21.175 +      <para id="x_55c">If the first character after the
  21.176 +	<quote><literal>[</literal></quote> in a character class is a
  21.177 +	<quote><literal>!</literal></quote>, it
  21.178 +	<emphasis>negates</emphasis> the class, making it match any
  21.179 +	single character not in the class.</para>
  21.180 +
  21.181 +      <para id="x_55d">A <quote><literal>{</literal></quote> begins a group of
  21.182 +	subpatterns, where the whole group matches if any subpattern
  21.183 +	in the group matches.  The <quote><literal>,</literal></quote>
  21.184 +	character separates subpatterns, and
  21.185 +	<quote><literal>}</literal></quote> ends the group.</para>
  21.186 +
  21.187 +      &interaction.filenames.glob.group;
  21.188 +
  21.189 +      <sect3>
  21.190 +	<title>Watch out!</title>
  21.191 +
  21.192 +	<para id="x_55e">Don't forget that if you want to match a pattern in any
  21.193 +	  directory, you should not be using the
  21.194 +	  <quote><literal>*</literal></quote> match-any token, as this
  21.195 +	  will only match within one directory.  Instead, use the
  21.196 +	  <quote><literal>**</literal></quote> token.  This small
  21.197 +	  example illustrates the difference between the two.</para>
  21.198 +
  21.199 +	  &interaction.filenames.glob.star-starstar;
  21.200 +
  21.201 +      </sect3>
  21.202 +    </sect2>
  21.203 +    <sect2>
  21.204 +      <title>Regular expression matching with <literal>re</literal>
  21.205 +	patterns</title>
  21.206 +
  21.207 +      <para id="x_55f">Mercurial accepts the same regular expression syntax as
  21.208 +	the Python programming language (it uses Python's regexp
  21.209 +	engine internally). This is based on the Perl language's
  21.210 +	regexp syntax, which is the most popular dialect in use (it's
  21.211 +	also used in Java, for example).</para>
  21.212 +
  21.213 +      <para id="x_560">I won't discuss Mercurial's regexp dialect in any detail
  21.214 +	here, as regexps are not often used.  Perl-style regexps are
  21.215 +	in any case already exhaustively documented on a multitude of
  21.216 +	web sites, and in many books.  Instead, I will focus here on a
  21.217 +	few things you should know if you find yourself needing to use
  21.218 +	regexps with Mercurial.</para>
  21.219 +
  21.220 +      <para id="x_561">A regexp is matched against an entire file name, relative
  21.221 +	to the root of the repository.  In other words, even if you're
  21.222 +	already in subbdirectory <filename
  21.223 +	  class="directory">foo</filename>, if you want to match files
  21.224 +	under this directory, your pattern must start with
  21.225 +	<quote><literal>foo/</literal></quote>.</para>
  21.226 +
  21.227 +      <para id="x_562">One thing to note, if you're familiar with Perl-style
  21.228 +	regexps, is that Mercurial's are <emphasis>rooted</emphasis>.
  21.229 +	That is, a regexp starts matching against the beginning of a
  21.230 +	string; it doesn't look for a match anywhere within the
  21.231 +	string.  To match anywhere in a string, start your pattern
  21.232 +	with <quote><literal>.*</literal></quote>.</para>
  21.233 +
  21.234 +    </sect2>
  21.235 +  </sect1>
  21.236 +  <sect1>
  21.237 +    <title>Filtering files</title>
  21.238 +
  21.239 +    <para id="x_563">Not only does Mercurial give you a variety of ways to
  21.240 +      specify files; it lets you further winnow those files using
  21.241 +      <emphasis>filters</emphasis>.  Commands that work with file
  21.242 +      names accept two filtering options.</para>
  21.243 +    <itemizedlist>
  21.244 +      <listitem><para id="x_564"><option role="hg-opt-global">-I</option>, or
  21.245 +	  <option role="hg-opt-global">--include</option>, lets you
  21.246 +	  specify a pattern that file names must match in order to be
  21.247 +	  processed.</para>
  21.248 +      </listitem>
  21.249 +      <listitem><para id="x_565"><option role="hg-opt-global">-X</option>, or
  21.250 +	  <option role="hg-opt-global">--exclude</option>, gives you a
  21.251 +	  way to <emphasis>avoid</emphasis> processing files, if they
  21.252 +	  match this pattern.</para>
  21.253 +      </listitem></itemizedlist>
  21.254 +    <para id="x_566">You can provide multiple <option
  21.255 +	role="hg-opt-global">-I</option> and <option
  21.256 +	role="hg-opt-global">-X</option> options on the command line,
  21.257 +      and intermix them as you please.  Mercurial interprets the
  21.258 +      patterns you provide using glob syntax by default (but you can
  21.259 +      use regexps if you need to).</para>
  21.260 +
  21.261 +    <para id="x_567">You can read a <option role="hg-opt-global">-I</option>
  21.262 +      filter as <quote>process only the files that match this
  21.263 +	filter</quote>.</para>
  21.264 +
  21.265 +    &interaction.filenames.filter.include;
  21.266 +
  21.267 +    <para id="x_568">The <option role="hg-opt-global">-X</option> filter is best
  21.268 +      read as <quote>process only the files that don't match this
  21.269 +	pattern</quote>.</para>
  21.270 +
  21.271 +    &interaction.filenames.filter.exclude;
  21.272 +
  21.273 +  </sect1>
  21.274 +  <sect1>
  21.275 +    <title>Ignoring unwanted files and directories</title>
  21.276 +
  21.277 +    <para id="x_569">XXX.</para>
  21.278 +
  21.279 +  </sect1>
  21.280 +  <sect1 id="sec.names.case">
  21.281 +    <title>Case sensitivity</title>
  21.282 +
  21.283 +    <para id="x_56a">If you're working in a mixed development environment that
  21.284 +      contains both Linux (or other Unix) systems and Macs or Windows
  21.285 +      systems, you should keep in the back of your mind the knowledge
  21.286 +      that they treat the case (<quote>N</quote> versus
  21.287 +      <quote>n</quote>) of file names in incompatible ways.  This is
  21.288 +      not very likely to affect you, and it's easy to deal with if it
  21.289 +      does, but it could surprise you if you don't know about
  21.290 +      it.</para>
  21.291 +
  21.292 +    <para id="x_56b">Operating systems and filesystems differ in the way they
  21.293 +      handle the <emphasis>case</emphasis> of characters in file and
  21.294 +      directory names.  There are three common ways to handle case in
  21.295 +      names.</para>
  21.296 +    <itemizedlist>
  21.297 +      <listitem><para id="x_56c">Completely case insensitive.  Uppercase and
  21.298 +	  lowercase versions of a letter are treated as identical,
  21.299 +	  both when creating a file and during subsequent accesses.
  21.300 +	  This is common on older DOS-based systems.</para>
  21.301 +      </listitem>
  21.302 +      <listitem><para id="x_56d">Case preserving, but insensitive.  When a file
  21.303 +	  or directory is created, the case of its name is stored, and
  21.304 +	  can be retrieved and displayed by the operating system.
  21.305 +	  When an existing file is being looked up, its case is
  21.306 +	  ignored.  This is the standard arrangement on Windows and
  21.307 +	  MacOS.  The names <filename>foo</filename> and
  21.308 +	  <filename>FoO</filename> identify the same file.  This
  21.309 +	  treatment of uppercase and lowercase letters as
  21.310 +	  interchangeable is also referred to as <emphasis>case
  21.311 +	    folding</emphasis>.</para>
  21.312 +      </listitem>
  21.313 +      <listitem><para id="x_56e">Case sensitive.  The case of a name is
  21.314 +	  significant at all times. The names <filename>foo</filename>
  21.315 +	  and {FoO} identify different files.  This is the way Linux
  21.316 +	  and Unix systems normally work.</para>
  21.317 +      </listitem></itemizedlist>
  21.318 +
  21.319 +    <para id="x_56f">On Unix-like systems, it is possible to have any or all of
  21.320 +      the above ways of handling case in action at once.  For example,
  21.321 +      if you use a USB thumb drive formatted with a FAT32 filesystem
  21.322 +      on a Linux system, Linux will handle names on that filesystem in
  21.323 +      a case preserving, but insensitive, way.</para>
  21.324 +
  21.325 +    <sect2>
  21.326 +      <title>Safe, portable repository storage</title>
  21.327 +
  21.328 +      <para id="x_570">Mercurial's repository storage mechanism is <emphasis>case
  21.329 +	  safe</emphasis>.  It translates file names so that they can
  21.330 +	be safely stored on both case sensitive and case insensitive
  21.331 +	filesystems.  This means that you can use normal file copying
  21.332 +	tools to transfer a Mercurial repository onto, for example, a
  21.333 +	USB thumb drive, and safely move that drive and repository
  21.334 +	back and forth between a Mac, a PC running Windows, and a
  21.335 +	Linux box.</para>
  21.336 +
  21.337 +    </sect2>
  21.338 +    <sect2>
  21.339 +      <title>Detecting case conflicts</title>
  21.340 +
  21.341 +      <para id="x_571">When operating in the working directory, Mercurial honours
  21.342 +	the naming policy of the filesystem where the working
  21.343 +	directory is located.  If the filesystem is case preserving,
  21.344 +	but insensitive, Mercurial will treat names that differ only
  21.345 +	in case as the same.</para>
  21.346 +
  21.347 +      <para id="x_572">An important aspect of this approach is that it is
  21.348 +	possible to commit a changeset on a case sensitive (typically
  21.349 +	Linux or Unix) filesystem that will cause trouble for users on
  21.350 +	case insensitive (usually Windows and MacOS) users.  If a
  21.351 +	Linux user commits changes to two files, one named
  21.352 +	<filename>myfile.c</filename> and the other named
  21.353 +	<filename>MyFile.C</filename>, they will be stored correctly
  21.354 +	in the repository.  And in the working directories of other
  21.355 +	Linux users, they will be correctly represented as separate
  21.356 +	files.</para>
  21.357 +
  21.358 +      <para id="x_573">If a Windows or Mac user pulls this change, they will not
  21.359 +	initially have a problem, because Mercurial's repository
  21.360 +	storage mechanism is case safe.  However, once they try to
  21.361 +	<command role="hg-cmd">hg update</command> the working
  21.362 +	directory to that changeset, or <command role="hg-cmd">hg
  21.363 +	  merge</command> with that changeset, Mercurial will spot the
  21.364 +	conflict between the two file names that the filesystem would
  21.365 +	treat as the same, and forbid the update or merge from
  21.366 +	occurring.</para>
  21.367 +
  21.368 +    </sect2>
  21.369 +    <sect2>
  21.370 +      <title>Fixing a case conflict</title>
  21.371 +
  21.372 +      <para id="x_574">If you are using Windows or a Mac in a mixed environment
  21.373 +	where some of your collaborators are using Linux or Unix, and
  21.374 +	Mercurial reports a case folding conflict when you try to
  21.375 +	<command role="hg-cmd">hg update</command> or <command
  21.376 +	  role="hg-cmd">hg merge</command>, the procedure to fix the
  21.377 +	problem is simple.</para>
  21.378 +
  21.379 +      <para id="x_575">Just find a nearby Linux or Unix box, clone the problem
  21.380 +	repository onto it, and use Mercurial's <command
  21.381 +	  role="hg-cmd">hg rename</command> command to change the
  21.382 +	names of any offending files or directories so that they will
  21.383 +	no longer cause case folding conflicts.  Commit this change,
  21.384 +	<command role="hg-cmd">hg pull</command> or <command
  21.385 +	  role="hg-cmd">hg push</command> it across to your Windows or
  21.386 +	MacOS system, and <command role="hg-cmd">hg update</command>
  21.387 +	to the revision with the non-conflicting names.</para>
  21.388 +
  21.389 +      <para id="x_576">The changeset with case-conflicting names will remain in
  21.390 +	your project's history, and you still won't be able to
  21.391 +	<command role="hg-cmd">hg update</command> your working
  21.392 +	directory to that changeset on a Windows or MacOS system, but
  21.393 +	you can continue development unimpeded.</para>
  21.394 +
  21.395 +      <note>
  21.396 +	<para id="x_577">  Prior to version 0.9.3, Mercurial did not use a case
  21.397 +	  safe repository storage mechanism, and did not detect case
  21.398 +	  folding conflicts.  If you are using an older version of
  21.399 +	  Mercurial on Windows or MacOS, I strongly recommend that you
  21.400 +	  upgrade.</para>
  21.401 +      </note>
  21.402 +
  21.403 +    </sect2>
  21.404 +  </sect1>
  21.405 +</chapter>
  21.406 +
  21.407 +<!--
  21.408 +local variables: 
  21.409 +sgml-parent-document: ("00book.xml" "book" "chapter")
  21.410 +end:
  21.411 +-->
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/en/ch07-branch.xml	Fri Mar 20 16:43:35 2009 +0800
    22.3 @@ -0,0 +1,533 @@
    22.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    22.5 +
    22.6 +<chapter id="chap.branch">
    22.7 +  <?dbhtml filename="managing-releases-and-branchy-development.html"?>
    22.8 +  <title>Managing releases and branchy development</title>
    22.9 +
   22.10 +  <para id="x_369">Mercurial provides several mechanisms for you to manage a
   22.11 +    project that is making progress on multiple fronts at once.  To
   22.12 +    understand these mechanisms, let's first take a brief look at a
   22.13 +    fairly normal software project structure.</para>
   22.14 +
   22.15 +  <para id="x_36a">Many software projects issue periodic <quote>major</quote>
   22.16 +    releases that contain substantial new features.  In parallel, they
   22.17 +    may issue <quote>minor</quote> releases.  These are usually
   22.18 +    identical to the major releases off which they're based, but with
   22.19 +    a few bugs fixed.</para>
   22.20 +
   22.21 +  <para id="x_36b">In this chapter, we'll start by talking about how to keep
   22.22 +    records of project milestones such as releases.  We'll then
   22.23 +    continue on to talk about the flow of work between different
   22.24 +    phases of a project, and how Mercurial can help you to isolate and
   22.25 +    manage this work.</para>
   22.26 +
   22.27 +  <sect1>
   22.28 +    <title>Giving a persistent name to a revision</title>
   22.29 +
   22.30 +    <para id="x_36c">Once you decide that you'd like to call a particular
   22.31 +      revision a <quote>release</quote>, it's a good idea to record
   22.32 +      the identity of that revision. This will let you reproduce that
   22.33 +      release at a later date, for whatever purpose you might need at
   22.34 +      the time (reproducing a bug, porting to a new platform, etc).
   22.35 +      &interaction.tag.init;</para>
   22.36 +
   22.37 +    <para id="x_36d">Mercurial lets you give a permanent name to any revision
   22.38 +      using the <command role="hg-cmd">hg tag</command> command.  Not
   22.39 +      surprisingly, these names are called <quote>tags</quote>.</para>
   22.40 +
   22.41 +    &interaction.tag.tag;
   22.42 +
   22.43 +    <para id="x_36e">A tag is nothing more than a <quote>symbolic name</quote>
   22.44 +      for a revision.  Tags exist purely for your convenience, so that
   22.45 +      you have a handy permanent way to refer to a revision; Mercurial
   22.46 +      doesn't interpret the tag names you use in any way.  Neither
   22.47 +      does Mercurial place any restrictions on the name of a tag,
   22.48 +      beyond a few that are necessary to ensure that a tag can be
   22.49 +      parsed unambiguously.  A tag name cannot contain any of the
   22.50 +      following characters:</para>
   22.51 +    <itemizedlist>
   22.52 +      <listitem><para id="x_36f">Colon (ASCII 58,
   22.53 +	  <quote><literal>:</literal></quote>)</para>
   22.54 +      </listitem>
   22.55 +      <listitem><para id="x_370">Carriage return (ASCII 13,
   22.56 +	  <quote><literal>\r</literal></quote>)</para>
   22.57 +      </listitem>
   22.58 +      <listitem><para id="x_371">Newline (ASCII 10,
   22.59 +	  <quote><literal>\n</literal></quote>)</para>
   22.60 +      </listitem></itemizedlist>
   22.61 +
   22.62 +    <para id="x_372">You can use the <command role="hg-cmd">hg tags</command>
   22.63 +      command to display the tags present in your repository.  In the
   22.64 +      output, each tagged revision is identified first by its name,
   22.65 +      then by revision number, and finally by the unique hash of the
   22.66 +      revision.</para>
   22.67 +
   22.68 +    &interaction.tag.tags;
   22.69 +
   22.70 +    <para id="x_373">Notice that <literal>tip</literal> is listed in the output
   22.71 +      of <command role="hg-cmd">hg tags</command>.  The
   22.72 +      <literal>tip</literal> tag is a special <quote>floating</quote>
   22.73 +      tag, which always identifies the newest revision in the
   22.74 +      repository.</para>
   22.75 +
   22.76 +    <para id="x_374">In the output of the <command role="hg-cmd">hg
   22.77 +	tags</command> command, tags are listed in reverse order, by
   22.78 +      revision number.  This usually means that recent tags are listed
   22.79 +      before older tags.  It also means that <literal>tip</literal> is
   22.80 +      always going to be the first tag listed in the output of
   22.81 +      <command role="hg-cmd">hg tags</command>.</para>
   22.82 +
   22.83 +    <para id="x_375">When you run <command role="hg-cmd">hg log</command>, if it
   22.84 +      displays a revision that has tags associated with it, it will
   22.85 +      print those tags.</para>
   22.86 +
   22.87 +    &interaction.tag.log;
   22.88 +
   22.89 +    <para id="x_376">Any time you need to provide a revision ID to a Mercurial
   22.90 +      command, the command will accept a tag name in its place.
   22.91 +      Internally, Mercurial will translate your tag name into the
   22.92 +      corresponding revision ID, then use that.</para>
   22.93 +
   22.94 +    &interaction.tag.log.v1.0;
   22.95 +
   22.96 +    <para id="x_377">There's no limit on the number of tags you can have in a
   22.97 +      repository, or on the number of tags that a single revision can
   22.98 +      have.  As a practical matter, it's not a great idea to have
   22.99 +      <quote>too many</quote> (a number which will vary from project
  22.100 +      to project), simply because tags are supposed to help you to
  22.101 +      find revisions.  If you have lots of tags, the ease of using
  22.102 +      them to identify revisions diminishes rapidly.</para>
  22.103 +
  22.104 +    <para id="x_378">For example, if your project has milestones as frequent as
  22.105 +      every few days, it's perfectly reasonable to tag each one of
  22.106 +      those.  But if you have a continuous build system that makes
  22.107 +      sure every revision can be built cleanly, you'd be introducing a
  22.108 +      lot of noise if you were to tag every clean build.  Instead, you
  22.109 +      could tag failed builds (on the assumption that they're rare!),
  22.110 +      or simply not use tags to track buildability.</para>
  22.111 +
  22.112 +    <para id="x_379">If you want to remove a tag that you no longer want, use
  22.113 +      <command role="hg-cmd">hg tag --remove</command>.</para>
  22.114 +
  22.115 +    &interaction.tag.remove;
  22.116 +
  22.117 +    <para id="x_37a">You can also modify a tag at any time, so that it identifies
  22.118 +      a different revision, by simply issuing a new <command
  22.119 +	role="hg-cmd">hg tag</command> command. You'll have to use the
  22.120 +      <option role="hg-opt-tag">-f</option> option to tell Mercurial
  22.121 +      that you <emphasis>really</emphasis> want to update the
  22.122 +      tag.</para>
  22.123 +
  22.124 +    &interaction.tag.replace;
  22.125 +
  22.126 +    <para id="x_37b">There will still be a permanent record of the previous
  22.127 +      identity of the tag, but Mercurial will no longer use it.
  22.128 +      There's thus no penalty to tagging the wrong revision; all you
  22.129 +      have to do is turn around and tag the correct revision once you
  22.130 +      discover your error.</para>
  22.131 +
  22.132 +    <para id="x_37c">Mercurial stores tags in a normal revision-controlled file
  22.133 +      in your repository.  If you've created any tags, you'll find
  22.134 +      them in a file named <filename
  22.135 +	role="special">.hgtags</filename>.  When you run the <command
  22.136 +	role="hg-cmd">hg tag</command> command, Mercurial modifies
  22.137 +      this file, then automatically commits the change to it.  This
  22.138 +      means that every time you run <command role="hg-cmd">hg
  22.139 +	tag</command>, you'll see a corresponding changeset in the
  22.140 +      output of <command role="hg-cmd">hg log</command>.</para>
  22.141 +
  22.142 +    &interaction.tag.tip;
  22.143 +
  22.144 +    <sect2>
  22.145 +      <title>Handling tag conflicts during a merge</title>
  22.146 +
  22.147 +      <para id="x_37d">You won't often need to care about the <filename
  22.148 +	  role="special">.hgtags</filename> file, but it sometimes
  22.149 +	makes its presence known during a merge.  The format of the
  22.150 +	file is simple: it consists of a series of lines.  Each line
  22.151 +	starts with a changeset hash, followed by a space, followed by
  22.152 +	the name of a tag.</para>
  22.153 +
  22.154 +      <para id="x_37e">If you're resolving a conflict in the <filename
  22.155 +	  role="special">.hgtags</filename> file during a merge,
  22.156 +	there's one twist to modifying the <filename
  22.157 +	  role="special">.hgtags</filename> file: when Mercurial is
  22.158 +	parsing the tags in a repository, it
  22.159 +	<emphasis>never</emphasis> reads the working copy of the
  22.160 +	<filename role="special">.hgtags</filename> file.  Instead, it
  22.161 +	reads the <emphasis>most recently committed</emphasis>
  22.162 +	revision of the file.</para>
  22.163 +
  22.164 +      <para id="x_37f">An unfortunate consequence of this design is that you
  22.165 +	can't actually verify that your merged <filename
  22.166 +	  role="special">.hgtags</filename> file is correct until
  22.167 +	<emphasis>after</emphasis> you've committed a change.  So if
  22.168 +	you find yourself resolving a conflict on <filename
  22.169 +	  role="special">.hgtags</filename> during a merge, be sure to
  22.170 +	run <command role="hg-cmd">hg tags</command> after you commit.
  22.171 +	If it finds an error in the <filename
  22.172 +	  role="special">.hgtags</filename> file, it will report the
  22.173 +	location of the error, which you can then fix and commit.  You
  22.174 +	should then run <command role="hg-cmd">hg tags</command>
  22.175 +	again, just to be sure that your fix is correct.</para>
  22.176 +
  22.177 +    </sect2>
  22.178 +    <sect2>
  22.179 +      <title>Tags and cloning</title>
  22.180 +
  22.181 +      <para id="x_380">You may have noticed that the <command role="hg-cmd">hg
  22.182 +	  clone</command> command has a <option
  22.183 +	  role="hg-opt-clone">-r</option> option that lets you clone
  22.184 +	an exact copy of the repository as of a particular changeset.
  22.185 +	The new clone will not contain any project history that comes
  22.186 +	after the revision you specified.  This has an interaction
  22.187 +	with tags that can surprise the unwary.</para>
  22.188 +
  22.189 +      <para id="x_381">Recall that a tag is stored as a revision to the <filename
  22.190 +	  role="special">.hgtags</filename> file, so that when you
  22.191 +	create a tag, the changeset in which it's recorded necessarily
  22.192 +	refers to an older changeset.  When you run <command
  22.193 +	  role="hg-cmd">hg clone -r foo</command> to clone a
  22.194 +	repository as of tag <literal>foo</literal>, the new clone
  22.195 +	<emphasis>will not contain the history that created the
  22.196 +	  tag</emphasis> that you used to clone the repository.  The
  22.197 +	result is that you'll get exactly the right subset of the
  22.198 +	project's history in the new repository, but
  22.199 +	<emphasis>not</emphasis> the tag you might have
  22.200 +	expected.</para>
  22.201 +
  22.202 +    </sect2>
  22.203 +    <sect2>
  22.204 +      <title>When permanent tags are too much</title>
  22.205 +
  22.206 +      <para id="x_382">Since Mercurial's tags are revision controlled and carried
  22.207 +	around with a project's history, everyone you work with will
  22.208 +	see the tags you create.  But giving names to revisions has
  22.209 +	uses beyond simply noting that revision
  22.210 +	<literal>4237e45506ee</literal> is really
  22.211 +	<literal>v2.0.2</literal>.  If you're trying to track down a
  22.212 +	subtle bug, you might want a tag to remind you of something
  22.213 +	like <quote>Anne saw the symptoms with this
  22.214 +	  revision</quote>.</para>
  22.215 +
  22.216 +      <para id="x_383">For cases like this, what you might want to use are
  22.217 +	<emphasis>local</emphasis> tags. You can create a local tag
  22.218 +	with the <option role="hg-opt-tag">-l</option> option to the
  22.219 +	<command role="hg-cmd">hg tag</command> command.  This will
  22.220 +	store the tag in a file called <filename
  22.221 +	  role="special">.hg/localtags</filename>.  Unlike <filename
  22.222 +	  role="special">.hgtags</filename>, <filename
  22.223 +	  role="special">.hg/localtags</filename> is not revision
  22.224 +	controlled.  Any tags you create using <option
  22.225 +	  role="hg-opt-tag">-l</option> remain strictly local to the
  22.226 +	repository you're currently working in.</para>
  22.227 +
  22.228 +    </sect2>
  22.229 +  </sect1>
  22.230 +  <sect1>
  22.231 +    <title>The flow of changes&emdash;big picture vs. little</title>
  22.232 +
  22.233 +    <para id="x_384">To return to the outline I sketched at the beginning of a
  22.234 +      chapter, let's think about a project that has multiple
  22.235 +      concurrent pieces of work under development at once.</para>
  22.236 +
  22.237 +    <para id="x_385">There might be a push for a new <quote>main</quote> release;
  22.238 +      a new minor bugfix release to the last main release; and an
  22.239 +      unexpected <quote>hot fix</quote> to an old release that is now
  22.240 +      in maintenance mode.</para>
  22.241 +
  22.242 +    <para id="x_386">The usual way people refer to these different concurrent
  22.243 +      directions of development is as <quote>branches</quote>.
  22.244 +      However, we've already seen numerous times that Mercurial treats
  22.245 +      <emphasis>all of history</emphasis> as a series of branches and
  22.246 +      merges.  Really, what we have here is two ideas that are
  22.247 +      peripherally related, but which happen to share a name.</para>
  22.248 +    <itemizedlist>
  22.249 +      <listitem><para id="x_387"><quote>Big picture</quote> branches represent
  22.250 +	  the sweep of a project's evolution; people give them names,
  22.251 +	  and talk about them in conversation.</para>
  22.252 +      </listitem>
  22.253 +      <listitem><para id="x_388"><quote>Little picture</quote> branches are
  22.254 +	  artefacts of the day-to-day activity of developing and
  22.255 +	  merging changes.  They expose the narrative of how the code
  22.256 +	  was developed.</para>
  22.257 +      </listitem></itemizedlist>
  22.258 +
  22.259 +  </sect1>
  22.260 +  <sect1>
  22.261 +    <title>Managing big-picture branches in repositories</title>
  22.262 +
  22.263 +    <para id="x_389">The easiest way to isolate a <quote>big picture</quote>
  22.264 +      branch in Mercurial is in a dedicated repository.  If you have
  22.265 +      an existing shared repository&emdash;let's call it
  22.266 +      <literal>myproject</literal>&emdash;that reaches a
  22.267 +      <quote>1.0</quote> milestone, you can start to prepare for
  22.268 +      future maintenance releases on top of version 1.0 by tagging the
  22.269 +      revision from which you prepared the 1.0 release.</para>
  22.270 +
  22.271 +    &interaction.branch-repo.tag;
  22.272 +
  22.273 +    <para id="x_38a">You can then clone a new shared
  22.274 +      <literal>myproject-1.0.1</literal> repository as of that
  22.275 +      tag.</para>
  22.276 +
  22.277 +    &interaction.branch-repo.clone;
  22.278 +
  22.279 +    <para id="x_38b">Afterwards, if someone needs to work on a bug fix that ought
  22.280 +      to go into an upcoming 1.0.1 minor release, they clone the
  22.281 +      <literal>myproject-1.0.1</literal> repository, make their
  22.282 +      changes, and push them back.</para>
  22.283 +
  22.284 +    &interaction.branch-repo.bugfix;
  22.285 +
  22.286 +    <para id="x_38c">Meanwhile, development for
  22.287 +      the next major release can continue, isolated and unabated, in
  22.288 +      the <literal>myproject</literal> repository.</para>
  22.289 +
  22.290 +    &interaction.branch-repo.new;
  22.291 +
  22.292 +  </sect1>
  22.293 +  <sect1>
  22.294 +    <title>Don't repeat yourself: merging across branches</title>
  22.295 +
  22.296 +    <para id="x_38d">In many cases, if you have a bug to fix on a maintenance
  22.297 +      branch, the chances are good that the bug exists on your
  22.298 +      project's main branch (and possibly other maintenance branches,
  22.299 +      too).  It's a rare developer who wants to fix the same bug
  22.300 +      multiple times, so let's look at a few ways that Mercurial can
  22.301 +      help you to manage these bugfixes without duplicating your
  22.302 +      work.</para>
  22.303 +
  22.304 +    <para id="x_38e">In the simplest instance, all you need to do is pull changes
  22.305 +      from your maintenance branch into your local clone of the target
  22.306 +      branch.</para>
  22.307 +
  22.308 +    &interaction.branch-repo.pull;
  22.309 +
  22.310 +    <para id="x_38f">You'll then need to merge the heads of the two branches, and
  22.311 +      push back to the main branch.</para>
  22.312 +
  22.313 +    &interaction.branch-repo.merge;
  22.314 +
  22.315 +  </sect1>
  22.316 +  <sect1>
  22.317 +    <title>Naming branches within one repository</title>
  22.318 +
  22.319 +    <para id="x_390">In most instances, isolating branches in repositories is the
  22.320 +      right approach.  Its simplicity makes it easy to understand; and
  22.321 +      so it's hard to make mistakes.  There's a one-to-one
  22.322 +      relationship between branches you're working in and directories
  22.323 +      on your system.  This lets you use normal (non-Mercurial-aware)
  22.324 +      tools to work on files within a branch/repository.</para>
  22.325 +
  22.326 +    <para id="x_391">If you're more in the <quote>power user</quote> category
  22.327 +      (<emphasis>and</emphasis> your collaborators are too), there is
  22.328 +      an alternative way of handling branches that you can consider.
  22.329 +      I've already mentioned the human-level distinction between
  22.330 +      <quote>small picture</quote> and <quote>big picture</quote>
  22.331 +      branches.  While Mercurial works with multiple <quote>small
  22.332 +	picture</quote> branches in a repository all the time (for
  22.333 +      example after you pull changes in, but before you merge them),
  22.334 +      it can <emphasis>also</emphasis> work with multiple <quote>big
  22.335 +	picture</quote> branches.</para>
  22.336 +
  22.337 +    <para id="x_392">The key to working this way is that Mercurial lets you
  22.338 +      assign a persistent <emphasis>name</emphasis> to a branch.
  22.339 +      There always exists a branch named <literal>default</literal>.
  22.340 +      Even before you start naming branches yourself, you can find
  22.341 +      traces of the <literal>default</literal> branch if you look for
  22.342 +      them.</para>
  22.343 +
  22.344 +    <para id="x_393">As an example, when you run the <command role="hg-cmd">hg
  22.345 +	commit</command> command, and it pops up your editor so that
  22.346 +      you can enter a commit message, look for a line that contains
  22.347 +      the text <quote><literal>HG: branch default</literal></quote> at
  22.348 +      the bottom. This is telling you that your commit will occur on
  22.349 +      the branch named <literal>default</literal>.</para>
  22.350 +
  22.351 +    <para id="x_394">To start working with named branches, use the <command
  22.352 +	role="hg-cmd">hg branches</command> command.  This command
  22.353 +      lists the named branches already present in your repository,
  22.354 +      telling you which changeset is the tip of each.</para>
  22.355 +
  22.356 +    &interaction.branch-named.branches;
  22.357 +
  22.358 +    <para id="x_395">Since you haven't created any named branches yet, the only
  22.359 +      one that exists is <literal>default</literal>.</para>
  22.360 +
  22.361 +    <para id="x_396">To find out what the <quote>current</quote> branch is, run
  22.362 +      the <command role="hg-cmd">hg branch</command> command, giving
  22.363 +      it no arguments.  This tells you what branch the parent of the
  22.364 +      current changeset is on.</para>
  22.365 +
  22.366 +    &interaction.branch-named.branch;
  22.367 +
  22.368 +    <para id="x_397">To create a new branch, run the <command role="hg-cmd">hg
  22.369 +	branch</command> command again.  This time, give it one
  22.370 +      argument: the name of the branch you want to create.</para>
  22.371 +
  22.372 +    &interaction.branch-named.create;
  22.373 +
  22.374 +    <para id="x_398">After you've created a branch, you might wonder what effect
  22.375 +      the <command role="hg-cmd">hg branch</command> command has had.
  22.376 +      What do the <command role="hg-cmd">hg status</command> and
  22.377 +      <command role="hg-cmd">hg tip</command> commands report?</para>
  22.378 +
  22.379 +    &interaction.branch-named.status;
  22.380 +
  22.381 +    <para id="x_399">Nothing has changed in the
  22.382 +      working directory, and there's been no new history created.  As
  22.383 +      this suggests, running the <command role="hg-cmd">hg
  22.384 +	branch</command> command has no permanent effect; it only
  22.385 +      tells Mercurial what branch name to use the
  22.386 +      <emphasis>next</emphasis> time you commit a changeset.</para>
  22.387 +
  22.388 +    <para id="x_39a">When you commit a change, Mercurial records the name of the
  22.389 +      branch on which you committed.  Once you've switched from the
  22.390 +      <literal>default</literal> branch to another and committed,
  22.391 +      you'll see the name of the new branch show up in the output of
  22.392 +      <command role="hg-cmd">hg log</command>, <command
  22.393 +	role="hg-cmd">hg tip</command>, and other commands that
  22.394 +      display the same kind of output.</para>
  22.395 +
  22.396 +    &interaction.branch-named.commit;
  22.397 +
  22.398 +    <para id="x_39b">The <command role="hg-cmd">hg log</command>-like commands
  22.399 +      will print the branch name of every changeset that's not on the
  22.400 +      <literal>default</literal> branch.  As a result, if you never
  22.401 +      use named branches, you'll never see this information.</para>
  22.402 +
  22.403 +    <para id="x_39c">Once you've named a branch and committed a change with that
  22.404 +      name, every subsequent commit that descends from that change
  22.405 +      will inherit the same branch name.  You can change the name of a
  22.406 +      branch at any time, using the <command role="hg-cmd">hg
  22.407 +	branch</command> command.</para>
  22.408 +
  22.409 +    &interaction.branch-named.rebranch;
  22.410 +
  22.411 +    <para id="x_39d">In practice, this is something you won't do very often, as
  22.412 +      branch names tend to have fairly long lifetimes.  (This isn't a
  22.413 +      rule, just an observation.)</para>
  22.414 +
  22.415 +  </sect1>
  22.416 +  <sect1>
  22.417 +    <title>Dealing with multiple named branches in a
  22.418 +      repository</title>
  22.419 +
  22.420 +    <para id="x_39e">If you have more than one named branch in a repository,
  22.421 +      Mercurial will remember the branch that your working directory
  22.422 +      on when you start a command like <command role="hg-cmd">hg
  22.423 +	update</command> or <command role="hg-cmd">hg pull
  22.424 +	-u</command>.  It will update the working directory to the tip
  22.425 +      of this branch, no matter what the <quote>repo-wide</quote> tip
  22.426 +      is.  To update to a revision that's on a different named branch,
  22.427 +      you may need to use the <option role="hg-opt-update">-C</option>
  22.428 +      option to <command role="hg-cmd">hg update</command>.</para>
  22.429 +
  22.430 +    <para id="x_39f">This behaviour is a little subtle, so let's see it in
  22.431 +      action.  First, let's remind ourselves what branch we're
  22.432 +      currently on, and what branches are in our repository.</para>
  22.433 +
  22.434 +    &interaction.branch-named.parents;
  22.435 +
  22.436 +    <para id="x_3a0">We're on the <literal>bar</literal> branch, but there also
  22.437 +      exists an older <command role="hg-cmd">hg foo</command>
  22.438 +      branch.</para>
  22.439 +
  22.440 +    <para id="x_3a1">We can <command role="hg-cmd">hg update</command> back and
  22.441 +      forth between the tips of the <literal>foo</literal> and
  22.442 +      <literal>bar</literal> branches without needing to use the
  22.443 +      <option role="hg-opt-update">-C</option> option, because this
  22.444 +      only involves going backwards and forwards linearly through our
  22.445 +      change history.</para>
  22.446 +
  22.447 +    &interaction.branch-named.update-switchy;
  22.448 +
  22.449 +    <para id="x_3a2">If we go back to the <literal>foo</literal> branch and then
  22.450 +      run <command role="hg-cmd">hg update</command>, it will keep us
  22.451 +      on <literal>foo</literal>, not move us to the tip of
  22.452 +      <literal>bar</literal>.</para>
  22.453 +
  22.454 +    &interaction.branch-named.update-nothing;
  22.455 +
  22.456 +    <para id="x_3a3">Committing a new change on the <literal>foo</literal> branch
  22.457 +      introduces a new head.</para>
  22.458 +
  22.459 +    &interaction.branch-named.foo-commit;
  22.460 +
  22.461 +  </sect1>
  22.462 +  <sect1>
  22.463 +    <title>Branch names and merging</title>
  22.464 +
  22.465 +    <para id="x_3a4">As you've probably noticed, merges in Mercurial are not
  22.466 +      symmetrical. Let's say our repository has two heads, 17 and 23.
  22.467 +      If I <command role="hg-cmd">hg update</command> to 17 and then
  22.468 +      <command role="hg-cmd">hg merge</command> with 23, Mercurial
  22.469 +      records 17 as the first parent of the merge, and 23 as the
  22.470 +      second.  Whereas if I <command role="hg-cmd">hg update</command>
  22.471 +      to 23 and then <command role="hg-cmd">hg merge</command> with
  22.472 +      17, it records 23 as the first parent, and 17 as the
  22.473 +      second.</para>
  22.474 +
  22.475 +    <para id="x_3a5">This affects Mercurial's choice of branch name when you
  22.476 +      merge.  After a merge, Mercurial will retain the branch name of
  22.477 +      the first parent when you commit the result of the merge.  If
  22.478 +      your first parent's branch name is <literal>foo</literal>, and
  22.479 +      you merge with <literal>bar</literal>, the branch name will
  22.480 +      still be <literal>foo</literal> after you merge.</para>
  22.481 +
  22.482 +    <para id="x_3a6">It's not unusual for a repository to contain multiple heads,
  22.483 +      each with the same branch name.  Let's say I'm working on the
  22.484 +      <literal>foo</literal> branch, and so are you.  We commit
  22.485 +      different changes; I pull your changes; I now have two heads,
  22.486 +      each claiming to be on the <literal>foo</literal> branch.  The
  22.487 +      result of a merge will be a single head on the
  22.488 +      <literal>foo</literal> branch, as you might hope.</para>
  22.489 +
  22.490 +    <para id="x_3a7">But if I'm working on the <literal>bar</literal> branch, and
  22.491 +      I merge work from the <literal>foo</literal> branch, the result
  22.492 +      will remain on the <literal>bar</literal> branch.</para>
  22.493 +
  22.494 +    &interaction.branch-named.merge;
  22.495 +
  22.496 +    <para id="x_3a8">To give a more concrete example, if I'm working on the
  22.497 +      <literal>bleeding-edge</literal> branch, and I want to bring in
  22.498 +      the latest fixes from the <literal>stable</literal> branch,
  22.499 +      Mercurial will choose the <quote>right</quote>
  22.500 +      (<literal>bleeding-edge</literal>) branch name when I pull and
  22.501 +      merge from <literal>stable</literal>.</para>
  22.502 +
  22.503 +  </sect1>
  22.504 +  <sect1>
  22.505 +    <title>Branch naming is generally useful</title>
  22.506 +
  22.507 +    <para id="x_3a9">You shouldn't think of named branches as applicable only to
  22.508 +      situations where you have multiple long-lived branches
  22.509 +      cohabiting in a single repository.  They're very useful even in
  22.510 +      the one-branch-per-repository case.</para>
  22.511 +
  22.512 +    <para id="x_3aa">In the simplest case, giving a name to each branch gives you
  22.513 +      a permanent record of which branch a changeset originated on.
  22.514 +      This gives you more context when you're trying to follow the
  22.515 +      history of a long-lived branchy project.</para>
  22.516 +
  22.517 +    <para id="x_3ab">If you're working with shared repositories, you can set up a
  22.518 +      <literal role="hook">pretxnchangegroup</literal> hook on each
  22.519 +      that will block incoming changes that have the
  22.520 +      <quote>wrong</quote> branch name.  This provides a simple, but
  22.521 +      effective, defence against people accidentally pushing changes
  22.522 +      from a <quote>bleeding edge</quote> branch to a
  22.523 +      <quote>stable</quote> branch.  Such a hook might look like this
  22.524 +      inside the shared repo's <filename role="special">
  22.525 +	/.hgrc</filename>.</para>
  22.526 +    <programlisting>[hooks]
  22.527 +pretxnchangegroup.branch = hg heads --template '{branches} ' | grep mybranch</programlisting>
  22.528 +
  22.529 +  </sect1>
  22.530 +</chapter>
  22.531 +
  22.532 +<!--
  22.533 +local variables: 
  22.534 +sgml-parent-document: ("00book.xml" "book" "chapter")
  22.535 +end:
  22.536 +-->
    23.1 --- a/en/ch07-filenames.xml	Fri Mar 20 15:40:06 2009 +0800
    23.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.3 @@ -1,408 +0,0 @@
    23.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    23.5 -
    23.6 -<chapter id="chap.names">
    23.7 -  <?dbhtml filename="file-names-and-pattern-matching.html"?>
    23.8 -  <title>File names and pattern matching</title>
    23.9 -
   23.10 -  <para>Mercurial provides mechanisms that let you work with file
   23.11 -    names in a consistent and expressive way.</para>
   23.12 -
   23.13 -  <sect1>
   23.14 -    <title>Simple file naming</title>
   23.15 -
   23.16 -    <para>Mercurial uses a unified piece of machinery <quote>under the
   23.17 -	hood</quote> to handle file names.  Every command behaves
   23.18 -      uniformly with respect to file names.  The way in which commands
   23.19 -      work with file names is as follows.</para>
   23.20 -
   23.21 -    <para>If you explicitly name real files on the command line,
   23.22 -      Mercurial works with exactly those files, as you would expect.
   23.23 -      &interaction.filenames.files;</para>
   23.24 -
   23.25 -    <para>When you provide a directory name, Mercurial will interpret
   23.26 -      this as <quote>operate on every file in this directory and its
   23.27 -	subdirectories</quote>. Mercurial traverses the files and
   23.28 -      subdirectories in a directory in alphabetical order.  When it
   23.29 -      encounters a subdirectory, it will traverse that subdirectory
   23.30 -      before continuing with the current directory.</para>
   23.31 -
   23.32 -      &interaction.filenames.dirs;
   23.33 -
   23.34 -  </sect1>
   23.35 -  <sect1>
   23.36 -    <title>Running commands without any file names</title>
   23.37 -
   23.38 -    <para>Mercurial's commands that work with file names have useful
   23.39 -      default behaviours when you invoke them without providing any
   23.40 -      file names or patterns.  What kind of behaviour you should
   23.41 -      expect depends on what the command does.  Here are a few rules
   23.42 -      of thumb you can use to predict what a command is likely to do
   23.43 -      if you don't give it any names to work with.</para>
   23.44 -    <itemizedlist>
   23.45 -      <listitem><para>Most commands will operate on the entire working
   23.46 -	  directory. This is what the <command role="hg-cmd">hg
   23.47 -	    add</command> command does, for example.</para>
   23.48 -      </listitem>
   23.49 -      <listitem><para>If the command has effects that are difficult or
   23.50 -	  impossible to reverse, it will force you to explicitly
   23.51 -	  provide at least one name or pattern (see below).  This
   23.52 -	  protects you from accidentally deleting files by running
   23.53 -	  <command role="hg-cmd">hg remove</command> with no
   23.54 -	  arguments, for example.</para>
   23.55 -      </listitem></itemizedlist>
   23.56 -
   23.57 -    <para>It's easy to work around these default behaviours if they
   23.58 -      don't suit you.  If a command normally operates on the whole
   23.59 -      working directory, you can invoke it on just the current
   23.60 -      directory and its subdirectories by giving it the name
   23.61 -      <quote><filename class="directory">.</filename></quote>.</para>
   23.62 -
   23.63 -    &interaction.filenames.wdir-subdir;
   23.64 -
   23.65 -    <para>Along the same lines, some commands normally print file
   23.66 -      names relative to the root of the repository, even if you're
   23.67 -      invoking them from a subdirectory.  Such a command will print
   23.68 -      file names relative to your subdirectory if you give it explicit
   23.69 -      names.  Here, we're going to run <command role="hg-cmd">hg
   23.70 -	status</command> from a subdirectory, and get it to operate on
   23.71 -      the entire working directory while printing file names relative
   23.72 -      to our subdirectory, by passing it the output of the <command
   23.73 -	role="hg-cmd">hg root</command> command.</para>
   23.74 -
   23.75 -      &interaction.filenames.wdir-relname;
   23.76 -
   23.77 -  </sect1>
   23.78 -  <sect1>
   23.79 -    <title>Telling you what's going on</title>
   23.80 -
   23.81 -    <para>The <command role="hg-cmd">hg add</command> example in the
   23.82 -      preceding section illustrates something else that's helpful
   23.83 -      about Mercurial commands.  If a command operates on a file that
   23.84 -      you didn't name explicitly on the command line, it will usually
   23.85 -      print the name of the file, so that you will not be surprised
   23.86 -      what's going on.</para>
   23.87 -
   23.88 -    <para>The principle here is of <emphasis>least
   23.89 -	surprise</emphasis>.  If you've exactly named a file on the
   23.90 -      command line, there's no point in repeating it back at you.  If
   23.91 -      Mercurial is acting on a file <emphasis>implicitly</emphasis>,
   23.92 -      because you provided no names, or a directory, or a pattern (see
   23.93 -      below), it's safest to tell you what it's doing.</para>
   23.94 -
   23.95 -    <para>For commands that behave this way, you can silence them
   23.96 -      using the <option role="hg-opt-global">-q</option> option.  You
   23.97 -      can also get them to print the name of every file, even those
   23.98 -      you've named explicitly, using the <option
   23.99 -	role="hg-opt-global">-v</option> option.</para>
  23.100 -
  23.101 -  </sect1>
  23.102 -  <sect1>
  23.103 -    <title>Using patterns to identify files</title>
  23.104 -
  23.105 -    <para>In addition to working with file and directory names,
  23.106 -      Mercurial lets you use <emphasis>patterns</emphasis> to identify
  23.107 -      files.  Mercurial's pattern handling is expressive.</para>
  23.108 -
  23.109 -    <para>On Unix-like systems (Linux, MacOS, etc.), the job of
  23.110 -      matching file names to patterns normally falls to the shell.  On
  23.111 -      these systems, you must explicitly tell Mercurial that a name is
  23.112 -      a pattern.  On Windows, the shell does not expand patterns, so
  23.113 -      Mercurial will automatically identify names that are patterns,
  23.114 -      and expand them for you.</para>
  23.115 -
  23.116 -    <para>To provide a pattern in place of a regular name on the
  23.117 -      command line, the mechanism is simple:</para>
  23.118 -    <programlisting>syntax:patternbody</programlisting>
  23.119 -    <para>That is, a pattern is identified by a short text string that
  23.120 -      says what kind of pattern this is, followed by a colon, followed
  23.121 -      by the actual pattern.</para>
  23.122 -
  23.123 -    <para>Mercurial supports two kinds of pattern syntax.  The most
  23.124 -      frequently used is called <literal>glob</literal>; this is the
  23.125 -      same kind of pattern matching used by the Unix shell, and should
  23.126 -      be familiar to Windows command prompt users, too.</para>
  23.127 -
  23.128 -    <para>When Mercurial does automatic pattern matching on Windows,
  23.129 -      it uses <literal>glob</literal> syntax.  You can thus omit the
  23.130 -      <quote><literal>glob:</literal></quote> prefix on Windows, but
  23.131 -      it's safe to use it, too.</para>
  23.132 -
  23.133 -    <para>The <literal>re</literal> syntax is more powerful; it lets
  23.134 -      you specify patterns using regular expressions, also known as
  23.135 -      regexps.</para>
  23.136 -
  23.137 -    <para>By the way, in the examples that follow, notice that I'm
  23.138 -      careful to wrap all of my patterns in quote characters, so that
  23.139 -      they won't get expanded by the shell before Mercurial sees
  23.140 -      them.</para>
  23.141 -
  23.142 -    <sect2>
  23.143 -      <title>Shell-style <literal>glob</literal> patterns</title>
  23.144 -
  23.145 -      <para>This is an overview of the kinds of patterns you can use
  23.146 -	when you're matching on glob patterns.</para>
  23.147 -
  23.148 -      <para>The <quote><literal>*</literal></quote> character matches
  23.149 -	any string, within a single directory.</para>
  23.150 -
  23.151 -      &interaction.filenames.glob.star;
  23.152 -
  23.153 -      <para>The <quote><literal>**</literal></quote> pattern matches
  23.154 -	any string, and crosses directory boundaries.  It's not a
  23.155 -	standard Unix glob token, but it's accepted by several popular
  23.156 -	Unix shells, and is very useful.</para>
  23.157 -
  23.158 -      &interaction.filenames.glob.starstar;
  23.159 -
  23.160 -      <para>The <quote><literal>?</literal></quote> pattern matches
  23.161 -	any single character.</para>
  23.162 -
  23.163 -      &interaction.filenames.glob.question;
  23.164 -
  23.165 -      <para>The <quote><literal>[</literal></quote> character begins a
  23.166 -	<emphasis>character class</emphasis>.  This matches any single
  23.167 -	character within the class.  The class ends with a
  23.168 -	<quote><literal>]</literal></quote> character.  A class may
  23.169 -	contain multiple <emphasis>range</emphasis>s of the form
  23.170 -	<quote><literal>a-f</literal></quote>, which is shorthand for
  23.171 -	<quote><literal>abcdef</literal></quote>.</para>
  23.172 -
  23.173 -	&interaction.filenames.glob.range;
  23.174 -
  23.175 -      <para>If the first character after the
  23.176 -	<quote><literal>[</literal></quote> in a character class is a
  23.177 -	<quote><literal>!</literal></quote>, it
  23.178 -	<emphasis>negates</emphasis> the class, making it match any
  23.179 -	single character not in the class.</para>
  23.180 -
  23.181 -      <para>A <quote><literal>{</literal></quote> begins a group of
  23.182 -	subpatterns, where the whole group matches if any subpattern
  23.183 -	in the group matches.  The <quote><literal>,</literal></quote>
  23.184 -	character separates subpatterns, and
  23.185 -	<quote><literal>}</literal></quote> ends the group.</para>
  23.186 -
  23.187 -      &interaction.filenames.glob.group;
  23.188 -
  23.189 -      <sect3>
  23.190 -	<title>Watch out!</title>
  23.191 -
  23.192 -	<para>Don't forget that if you want to match a pattern in any
  23.193 -	  directory, you should not be using the
  23.194 -	  <quote><literal>*</literal></quote> match-any token, as this
  23.195 -	  will only match within one directory.  Instead, use the
  23.196 -	  <quote><literal>**</literal></quote> token.  This small
  23.197 -	  example illustrates the difference between the two.</para>
  23.198 -
  23.199 -	  &interaction.filenames.glob.star-starstar;
  23.200 -
  23.201 -      </sect3>
  23.202 -    </sect2>
  23.203 -    <sect2>
  23.204 -      <title>Regular expression matching with <literal>re</literal>
  23.205 -	patterns</title>
  23.206 -
  23.207 -      <para>Mercurial accepts the same regular expression syntax as
  23.208 -	the Python programming language (it uses Python's regexp
  23.209 -	engine internally). This is based on the Perl language's
  23.210 -	regexp syntax, which is the most popular dialect in use (it's
  23.211 -	also used in Java, for example).</para>
  23.212 -
  23.213 -      <para>I won't discuss Mercurial's regexp dialect in any detail
  23.214 -	here, as regexps are not often used.  Perl-style regexps are
  23.215 -	in any case already exhaustively documented on a multitude of
  23.216 -	web sites, and in many books.  Instead, I will focus here on a
  23.217 -	few things you should know if you find yourself needing to use
  23.218 -	regexps with Mercurial.</para>
  23.219 -
  23.220 -      <para>A regexp is matched against an entire file name, relative
  23.221 -	to the root of the repository.  In other words, even if you're
  23.222 -	already in subbdirectory <filename
  23.223 -	  class="directory">foo</filename>, if you want to match files
  23.224 -	under this directory, your pattern must start with
  23.225 -	<quote><literal>foo/</literal></quote>.</para>
  23.226 -
  23.227 -      <para>One thing to note, if you're familiar with Perl-style
  23.228 -	regexps, is that Mercurial's are <emphasis>rooted</emphasis>.
  23.229 -	That is, a regexp starts matching against the beginning of a
  23.230 -	string; it doesn't look for a match anywhere within the
  23.231 -	string.  To match anywhere in a string, start your pattern
  23.232 -	with <quote><literal>.*</literal></quote>.</para>
  23.233 -
  23.234 -    </sect2>
  23.235 -  </sect1>
  23.236 -  <sect1>
  23.237 -    <title>Filtering files</title>
  23.238 -
  23.239 -    <para>Not only does Mercurial give you a variety of ways to
  23.240 -      specify files; it lets you further winnow those files using
  23.241 -      <emphasis>filters</emphasis>.  Commands that work with file
  23.242 -      names accept two filtering options.</para>
  23.243 -    <itemizedlist>
  23.244 -      <listitem><para><option role="hg-opt-global">-I</option>, or
  23.245 -	  <option role="hg-opt-global">--include</option>, lets you
  23.246 -	  specify a pattern that file names must match in order to be
  23.247 -	  processed.</para>
  23.248 -      </listitem>
  23.249 -      <listitem><para><option role="hg-opt-global">-X</option>, or
  23.250 -	  <option role="hg-opt-global">--exclude</option>, gives you a
  23.251 -	  way to <emphasis>avoid</emphasis> processing files, if they
  23.252 -	  match this pattern.</para>
  23.253 -      </listitem></itemizedlist>
  23.254 -    <para>You can provide multiple <option
  23.255 -	role="hg-opt-global">-I</option> and <option
  23.256 -	role="hg-opt-global">-X</option> options on the command line,
  23.257 -      and intermix them as you please.  Mercurial interprets the
  23.258 -      patterns you provide using glob syntax by default (but you can
  23.259 -      use regexps if you need to).</para>
  23.260 -
  23.261 -    <para>You can read a <option role="hg-opt-global">-I</option>
  23.262 -      filter as <quote>process only the files that match this
  23.263 -	filter</quote>.</para>
  23.264 -
  23.265 -    &interaction.filenames.filter.include;
  23.266 -
  23.267 -    <para>The <option role="hg-opt-global">-X</option> filter is best
  23.268 -      read as <quote>process only the files that don't match this
  23.269 -	pattern</quote>.</para>
  23.270 -
  23.271 -    &interaction.filenames.filter.exclude;
  23.272 -
  23.273 -  </sect1>
  23.274 -  <sect1>
  23.275 -    <title>Ignoring unwanted files and directories</title>
  23.276 -
  23.277 -    <para>XXX.</para>
  23.278 -
  23.279 -  </sect1>
  23.280 -  <sect1 id="sec.names.case">
  23.281 -    <title>Case sensitivity</title>
  23.282 -
  23.283 -    <para>If you're working in a mixed development environment that
  23.284 -      contains both Linux (or other Unix) systems and Macs or Windows
  23.285 -      systems, you should keep in the back of your mind the knowledge
  23.286 -      that they treat the case (<quote>N</quote> versus
  23.287 -      <quote>n</quote>) of file names in incompatible ways.  This is
  23.288 -      not very likely to affect you, and it's easy to deal with if it
  23.289 -      does, but it could surprise you if you don't know about
  23.290 -      it.</para>
  23.291 -
  23.292 -    <para>Operating systems and filesystems differ in the way they
  23.293 -      handle the <emphasis>case</emphasis> of characters in file and
  23.294 -      directory names.  There are three common ways to handle case in
  23.295 -      names.</para>
  23.296 -    <itemizedlist>
  23.297 -      <listitem><para>Completely case insensitive.  Uppercase and
  23.298 -	  lowercase versions of a letter are treated as identical,
  23.299 -	  both when creating a file and during subsequent accesses.
  23.300 -	  This is common on older DOS-based systems.</para>
  23.301 -      </listitem>
  23.302 -      <listitem><para>Case preserving, but insensitive.  When a file
  23.303 -	  or directory is created, the case of its name is stored, and
  23.304 -	  can be retrieved and displayed by the operating system.
  23.305 -	  When an existing file is being looked up, its case is
  23.306 -	  ignored.  This is the standard arrangement on Windows and
  23.307 -	  MacOS.  The names <filename>foo</filename> and
  23.308 -	  <filename>FoO</filename> identify the same file.  This
  23.309 -	  treatment of uppercase and lowercase letters as
  23.310 -	  interchangeable is also referred to as <emphasis>case
  23.311 -	    folding</emphasis>.</para>
  23.312 -      </listitem>
  23.313 -      <listitem><para>Case sensitive.  The case of a name is
  23.314 -	  significant at all times. The names <filename>foo</filename>
  23.315 -	  and {FoO} identify different files.  This is the way Linux
  23.316 -	  and Unix systems normally work.</para>
  23.317 -      </listitem></itemizedlist>
  23.318 -
  23.319 -    <para>On Unix-like systems, it is possible to have any or all of
  23.320 -      the above ways of handling case in action at once.  For example,
  23.321 -      if you use a USB thumb drive formatted with a FAT32 filesystem
  23.322 -      on a Linux system, Linux will handle names on that filesystem in
  23.323 -      a case preserving, but insensitive, way.</para>
  23.324 -
  23.325 -    <sect2>
  23.326 -      <title>Safe, portable repository storage</title>
  23.327 -
  23.328 -      <para>Mercurial's repository storage mechanism is <emphasis>case
  23.329 -	  safe</emphasis>.  It translates file names so that they can
  23.330 -	be safely stored on both case sensitive and case insensitive
  23.331 -	filesystems.  This means that you can use normal file copying
  23.332 -	tools to transfer a Mercurial repository onto, for example, a
  23.333 -	USB thumb drive, and safely move that drive and repository
  23.334 -	back and forth between a Mac, a PC running Windows, and a
  23.335 -	Linux box.</para>
  23.336 -
  23.337 -    </sect2>
  23.338 -    <sect2>
  23.339 -      <title>Detecting case conflicts</title>
  23.340 -
  23.341 -      <para>When operating in the working directory, Mercurial honours
  23.342 -	the naming policy of the filesystem where the working
  23.343 -	directory is located.  If the filesystem is case preserving,
  23.344 -	but insensitive, Mercurial will treat names that differ only
  23.345 -	in case as the same.</para>
  23.346 -
  23.347 -      <para>An important aspect of this approach is that it is
  23.348 -	possible to commit a changeset on a case sensitive (typically
  23.349 -	Linux or Unix) filesystem that will cause trouble for users on
  23.350 -	case insensitive (usually Windows and MacOS) users.  If a
  23.351 -	Linux user commits changes to two files, one named
  23.352 -	<filename>myfile.c</filename> and the other named
  23.353 -	<filename>MyFile.C</filename>, they will be stored correctly
  23.354 -	in the repository.  And in the working directories of other
  23.355 -	Linux users, they will be correctly represented as separate
  23.356 -	files.</para>
  23.357 -
  23.358 -      <para>If a Windows or Mac user pulls this change, they will not
  23.359 -	initially have a problem, because Mercurial's repository
  23.360 -	storage mechanism is case safe.  However, once they try to
  23.361 -	<command role="hg-cmd">hg update</command> the working
  23.362 -	directory to that changeset, or <command role="hg-cmd">hg
  23.363 -	  merge</command> with that changeset, Mercurial will spot the
  23.364 -	conflict between the two file names that the filesystem would
  23.365 -	treat as the same, and forbid the update or merge from
  23.366 -	occurring.</para>
  23.367 -
  23.368 -    </sect2>
  23.369 -    <sect2>
  23.370 -      <title>Fixing a case conflict</title>
  23.371 -
  23.372 -      <para>If you are using Windows or a Mac in a mixed environment
  23.373 -	where some of your collaborators are using Linux or Unix, and
  23.374 -	Mercurial reports a case folding conflict when you try to
  23.375 -	<command role="hg-cmd">hg update</command> or <command
  23.376 -	  role="hg-cmd">hg merge</command>, the procedure to fix the
  23.377 -	problem is simple.</para>
  23.378 -
  23.379 -      <para>Just find a nearby Linux or Unix box, clone the problem
  23.380 -	repository onto it, and use Mercurial's <command
  23.381 -	  role="hg-cmd">hg rename</command> command to change the
  23.382 -	names of any offending files or directories so that they will
  23.383 -	no longer cause case folding conflicts.  Commit this change,
  23.384 -	<command role="hg-cmd">hg pull</command> or <command
  23.385 -	  role="hg-cmd">hg push</command> it across to your Windows or
  23.386 -	MacOS system, and <command role="hg-cmd">hg update</command>
  23.387 -	to the revision with the non-conflicting names.</para>
  23.388 -
  23.389 -      <para>The changeset with case-conflicting names will remain in
  23.390 -	your project's history, and you still won't be able to
  23.391 -	<command role="hg-cmd">hg update</command> your working
  23.392 -	directory to that changeset on a Windows or MacOS system, but
  23.393 -	you can continue development unimpeded.</para>
  23.394 -
  23.395 -      <note>
  23.396 -	<para>  Prior to version 0.9.3, Mercurial did not use a case
  23.397 -	  safe repository storage mechanism, and did not detect case
  23.398 -	  folding conflicts.  If you are using an older version of
  23.399 -	  Mercurial on Windows or MacOS, I strongly recommend that you
  23.400 -	  upgrade.</para>
  23.401 -      </note>
  23.402 -
  23.403 -    </sect2>
  23.404 -  </sect1>
  23.405 -</chapter>
  23.406 -
  23.407 -<!--
  23.408 -local variables: 
  23.409 -sgml-parent-document: ("00book.xml" "book" "chapter")
  23.410 -end:
  23.411 --->
    24.1 --- a/en/ch08-branch.xml	Fri Mar 20 15:40:06 2009 +0800
    24.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.3 @@ -1,533 +0,0 @@
    24.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    24.5 -
    24.6 -<chapter id="chap.branch">
    24.7 -  <?dbhtml filename="managing-releases-and-branchy-development.html"?>
    24.8 -  <title>Managing releases and branchy development</title>
    24.9 -
   24.10 -  <para>Mercurial provides several mechanisms for you to manage a
   24.11 -    project that is making progress on multiple fronts at once.  To
   24.12 -    understand these mechanisms, let's first take a brief look at a
   24.13 -    fairly normal software project structure.</para>
   24.14 -
   24.15 -  <para>Many software projects issue periodic <quote>major</quote>
   24.16 -    releases that contain substantial new features.  In parallel, they
   24.17 -    may issue <quote>minor</quote> releases.  These are usually
   24.18 -    identical to the major releases off which they're based, but with
   24.19 -    a few bugs fixed.</para>
   24.20 -
   24.21 -  <para>In this chapter, we'll start by talking about how to keep
   24.22 -    records of project milestones such as releases.  We'll then
   24.23 -    continue on to talk about the flow of work between different
   24.24 -    phases of a project, and how Mercurial can help you to isolate and
   24.25 -    manage this work.</para>
   24.26 -
   24.27 -  <sect1>
   24.28 -    <title>Giving a persistent name to a revision</title>
   24.29 -
   24.30 -    <para>Once you decide that you'd like to call a particular
   24.31 -      revision a <quote>release</quote>, it's a good idea to record
   24.32 -      the identity of that revision. This will let you reproduce that
   24.33 -      release at a later date, for whatever purpose you might need at
   24.34 -      the time (reproducing a bug, porting to a new platform, etc).
   24.35 -      &interaction.tag.init;</para>
   24.36 -
   24.37 -    <para>Mercurial lets you give a permanent name to any revision
   24.38 -      using the <command role="hg-cmd">hg tag</command> command.  Not
   24.39 -      surprisingly, these names are called <quote>tags</quote>.</para>
   24.40 -
   24.41 -    &interaction.tag.tag;
   24.42 -
   24.43 -    <para>A tag is nothing more than a <quote>symbolic name</quote>
   24.44 -      for a revision.  Tags exist purely for your convenience, so that
   24.45 -      you have a handy permanent way to refer to a revision; Mercurial
   24.46 -      doesn't interpret the tag names you use in any way.  Neither
   24.47 -      does Mercurial place any restrictions on the name of a tag,
   24.48 -      beyond a few that are necessary to ensure that a tag can be
   24.49 -      parsed unambiguously.  A tag name cannot contain any of the
   24.50 -      following characters:</para>
   24.51 -    <itemizedlist>
   24.52 -      <listitem><para>Colon (ASCII 58,
   24.53 -	  <quote><literal>:</literal></quote>)</para>
   24.54 -      </listitem>
   24.55 -      <listitem><para>Carriage return (ASCII 13,
   24.56 -	  <quote><literal>\r</literal></quote>)</para>
   24.57 -      </listitem>
   24.58 -      <listitem><para>Newline (ASCII 10,
   24.59 -	  <quote><literal>\n</literal></quote>)</para>
   24.60 -      </listitem></itemizedlist>
   24.61 -
   24.62 -    <para>You can use the <command role="hg-cmd">hg tags</command>
   24.63 -      command to display the tags present in your repository.  In the
   24.64 -      output, each tagged revision is identified first by its name,
   24.65 -      then by revision number, and finally by the unique hash of the
   24.66 -      revision.</para>
   24.67 -
   24.68 -    &interaction.tag.tags;
   24.69 -
   24.70 -    <para>Notice that <literal>tip</literal> is listed in the output
   24.71 -      of <command role="hg-cmd">hg tags</command>.  The
   24.72 -      <literal>tip</literal> tag is a special <quote>floating</quote>
   24.73 -      tag, which always identifies the newest revision in the
   24.74 -      repository.</para>
   24.75 -
   24.76 -    <para>In the output of the <command role="hg-cmd">hg
   24.77 -	tags</command> command, tags are listed in reverse order, by
   24.78 -      revision number.  This usually means that recent tags are listed
   24.79 -      before older tags.  It also means that <literal>tip</literal> is
   24.80 -      always going to be the first tag listed in the output of
   24.81 -      <command role="hg-cmd">hg tags</command>.</para>
   24.82 -
   24.83 -    <para>When you run <command role="hg-cmd">hg log</command>, if it
   24.84 -      displays a revision that has tags associated with it, it will
   24.85 -      print those tags.</para>
   24.86 -
   24.87 -    &interaction.tag.log;
   24.88 -
   24.89 -    <para>Any time you need to provide a revision ID to a Mercurial
   24.90 -      command, the command will accept a tag name in its place.
   24.91 -      Internally, Mercurial will translate your tag name into the
   24.92 -      corresponding revision ID, then use that.</para>
   24.93 -
   24.94 -    &interaction.tag.log.v1.0;
   24.95 -
   24.96 -    <para>There's no limit on the number of tags you can have in a
   24.97 -      repository, or on the number of tags that a single revision can
   24.98 -      have.  As a practical matter, it's not a great idea to have
   24.99 -      <quote>too many</quote> (a number which will vary from project
  24.100 -      to project), simply because tags are supposed to help you to
  24.101 -      find revisions.  If you have lots of tags, the ease of using
  24.102 -      them to identify revisions diminishes rapidly.</para>
  24.103 -
  24.104 -    <para>For example, if your project has milestones as frequent as
  24.105 -      every few days, it's perfectly reasonable to tag each one of
  24.106 -      those.  But if you have a continuous build system that makes
  24.107 -      sure every revision can be built cleanly, you'd be introducing a
  24.108 -      lot of noise if you were to tag every clean build.  Instead, you
  24.109 -      could tag failed builds (on the assumption that they're rare!),
  24.110 -      or simply not use tags to track buildability.</para>
  24.111 -
  24.112 -    <para>If you want to remove a tag that you no longer want, use
  24.113 -      <command role="hg-cmd">hg tag --remove</command>.</para>
  24.114 -
  24.115 -    &interaction.tag.remove;
  24.116 -
  24.117 -    <para>You can also modify a tag at any time, so that it identifies
  24.118 -      a different revision, by simply issuing a new <command
  24.119 -	role="hg-cmd">hg tag</command> command. You'll have to use the
  24.120 -      <option role="hg-opt-tag">-f</option> option to tell Mercurial
  24.121 -      that you <emphasis>really</emphasis> want to update the
  24.122 -      tag.</para>
  24.123 -
  24.124 -    &interaction.tag.replace;
  24.125 -
  24.126 -    <para>There will still be a permanent record of the previous
  24.127 -      identity of the tag, but Mercurial will no longer use it.
  24.128 -      There's thus no penalty to tagging the wrong revision; all you
  24.129 -      have to do is turn around and tag the correct revision once you
  24.130 -      discover your error.</para>
  24.131 -
  24.132 -    <para>Mercurial stores tags in a normal revision-controlled file
  24.133 -      in your repository.  If you've created any tags, you'll find
  24.134 -      them in a file named <filename
  24.135 -	role="special">.hgtags</filename>.  When you run the <command
  24.136 -	role="hg-cmd">hg tag</command> command, Mercurial modifies
  24.137 -      this file, then automatically commits the change to it.  This
  24.138 -      means that every time you run <command role="hg-cmd">hg
  24.139 -	tag</command>, you'll see a corresponding changeset in the
  24.140 -      output of <command role="hg-cmd">hg log</command>.</para>
  24.141 -
  24.142 -    &interaction.tag.tip;
  24.143 -
  24.144 -    <sect2>
  24.145 -      <title>Handling tag conflicts during a merge</title>
  24.146 -
  24.147 -      <para>You won't often need to care about the <filename
  24.148 -	  role="special">.hgtags</filename> file, but it sometimes
  24.149 -	makes its presence known during a merge.  The format of the
  24.150 -	file is simple: it consists of a series of lines.  Each line
  24.151 -	starts with a changeset hash, followed by a space, followed by
  24.152 -	the name of a tag.</para>
  24.153 -
  24.154 -      <para>If you're resolving a conflict in the <filename
  24.155 -	  role="special">.hgtags</filename> file during a merge,
  24.156 -	there's one twist to modifying the <filename
  24.157 -	  role="special">.hgtags</filename> file: when Mercurial is
  24.158 -	parsing the tags in a repository, it
  24.159 -	<emphasis>never</emphasis> reads the working copy of the
  24.160 -	<filename role="special">.hgtags</filename> file.  Instead, it
  24.161 -	reads the <emphasis>most recently committed</emphasis>
  24.162 -	revision of the file.</para>
  24.163 -
  24.164 -      <para>An unfortunate consequence of this design is that you
  24.165 -	can't actually verify that your merged <filename
  24.166 -	  role="special">.hgtags</filename> file is correct until
  24.167 -	<emphasis>after</emphasis> you've committed a change.  So if
  24.168 -	you find yourself resolving a conflict on <filename
  24.169 -	  role="special">.hgtags</filename> during a merge, be sure to
  24.170 -	run <command role="hg-cmd">hg tags</command> after you commit.
  24.171 -	If it finds an error in the <filename
  24.172 -	  role="special">.hgtags</filename> file, it will report the
  24.173 -	location of the error, which you can then fix and commit.  You
  24.174 -	should then run <command role="hg-cmd">hg tags</command>
  24.175 -	again, just to be sure that your fix is correct.</para>
  24.176 -
  24.177 -    </sect2>
  24.178 -    <sect2>
  24.179 -      <title>Tags and cloning</title>
  24.180 -
  24.181 -      <para>You may have noticed that the <command role="hg-cmd">hg
  24.182 -	  clone</command> command has a <option
  24.183 -	  role="hg-opt-clone">-r</option> option that lets you clone
  24.184 -	an exact copy of the repository as of a particular changeset.
  24.185 -	The new clone will not contain any project history that comes
  24.186 -	after the revision you specified.  This has an interaction
  24.187 -	with tags that can surprise the unwary.</para>
  24.188 -
  24.189 -      <para>Recall that a tag is stored as a revision to the <filename
  24.190 -	  role="special">.hgtags</filename> file, so that when you
  24.191 -	create a tag, the changeset in which it's recorded necessarily
  24.192 -	refers to an older changeset.  When you run <command
  24.193 -	  role="hg-cmd">hg clone -r foo</command> to clone a
  24.194 -	repository as of tag <literal>foo</literal>, the new clone
  24.195 -	<emphasis>will not contain the history that created the
  24.196 -	  tag</emphasis> that you used to clone the repository.  The
  24.197 -	result is that you'll get exactly the right subset of the
  24.198 -	project's history in the new repository, but
  24.199 -	<emphasis>not</emphasis> the tag you might have
  24.200 -	expected.</para>
  24.201 -
  24.202 -    </sect2>
  24.203 -    <sect2>
  24.204 -      <title>When permanent tags are too much</title>
  24.205 -
  24.206 -      <para>Since Mercurial's tags are revision controlled and carried
  24.207 -	around with a project's history, everyone you work with will
  24.208 -	see the tags you create.  But giving names to revisions has
  24.209 -	uses beyond simply noting that revision
  24.210 -	<literal>4237e45506ee</literal> is really
  24.211 -	<literal>v2.0.2</literal>.  If you're trying to track down a
  24.212 -	subtle bug, you might want a tag to remind you of something
  24.213 -	like <quote>Anne saw the symptoms with this
  24.214 -	  revision</quote>.</para>
  24.215 -
  24.216 -      <para>For cases like this, what you might want to use are
  24.217 -	<emphasis>local</emphasis> tags. You can create a local tag
  24.218 -	with the <option role="hg-opt-tag">-l</option> option to the
  24.219 -	<command role="hg-cmd">hg tag</command> command.  This will
  24.220 -	store the tag in a file called <filename
  24.221 -	  role="special">.hg/localtags</filename>.  Unlike <filename
  24.222 -	  role="special">.hgtags</filename>, <filename
  24.223 -	  role="special">.hg/localtags</filename> is not revision
  24.224 -	controlled.  Any tags you create using <option
  24.225 -	  role="hg-opt-tag">-l</option> remain strictly local to the
  24.226 -	repository you're currently working in.</para>
  24.227 -
  24.228 -    </sect2>
  24.229 -  </sect1>
  24.230 -  <sect1>
  24.231 -    <title>The flow of changes&emdash;big picture vs. little</title>
  24.232 -
  24.233 -    <para>To return to the outline I sketched at the beginning of a
  24.234 -      chapter, let's think about a project that has multiple
  24.235 -      concurrent pieces of work under development at once.</para>
  24.236 -
  24.237 -    <para>There might be a push for a new <quote>main</quote> release;
  24.238 -      a new minor bugfix release to the last main release; and an
  24.239 -      unexpected <quote>hot fix</quote> to an old release that is now
  24.240 -      in maintenance mode.</para>
  24.241 -
  24.242 -    <para>The usual way people refer to these different concurrent
  24.243 -      directions of development is as <quote>branches</quote>.
  24.244 -      However, we've already seen numerous times that Mercurial treats
  24.245 -      <emphasis>all of history</emphasis> as a series of branches and
  24.246 -      merges.  Really, what we have here is two ideas that are
  24.247 -      peripherally related, but which happen to share a name.</para>
  24.248 -    <itemizedlist>
  24.249 -      <listitem><para><quote>Big picture</quote> branches represent
  24.250 -	  the sweep of a project's evolution; people give them names,
  24.251 -	  and talk about them in conversation.</para>
  24.252 -      </listitem>
  24.253 -      <listitem><para><quote>Little picture</quote> branches are
  24.254 -	  artefacts of the day-to-day activity of developing and
  24.255 -	  merging changes.  They expose the narrative of how the code
  24.256 -	  was developed.</para>
  24.257 -      </listitem></itemizedlist>
  24.258 -
  24.259 -  </sect1>
  24.260 -  <sect1>
  24.261 -    <title>Managing big-picture branches in repositories</title>
  24.262 -
  24.263 -    <para>The easiest way to isolate a <quote>big picture</quote>
  24.264 -      branch in Mercurial is in a dedicated repository.  If you have
  24.265 -      an existing shared repository&emdash;let's call it
  24.266 -      <literal>myproject</literal>&emdash;that reaches a
  24.267 -      <quote>1.0</quote> milestone, you can start to prepare for
  24.268 -      future maintenance releases on top of version 1.0 by tagging the
  24.269 -      revision from which you prepared the 1.0 release.</para>
  24.270 -
  24.271 -    &interaction.branch-repo.tag;
  24.272 -
  24.273 -    <para>You can then clone a new shared
  24.274 -      <literal>myproject-1.0.1</literal> repository as of that
  24.275 -      tag.</para>
  24.276 -
  24.277 -    &interaction.branch-repo.clone;
  24.278 -
  24.279 -    <para>Afterwards, if someone needs to work on a bug fix that ought
  24.280 -      to go into an upcoming 1.0.1 minor release, they clone the
  24.281 -      <literal>myproject-1.0.1</literal> repository, make their
  24.282 -      changes, and push them back.</para>
  24.283 -
  24.284 -    &interaction.branch-repo.bugfix;
  24.285 -
  24.286 -    <para>Meanwhile, development for
  24.287 -      the next major release can continue, isolated and unabated, in
  24.288 -      the <literal>myproject</literal> repository.</para>
  24.289 -
  24.290 -    &interaction.branch-repo.new;
  24.291 -
  24.292 -  </sect1>
  24.293 -  <sect1>
  24.294 -    <title>Don't repeat yourself: merging across branches</title>
  24.295 -
  24.296 -    <para>In many cases, if you have a bug to fix on a maintenance
  24.297 -      branch, the chances are good that the bug exists on your
  24.298 -      project's main branch (and possibly other maintenance branches,
  24.299 -      too).  It's a rare developer who wants to fix the same bug
  24.300 -      multiple times, so let's look at a few ways that Mercurial can
  24.301 -      help you to manage these bugfixes without duplicating your
  24.302 -      work.</para>
  24.303 -
  24.304 -    <para>In the simplest instance, all you need to do is pull changes
  24.305 -      from your maintenance branch into your local clone of the target
  24.306 -      branch.</para>
  24.307 -
  24.308 -    &interaction.branch-repo.pull;
  24.309 -
  24.310 -    <para>You'll then need to merge the heads of the two branches, and
  24.311 -      push back to the main branch.</para>
  24.312 -
  24.313 -    &interaction.branch-repo.merge;
  24.314 -
  24.315 -  </sect1>
  24.316 -  <sect1>
  24.317 -    <title>Naming branches within one repository</title>
  24.318 -
  24.319 -    <para>In most instances, isolating branches in repositories is the
  24.320 -      right approach.  Its simplicity makes it easy to understand; and
  24.321 -      so it's hard to make mistakes.  There's a one-to-one
  24.322 -      relationship between branches you're working in and directories
  24.323 -      on your system.  This lets you use normal (non-Mercurial-aware)
  24.324 -      tools to work on files within a branch/repository.</para>
  24.325 -
  24.326 -    <para>If you're more in the <quote>power user</quote> category
  24.327 -      (<emphasis>and</emphasis> your collaborators are too), there is
  24.328 -      an alternative way of handling branches that you can consider.
  24.329 -      I've already mentioned the human-level distinction between
  24.330 -      <quote>small picture</quote> and <quote>big picture</quote>
  24.331 -      branches.  While Mercurial works with multiple <quote>small
  24.332 -	picture</quote> branches in a repository all the time (for
  24.333 -      example after you pull changes in, but before you merge them),
  24.334 -      it can <emphasis>also</emphasis> work with multiple <quote>big
  24.335 -	picture</quote> branches.</para>
  24.336 -
  24.337 -    <para>The key to working this way is that Mercurial lets you
  24.338 -      assign a persistent <emphasis>name</emphasis> to a branch.
  24.339 -      There always exists a branch named <literal>default</literal>.
  24.340 -      Even before you start naming branches yourself, you can find
  24.341 -      traces of the <literal>default</literal> branch if you look for
  24.342 -      them.</para>
  24.343 -
  24.344 -    <para>As an example, when you run the <command role="hg-cmd">hg
  24.345 -	commit</command> command, and it pops up your editor so that
  24.346 -      you can enter a commit message, look for a line that contains
  24.347 -      the text <quote><literal>HG: branch default</literal></quote> at
  24.348 -      the bottom. This is telling you that your commit will occur on
  24.349 -      the branch named <literal>default</literal>.</para>
  24.350 -
  24.351 -    <para>To start working with named branches, use the <command
  24.352 -	role="hg-cmd">hg branches</command> command.  This command
  24.353 -      lists the named branches already present in your repository,
  24.354 -      telling you which changeset is the tip of each.</para>
  24.355 -
  24.356 -    &interaction.branch-named.branches;
  24.357 -
  24.358 -    <para>Since you haven't created any named branches yet, the only
  24.359 -      one that exists is <literal>default</literal>.</para>
  24.360 -
  24.361 -    <para>To find out what the <quote>current</quote> branch is, run
  24.362 -      the <command role="hg-cmd">hg branch</command> command, giving
  24.363 -      it no arguments.  This tells you what branch the parent of the
  24.364 -      current changeset is on.</para>
  24.365 -
  24.366 -    &interaction.branch-named.branch;
  24.367 -
  24.368 -    <para>To create a new branch, run the <command role="hg-cmd">hg
  24.369 -	branch</command> command again.  This time, give it one
  24.370 -      argument: the name of the branch you want to create.</para>
  24.371 -
  24.372 -    &interaction.branch-named.create;
  24.373 -
  24.374 -    <para>After you've created a branch, you might wonder what effect
  24.375 -      the <command role="hg-cmd">hg branch</command> command has had.
  24.376 -      What do the <command role="hg-cmd">hg status</command> and
  24.377 -      <command role="hg-cmd">hg tip</command> commands report?</para>
  24.378 -
  24.379 -    &interaction.branch-named.status;
  24.380 -
  24.381 -    <para>Nothing has changed in the
  24.382 -      working directory, and there's been no new history created.  As
  24.383 -      this suggests, running the <command role="hg-cmd">hg
  24.384 -	branch</command> command has no permanent effect; it only
  24.385 -      tells Mercurial what branch name to use the
  24.386 -      <emphasis>next</emphasis> time you commit a changeset.</para>
  24.387 -
  24.388 -    <para>When you commit a change, Mercurial records the name of the
  24.389 -      branch on which you committed.  Once you've switched from the
  24.390 -      <literal>default</literal> branch to another and committed,
  24.391 -      you'll see the name of the new branch show up in the output of
  24.392 -      <command role="hg-cmd">hg log</command>, <command
  24.393 -	role="hg-cmd">hg tip</command>, and other commands that
  24.394 -      display the same kind of output.</para>
  24.395 -
  24.396 -    &interaction.branch-named.commit;
  24.397 -
  24.398 -    <para>The <command role="hg-cmd">hg log</command>-like commands
  24.399 -      will print the branch name of every changeset that's not on the
  24.400 -      <literal>default</literal> branch.  As a result, if you never
  24.401 -      use named branches, you'll never see this information.</para>
  24.402 -
  24.403 -    <para>Once you've named a branch and committed a change with that
  24.404 -      name, every subsequent commit that descends from that change
  24.405 -      will inherit the same branch name.  You can change the name of a
  24.406 -      branch at any time, using the <command role="hg-cmd">hg
  24.407 -	branch</command> command.</para>
  24.408 -
  24.409 -    &interaction.branch-named.rebranch;
  24.410 -
  24.411 -    <para>In practice, this is something you won't do very often, as
  24.412 -      branch names tend to have fairly long lifetimes.  (This isn't a
  24.413 -      rule, just an observation.)</para>
  24.414 -
  24.415 -  </sect1>
  24.416 -  <sect1>
  24.417 -    <title>Dealing with multiple named branches in a
  24.418 -      repository</title>
  24.419 -
  24.420 -    <para>If you have more than one named branch in a repository,
  24.421 -      Mercurial will remember the branch that your working directory
  24.422 -      on when you start a command like <command role="hg-cmd">hg
  24.423 -	update</command> or <command role="hg-cmd">hg pull
  24.424 -	-u</command>.  It will update the working directory to the tip
  24.425 -      of this branch, no matter what the <quote>repo-wide</quote> tip
  24.426 -      is.  To update to a revision that's on a different named branch,
  24.427 -      you may need to use the <option role="hg-opt-update">-C</option>
  24.428 -      option to <command role="hg-cmd">hg update</command>.</para>
  24.429 -
  24.430 -    <para>This behaviour is a little subtle, so let's see it in
  24.431 -      action.  First, let's remind ourselves what branch we're
  24.432 -      currently on, and what branches are in our repository.</para>
  24.433 -
  24.434 -    &interaction.branch-named.parents;
  24.435 -
  24.436 -    <para>We're on the <literal>bar</literal> branch, but there also
  24.437 -      exists an older <command role="hg-cmd">hg foo</command>
  24.438 -      branch.</para>
  24.439 -
  24.440 -    <para>We can <command role="hg-cmd">hg update</command> back and
  24.441 -      forth between the tips of the <literal>foo</literal> and
  24.442 -      <literal>bar</literal> branches without needing to use the
  24.443 -      <option role="hg-opt-update">-C</option> option, because this
  24.444 -      only involves going backwards and forwards linearly through our
  24.445 -      change history.</para>
  24.446 -
  24.447 -    &interaction.branch-named.update-switchy;
  24.448 -
  24.449 -    <para>If we go back to the <literal>foo</literal> branch and then
  24.450 -      run <command role="hg-cmd">hg update</command>, it will keep us
  24.451 -      on <literal>foo</literal>, not move us to the tip of
  24.452 -      <literal>bar</literal>.</para>
  24.453 -
  24.454 -    &interaction.branch-named.update-nothing;
  24.455 -
  24.456 -    <para>Committing a new change on the <literal>foo</literal> branch
  24.457 -      introduces a new head.</para>
  24.458 -
  24.459 -    &interaction.branch-named.foo-commit;
  24.460 -
  24.461 -  </sect1>
  24.462 -  <sect1>
  24.463 -    <title>Branch names and merging</title>
  24.464 -
  24.465 -    <para>As you've probably noticed, merges in Mercurial are not
  24.466 -      symmetrical. Let's say our repository has two heads, 17 and 23.
  24.467 -      If I <command role="hg-cmd">hg update</command> to 17 and then
  24.468 -      <command role="hg-cmd">hg merge</command> with 23, Mercurial
  24.469 -      records 17 as the first parent of the merge, and 23 as the
  24.470 -      second.  Whereas if I <command role="hg-cmd">hg update</command>
  24.471 -      to 23 and then <command role="hg-cmd">hg merge</command> with
  24.472 -      17, it records 23 as the first parent, and 17 as the
  24.473 -      second.</para>
  24.474 -
  24.475 -    <para>This affects Mercurial's choice of branch name when you
  24.476 -      merge.  After a merge, Mercurial will retain the branch name of
  24.477 -      the first parent when you commit the result of the merge.  If
  24.478 -      your first parent's branch name is <literal>foo</literal>, and
  24.479 -      you merge with <literal>bar</literal>, the branch name will
  24.480 -      still be <literal>foo</literal> after you merge.</para>
  24.481 -
  24.482 -    <para>It's not unusual for a repository to contain multiple heads,
  24.483 -      each with the same branch name.  Let's say I'm working on the
  24.484 -      <literal>foo</literal> branch, and so are you.  We commit
  24.485 -      different changes; I pull your changes; I now have two heads,
  24.486 -      each claiming to be on the <literal>foo</literal> branch.  The
  24.487 -      result of a merge will be a single head on the
  24.488 -      <literal>foo</literal> branch, as you might hope.</para>
  24.489 -
  24.490 -    <para>But if I'm working on the <literal>bar</literal> branch, and
  24.491 -      I merge work from the <literal>foo</literal> branch, the result
  24.492 -      will remain on the <literal>bar</literal> branch.</para>
  24.493 -
  24.494 -    &interaction.branch-named.merge;
  24.495 -
  24.496 -    <para>To give a more concrete example, if I'm working on the
  24.497 -      <literal>bleeding-edge</literal> branch, and I want to bring in
  24.498 -      the latest fixes from the <literal>stable</literal> branch,
  24.499 -      Mercurial will choose the <quote>right</quote>
  24.500 -      (<literal>bleeding-edge</literal>) branch name when I pull and
  24.501 -      merge from <literal>stable</literal>.</para>
  24.502 -
  24.503 -  </sect1>
  24.504 -  <sect1>
  24.505 -    <title>Branch naming is generally useful</title>
  24.506 -
  24.507 -    <para>You shouldn't think of named branches as applicable only to
  24.508 -      situations where you have multiple long-lived branches
  24.509 -      cohabiting in a single repository.  They're very useful even in
  24.510 -      the one-branch-per-repository case.</para>
  24.511 -
  24.512 -    <para>In the simplest case, giving a name to each branch gives you
  24.513 -      a permanent record of which branch a changeset originated on.
  24.514 -      This gives you more context when you're trying to follow the
  24.515 -      history of a long-lived branchy project.</para>
  24.516 -
  24.517 -    <para>If you're working with shared repositories, you can set up a
  24.518 -      <literal role="hook">pretxnchangegroup</literal> hook on each
  24.519 -      that will block incoming changes that have the
  24.520 -      <quote>wrong</quote> branch name.  This provides a simple, but
  24.521 -      effective, defence against people accidentally pushing changes
  24.522 -      from a <quote>bleeding edge</quote> branch to a
  24.523 -      <quote>stable</quote> branch.  Such a hook might look like this
  24.524 -      inside the shared repo's <filename role="special">
  24.525 -	/.hgrc</filename>.</para>
  24.526 -    <programlisting>[hooks]
  24.527 -pretxnchangegroup.branch = hg heads --template '{branches} ' | grep mybranch</programlisting>
  24.528 -
  24.529 -  </sect1>
  24.530 -</chapter>
  24.531 -
  24.532 -<!--
  24.533 -local variables: 
  24.534 -sgml-parent-document: ("00book.xml" "book" "chapter")
  24.535 -end:
  24.536 --->
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/en/ch08-undo.xml	Fri Mar 20 16:43:35 2009 +0800
    25.3 @@ -0,0 +1,1083 @@
    25.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    25.5 +
    25.6 +<chapter id="chap.undo">
    25.7 +  <?dbhtml filename="finding-and-fixing-mistakes.html"?>
    25.8 +  <title>Finding and fixing mistakes</title>
    25.9 +
   25.10 +  <para>To err might be human, but to really handle the consequences
   25.11 +    well takes a top-notch revision control system.  In this chapter,
   25.12 +    we'll discuss some of the techniques you can use when you find
   25.13 +    that a problem has crept into your project.  Mercurial has some
   25.14 +    highly capable features that will help you to isolate the sources
   25.15 +    of problems, and to handle them appropriately.</para>
   25.16 +
   25.17 +  <sect1>
   25.18 +    <title>Erasing local history</title>
   25.19 +
   25.20 +    <sect2>
   25.21 +      <title>The accidental commit</title>
   25.22 +
   25.23 +      <para>I have the occasional but persistent problem of typing
   25.24 +	rather more quickly than I can think, which sometimes results
   25.25 +	in me committing a changeset that is either incomplete or
   25.26 +	plain wrong.  In my case, the usual kind of incomplete
   25.27 +	changeset is one in which I've created a new source file, but
   25.28 +	forgotten to <command role="hg-cmd">hg add</command> it.  A
   25.29 +	<quote>plain wrong</quote> changeset is not as common, but no
   25.30 +	less annoying.</para>
   25.31 +
   25.32 +    </sect2>
   25.33 +    <sect2 id="sec.undo.rollback">
   25.34 +      <title>Rolling back a transaction</title>
   25.35 +
   25.36 +      <para>In section <xref linkend="sec.concepts.txn"/>, I mentioned
   25.37 +	that Mercurial treats each modification of a repository as a
   25.38 +	<emphasis>transaction</emphasis>.  Every time you commit a
   25.39 +	changeset or pull changes from another repository, Mercurial
   25.40 +	remembers what you did.  You can undo, or <emphasis>roll
   25.41 +	  back</emphasis>, exactly one of these actions using the
   25.42 +	<command role="hg-cmd">hg rollback</command> command.  (See
   25.43 +	section <xref linkend="sec.undo.rollback-after-push"/> for an
   25.44 +	important caveat about the use of this command.)</para>
   25.45 +
   25.46 +      <para>Here's a mistake that I often find myself making:
   25.47 +	committing a change in which I've created a new file, but
   25.48 +	forgotten to <command role="hg-cmd">hg add</command>
   25.49 +	it.</para>
   25.50 +
   25.51 +      &interaction.rollback.commit;
   25.52 +
   25.53 +      <para>Looking at the output of <command role="hg-cmd">hg
   25.54 +	  status</command> after the commit immediately confirms the
   25.55 +	error.</para>
   25.56 +
   25.57 +      &interaction.rollback.status;
   25.58 +
   25.59 +      <para>The commit captured the changes to the file
   25.60 +	<filename>a</filename>, but not the new file
   25.61 +	<filename>b</filename>.  If I were to push this changeset to a
   25.62 +	repository that I shared with a colleague, the chances are
   25.63 +	high that something in <filename>a</filename> would refer to
   25.64 +	<filename>b</filename>, which would not be present in their
   25.65 +	repository when they pulled my changes.  I would thus become
   25.66 +	the object of some indignation.</para>
   25.67 +
   25.68 +      <para>However, luck is with me&emdash;I've caught my error
   25.69 +	before I pushed the changeset.  I use the <command
   25.70 +	  role="hg-cmd">hg rollback</command> command, and Mercurial
   25.71 +	makes that last changeset vanish.</para>
   25.72 +
   25.73 +      &interaction.rollback.rollback;
   25.74 +
   25.75 +      <para>Notice that the changeset is no longer present in the
   25.76 +	repository's history, and the working directory once again
   25.77 +	thinks that the file <filename>a</filename> is modified.  The
   25.78 +	commit and rollback have left the working directory exactly as
   25.79 +	it was prior to the commit; the changeset has been completely
   25.80 +	erased.  I can now safely <command role="hg-cmd">hg
   25.81 +	  add</command> the file <filename>b</filename>, and rerun my
   25.82 +	commit.</para>
   25.83 +
   25.84 +      &interaction.rollback.add;
   25.85 +
   25.86 +    </sect2>
   25.87 +    <sect2>
   25.88 +      <title>The erroneous pull</title>
   25.89 +
   25.90 +      <para>It's common practice with Mercurial to maintain separate
   25.91 +	development branches of a project in different repositories.
   25.92 +	Your development team might have one shared repository for
   25.93 +	your project's <quote>0.9</quote> release, and another,
   25.94 +	containing different changes, for the <quote>1.0</quote>
   25.95 +	release.</para>
   25.96 +
   25.97 +      <para>Given this, you can imagine that the consequences could be
   25.98 +	messy if you had a local <quote>0.9</quote> repository, and
   25.99 +	accidentally pulled changes from the shared <quote>1.0</quote>
  25.100 +	repository into it.  At worst, you could be paying
  25.101 +	insufficient attention, and push those changes into the shared
  25.102 +	<quote>0.9</quote> tree, confusing your entire team (but don't
  25.103 +	worry, we'll return to this horror scenario later).  However,
  25.104 +	it's more likely that you'll notice immediately, because
  25.105 +	Mercurial will display the URL it's pulling from, or you will
  25.106 +	see it pull a suspiciously large number of changes into the
  25.107 +	repository.</para>
  25.108 +
  25.109 +      <para>The <command role="hg-cmd">hg rollback</command> command
  25.110 +	will work nicely to expunge all of the changesets that you
  25.111 +	just pulled.  Mercurial groups all changes from one <command
  25.112 +	  role="hg-cmd">hg pull</command> into a single transaction,
  25.113 +	so one <command role="hg-cmd">hg rollback</command> is all you
  25.114 +	need to undo this mistake.</para>
  25.115 +
  25.116 +    </sect2>
  25.117 +    <sect2 id="sec.undo.rollback-after-push">
  25.118 +      <title>Rolling back is useless once you've pushed</title>
  25.119 +
  25.120 +      <para>The value of the <command role="hg-cmd">hg
  25.121 +	  rollback</command> command drops to zero once you've pushed
  25.122 +	your changes to another repository.  Rolling back a change
  25.123 +	makes it disappear entirely, but <emphasis>only</emphasis> in
  25.124 +	the repository in which you perform the <command
  25.125 +	  role="hg-cmd">hg rollback</command>.  Because a rollback
  25.126 +	eliminates history, there's no way for the disappearance of a
  25.127 +	change to propagate between repositories.</para>
  25.128 +
  25.129 +      <para>If you've pushed a change to another
  25.130 +	repository&emdash;particularly if it's a shared
  25.131 +	repository&emdash;it has essentially <quote>escaped into the
  25.132 +	  wild,</quote> and you'll have to recover from your mistake
  25.133 +	in a different way.  What will happen if you push a changeset
  25.134 +	somewhere, then roll it back, then pull from the repository
  25.135 +	you pushed to, is that the changeset will reappear in your
  25.136 +	repository.</para>
  25.137 +
  25.138 +      <para>(If you absolutely know for sure that the change you want
  25.139 +	to roll back is the most recent change in the repository that
  25.140 +	you pushed to, <emphasis>and</emphasis> you know that nobody
  25.141 +	else could have pulled it from that repository, you can roll
  25.142 +	back the changeset there, too, but you really should really
  25.143 +	not rely on this working reliably.  If you do this, sooner or
  25.144 +	later a change really will make it into a repository that you
  25.145 +	don't directly control (or have forgotten about), and come
  25.146 +	back to bite you.)</para>
  25.147 +
  25.148 +    </sect2>
  25.149 +    <sect2>
  25.150 +      <title>You can only roll back once</title>
  25.151 +
  25.152 +      <para>Mercurial stores exactly one transaction in its
  25.153 +	transaction log; that transaction is the most recent one that
  25.154 +	occurred in the repository. This means that you can only roll
  25.155 +	back one transaction.  If you expect to be able to roll back
  25.156 +	one transaction, then its predecessor, this is not the
  25.157 +	behaviour you will get.</para>
  25.158 +
  25.159 +      &interaction.rollback.twice;
  25.160 +
  25.161 +      <para>Once you've rolled back one transaction in a repository,
  25.162 +	you can't roll back again in that repository until you perform
  25.163 +	another commit or pull.</para>
  25.164 +
  25.165 +    </sect2>
  25.166 +  </sect1>
  25.167 +  <sect1>
  25.168 +    <title>Reverting the mistaken change</title>
  25.169 +
  25.170 +    <para>If you make a modification to a file, and decide that you
  25.171 +      really didn't want to change the file at all, and you haven't
  25.172 +      yet committed your changes, the <command role="hg-cmd">hg
  25.173 +	revert</command> command is the one you'll need.  It looks at
  25.174 +      the changeset that's the parent of the working directory, and
  25.175 +      restores the contents of the file to their state as of that
  25.176 +      changeset. (That's a long-winded way of saying that, in the
  25.177 +      normal case, it undoes your modifications.)</para>
  25.178 +
  25.179 +    <para>Let's illustrate how the <command role="hg-cmd">hg
  25.180 +	revert</command> command works with yet another small example.
  25.181 +      We'll begin by modifying a file that Mercurial is already
  25.182 +      tracking.</para>
  25.183 +
  25.184 +    &interaction.daily.revert.modify;
  25.185 +
  25.186 +    <para>If we don't
  25.187 +      want that change, we can simply <command role="hg-cmd">hg
  25.188 +	revert</command> the file.</para>
  25.189 +
  25.190 +      &interaction.daily.revert.unmodify;
  25.191 +
  25.192 +    <para>The <command role="hg-cmd">hg revert</command> command
  25.193 +      provides us with an extra degree of safety by saving our
  25.194 +      modified file with a <filename>.orig</filename>
  25.195 +      extension.</para>
  25.196 +
  25.197 +    &interaction.daily.revert.status;
  25.198 +
  25.199 +    <para>Here is a summary of the cases that the <command
  25.200 +	role="hg-cmd">hg revert</command> command can deal with.  We
  25.201 +      will describe each of these in more detail in the section that
  25.202 +      follows.</para>
  25.203 +    <itemizedlist>
  25.204 +      <listitem><para>If you modify a file, it will restore the file
  25.205 +	  to its unmodified state.</para>
  25.206 +      </listitem>
  25.207 +      <listitem><para>If you <command role="hg-cmd">hg add</command> a
  25.208 +	  file, it will undo the <quote>added</quote> state of the
  25.209 +	  file, but leave the file itself untouched.</para>
  25.210 +      </listitem>
  25.211 +      <listitem><para>If you delete a file without telling Mercurial,
  25.212 +	  it will restore the file to its unmodified contents.</para>
  25.213 +      </listitem>
  25.214 +      <listitem><para>If you use the <command role="hg-cmd">hg
  25.215 +	    remove</command> command to remove a file, it will undo
  25.216 +	  the <quote>removed</quote> state of the file, and restore
  25.217 +	  the file to its unmodified contents.</para>
  25.218 +      </listitem></itemizedlist>
  25.219 +
  25.220 +    <sect2 id="sec.undo.mgmt">
  25.221 +      <title>File management errors</title>
  25.222 +
  25.223 +      <para>The <command role="hg-cmd">hg revert</command> command is
  25.224 +	useful for more than just modified files.  It lets you reverse
  25.225 +	the results of all of Mercurial's file management
  25.226 +	commands&emdash;<command role="hg-cmd">hg add</command>,
  25.227 +	<command role="hg-cmd">hg remove</command>, and so on.</para>
  25.228 +
  25.229 +      <para>If you <command role="hg-cmd">hg add</command> a file,
  25.230 +	then decide that in fact you don't want Mercurial to track it,
  25.231 +	use <command role="hg-cmd">hg revert</command> to undo the
  25.232 +	add.  Don't worry; Mercurial will not modify the file in any
  25.233 +	way.  It will just <quote>unmark</quote> the file.</para>
  25.234 +
  25.235 +      &interaction.daily.revert.add;
  25.236 +
  25.237 +      <para>Similarly, if you ask Mercurial to <command
  25.238 +	  role="hg-cmd">hg remove</command> a file, you can use
  25.239 +	<command role="hg-cmd">hg revert</command> to restore it to
  25.240 +	the contents it had as of the parent of the working directory.
  25.241 +	&interaction.daily.revert.remove; This works just as
  25.242 +	well for a file that you deleted by hand, without telling
  25.243 +	Mercurial (recall that in Mercurial terminology, this kind of
  25.244 +	file is called <quote>missing</quote>).</para>
  25.245 +
  25.246 +      &interaction.daily.revert.missing;
  25.247 +
  25.248 +      <para>If you revert a <command role="hg-cmd">hg copy</command>,
  25.249 +	the copied-to file remains in your working directory
  25.250 +	afterwards, untracked.  Since a copy doesn't affect the
  25.251 +	copied-from file in any way, Mercurial doesn't do anything
  25.252 +	with the copied-from file.</para>
  25.253 +
  25.254 +      &interaction.daily.revert.copy;
  25.255 +
  25.256 +      <sect3>
  25.257 +	<title>A slightly special case: reverting a rename</title>
  25.258 +
  25.259 +	<para>If you <command role="hg-cmd">hg rename</command> a
  25.260 +	  file, there is one small detail that you should remember.
  25.261 +	  When you <command role="hg-cmd">hg revert</command> a
  25.262 +	  rename, it's not enough to provide the name of the
  25.263 +	  renamed-to file, as you can see here.</para>
  25.264 +
  25.265 +	&interaction.daily.revert.rename;
  25.266 +
  25.267 +	<para>As you can see from the output of <command
  25.268 +	    role="hg-cmd">hg status</command>, the renamed-to file is
  25.269 +	  no longer identified as added, but the
  25.270 +	  renamed-<emphasis>from</emphasis> file is still removed!
  25.271 +	  This is counter-intuitive (at least to me), but at least
  25.272 +	  it's easy to deal with.</para>
  25.273 +
  25.274 +	&interaction.daily.revert.rename-orig;
  25.275 +
  25.276 +	<para>So remember, to revert a <command role="hg-cmd">hg
  25.277 +	    rename</command>, you must provide
  25.278 +	  <emphasis>both</emphasis> the source and destination
  25.279 +	  names.</para>
  25.280 +
  25.281 +	<para>% TODO: the output doesn't look like it will be
  25.282 +	  removed!</para>
  25.283 +
  25.284 +	<para>(By the way, if you rename a file, then modify the
  25.285 +	  renamed-to file, then revert both components of the rename,
  25.286 +	  when Mercurial restores the file that was removed as part of
  25.287 +	  the rename, it will be unmodified. If you need the
  25.288 +	  modifications in the renamed-to file to show up in the
  25.289 +	  renamed-from file, don't forget to copy them over.)</para>
  25.290 +
  25.291 +	<para>These fiddly aspects of reverting a rename arguably
  25.292 +	  constitute a small bug in Mercurial.</para>
  25.293 +
  25.294 +      </sect3>
  25.295 +    </sect2>
  25.296 +  </sect1>
  25.297 +  <sect1>
  25.298 +    <title>Dealing with committed changes</title>
  25.299 +
  25.300 +    <para>Consider a case where you have committed a change $a$, and
  25.301 +      another change $b$ on top of it; you then realise that change
  25.302 +      $a$ was incorrect.  Mercurial lets you <quote>back out</quote>
  25.303 +      an entire changeset automatically, and building blocks that let
  25.304 +      you reverse part of a changeset by hand.</para>
  25.305 +
  25.306 +    <para>Before you read this section, here's something to keep in
  25.307 +      mind: the <command role="hg-cmd">hg backout</command> command
  25.308 +      undoes changes by <emphasis>adding</emphasis> history, not by
  25.309 +      modifying or erasing it.  It's the right tool to use if you're
  25.310 +      fixing bugs, but not if you're trying to undo some change that
  25.311 +      has catastrophic consequences.  To deal with those, see section
  25.312 +      <xref linkend="sec.undo.aaaiiieee"/>.</para>
  25.313 +
  25.314 +    <sect2>
  25.315 +      <title>Backing out a changeset</title>
  25.316 +
  25.317 +      <para>The <command role="hg-cmd">hg backout</command> command
  25.318 +	lets you <quote>undo</quote> the effects of an entire
  25.319 +	changeset in an automated fashion.  Because Mercurial's
  25.320 +	history is immutable, this command <emphasis>does
  25.321 +	  not</emphasis> get rid of the changeset you want to undo.
  25.322 +	Instead, it creates a new changeset that
  25.323 +	<emphasis>reverses</emphasis> the effect of the to-be-undone
  25.324 +	changeset.</para>
  25.325 +
  25.326 +      <para>The operation of the <command role="hg-cmd">hg
  25.327 +	  backout</command> command is a little intricate, so let's
  25.328 +	illustrate it with some examples.  First, we'll create a
  25.329 +	repository with some simple changes.</para>
  25.330 +
  25.331 +      &interaction.backout.init;
  25.332 +
  25.333 +      <para>The <command role="hg-cmd">hg backout</command> command
  25.334 +	takes a single changeset ID as its argument; this is the
  25.335 +	changeset to back out.  Normally, <command role="hg-cmd">hg
  25.336 +	  backout</command> will drop you into a text editor to write
  25.337 +	a commit message, so you can record why you're backing the
  25.338 +	change out.  In this example, we provide a commit message on
  25.339 +	the command line using the <option
  25.340 +	  role="hg-opt-backout">-m</option> option.</para>
  25.341 +
  25.342 +    </sect2>
  25.343 +    <sect2>
  25.344 +      <title>Backing out the tip changeset</title>
  25.345 +
  25.346 +      <para>We're going to start by backing out the last changeset we
  25.347 +	committed.</para>
  25.348 +
  25.349 +      &interaction.backout.simple;
  25.350 +
  25.351 +      <para>You can see that the second line from
  25.352 +	<filename>myfile</filename> is no longer present.  Taking a
  25.353 +	look at the output of <command role="hg-cmd">hg log</command>
  25.354 +	gives us an idea of what the <command role="hg-cmd">hg
  25.355 +	  backout</command> command has done.
  25.356 +	&interaction.backout.simple.log; Notice that the new changeset
  25.357 +	that <command role="hg-cmd">hg backout</command> has created
  25.358 +	is a child of the changeset we backed out.  It's easier to see
  25.359 +	this in figure <xref
  25.360 +	  endterm="fig.undo.backout.caption" linkend="fig.undo.backout"/>,
  25.361 +	which presents a graphical
  25.362 +	view of the change history.  As you can see, the history is
  25.363 +	nice and linear.</para>
  25.364 +
  25.365 +      <informalfigure id="fig.undo.backout">
  25.366 +        <mediaobject>
  25.367 +          <imageobject><imagedata fileref="images/undo-simple.png"/>
  25.368 +          </imageobject>
  25.369 +          <textobject><phrase>XXX add text</phrase></textobject>
  25.370 +          <caption><para id="fig.undo.backout.caption">Backing out
  25.371 +            a change using the 
  25.372 +            <command role="hg-cmd">hg backout</command>
  25.373 +            command</para></caption>
  25.374 +      </mediaobject>
  25.375 +      </informalfigure>
  25.376 +
  25.377 +    </sect2>
  25.378 +    <sect2>
  25.379 +      <title>Backing out a non-tip change</title>
  25.380 +
  25.381 +      <para>If you want to back out a change other than the last one
  25.382 +	you committed, pass the <option
  25.383 +	  role="hg-opt-backout">--merge</option> option to the
  25.384 +	<command role="hg-cmd">hg backout</command> command.</para>
  25.385 +
  25.386 +      &interaction.backout.non-tip.clone;
  25.387 +
  25.388 +      <para>This makes backing out any changeset a
  25.389 +	<quote>one-shot</quote> operation that's usually simple and
  25.390 +	fast.</para>
  25.391 +
  25.392 +      &interaction.backout.non-tip.backout;
  25.393 +
  25.394 +      <para>If you take a look at the contents of
  25.395 +	<filename>myfile</filename> after the backout finishes, you'll
  25.396 +	see that the first and third changes are present, but not the
  25.397 +	second.</para>
  25.398 +
  25.399 +      &interaction.backout.non-tip.cat;
  25.400 +
  25.401 +      <para>As the graphical history in figure <xref
  25.402 +	  endterm="fig.undo.backout-non-tip.caption"
  25.403 +	  linkend="fig.undo.backout-non-tip"/> illustrates, Mercurial
  25.404 +	actually commits <emphasis>two</emphasis> changes in this kind
  25.405 +	of situation (the box-shaped nodes are the ones that Mercurial
  25.406 +	commits automatically).  Before Mercurial begins the backout
  25.407 +	process, it first remembers what the current parent of the
  25.408 +	working directory is.  It then backs out the target changeset,
  25.409 +	and commits that as a changeset.  Finally, it merges back to
  25.410 +	the previous parent of the working directory, and commits the
  25.411 +	result of the merge.</para>
  25.412 +
  25.413 +      <para>% TODO: to me it looks like mercurial doesn't commit the
  25.414 +	second merge automatically!</para>
  25.415 +
  25.416 +      <informalfigure id="fig.undo.backout-non-tip">
  25.417 +        <mediaobject>
  25.418 +          <imageobject><imagedata fileref="images/undo-non-tip.png"/>
  25.419 +          </imageobject>
  25.420 +          <textobject><phrase>XXX add text</phrase></textobject>
  25.421 +          <caption><para id="fig.undo.backout-non-tip.caption">Automated
  25.422 +            backout of a non-tip change using the
  25.423 +            <command role="hg-cmd">hg backout</command> command</para></caption>
  25.424 +        </mediaobject>
  25.425 +      </informalfigure>
  25.426 +
  25.427 +      <para>The result is that you end up <quote>back where you
  25.428 +	  were</quote>, only with some extra history that undoes the
  25.429 +	effect of the changeset you wanted to back out.</para>
  25.430 +
  25.431 +      <sect3>
  25.432 +	<title>Always use the <option
  25.433 +	    role="hg-opt-backout">--merge</option> option</title>
  25.434 +
  25.435 +	<para>In fact, since the <option
  25.436 +	    role="hg-opt-backout">--merge</option> option will do the
  25.437 +	  <quote>right thing</quote> whether or not the changeset
  25.438 +	  you're backing out is the tip (i.e. it won't try to merge if
  25.439 +	  it's backing out the tip, since there's no need), you should
  25.440 +	  <emphasis>always</emphasis> use this option when you run the
  25.441 +	  <command role="hg-cmd">hg backout</command> command.</para>
  25.442 +
  25.443 +      </sect3>
  25.444 +    </sect2>
  25.445 +    <sect2>
  25.446 +      <title>Gaining more control of the backout process</title>
  25.447 +
  25.448 +      <para>While I've recommended that you always use the <option
  25.449 +	  role="hg-opt-backout">--merge</option> option when backing
  25.450 +	out a change, the <command role="hg-cmd">hg backout</command>
  25.451 +	command lets you decide how to merge a backout changeset.
  25.452 +	Taking control of the backout process by hand is something you
  25.453 +	will rarely need to do, but it can be useful to understand
  25.454 +	what the <command role="hg-cmd">hg backout</command> command
  25.455 +	is doing for you automatically.  To illustrate this, let's
  25.456 +	clone our first repository, but omit the backout change that
  25.457 +	it contains.</para>
  25.458 +
  25.459 +      &interaction.backout.manual.clone;
  25.460 +
  25.461 +      <para>As with our
  25.462 +	earlier example, We'll commit a third changeset, then back out
  25.463 +	its parent, and see what happens.</para>
  25.464 +
  25.465 +      &interaction.backout.manual.backout;
  25.466 +
  25.467 +      <para>Our new changeset is again a descendant of the changeset
  25.468 +	we backout out; it's thus a new head, <emphasis>not</emphasis>
  25.469 +	a descendant of the changeset that was the tip.  The <command
  25.470 +	  role="hg-cmd">hg backout</command> command was quite
  25.471 +	explicit in telling us this.</para>
  25.472 +
  25.473 +      &interaction.backout.manual.log;
  25.474 +
  25.475 +      <para>Again, it's easier to see what has happened by looking at
  25.476 +	a graph of the revision history, in figure <xref
  25.477 +	  endterm="fig.undo.backout-manual.caption"
  25.478 +	  linkend="fig.undo.backout-manual"/>.  This makes it clear
  25.479 +	that when we use <command role="hg-cmd">hg backout</command>
  25.480 +	to back out a change other than the tip, Mercurial adds a new
  25.481 +	head to the repository (the change it committed is
  25.482 +	box-shaped).</para>
  25.483 +
  25.484 +      <informalfigure id="fig.undo.backout-manual">
  25.485 +        <mediaobject>
  25.486 +          <imageobject><imagedata fileref="images/undo-manual.png"/>
  25.487 +          </imageobject>
  25.488 +          <textobject><phrase>XXX add text</phrase></textobject>
  25.489 +          <caption><para id="fig.undo.backout-manual.caption">Backing out a
  25.490 +            change using the <command role="hg-cmd">hg backout</command>
  25.491 +            command</para></caption>
  25.492 +        </mediaobject>
  25.493 +      </informalfigure>
  25.494 +
  25.495 +      <para>After the <command role="hg-cmd">hg backout</command>
  25.496 +	command has completed, it leaves the new
  25.497 +	<quote>backout</quote> changeset as the parent of the working
  25.498 +	directory.</para>
  25.499 +
  25.500 +      &interaction.backout.manual.parents;
  25.501 +
  25.502 +      <para>Now we have two isolated sets of changes.</para>
  25.503 +
  25.504 +      &interaction.backout.manual.heads;
  25.505 +
  25.506 +      <para>Let's think about what we expect to see as the contents of
  25.507 +	<filename>myfile</filename> now.  The first change should be
  25.508 +	present, because we've never backed it out.  The second change
  25.509 +	should be missing, as that's the change we backed out.  Since
  25.510 +	the history graph shows the third change as a separate head,
  25.511 +	we <emphasis>don't</emphasis> expect to see the third change
  25.512 +	present in <filename>myfile</filename>.</para>
  25.513 +
  25.514 +      &interaction.backout.manual.cat;
  25.515 +
  25.516 +      <para>To get the third change back into the file, we just do a
  25.517 +	normal merge of our two heads.</para>
  25.518 +
  25.519 +      &interaction.backout.manual.merge;
  25.520 +
  25.521 +      <para>Afterwards, the graphical history of our repository looks
  25.522 +	like figure
  25.523 +	<xref endterm="fig.undo.backout-manual-merge.caption"
  25.524 +	  linkend="fig.undo.backout-manual-merge"/>.</para>
  25.525 +
  25.526 +      <informalfigure id="fig.undo.backout-manual-merge">
  25.527 +        <mediaobject>
  25.528 +          <imageobject><imagedata fileref="images/undo-manual-merge.png"/>
  25.529 +          </imageobject>
  25.530 +          <textobject><phrase>XXX add text</phrase></textobject>
  25.531 +          <caption><para id="fig.undo.backout-manual-merge.caption">Manually
  25.532 +            merging a backout change</para></caption>
  25.533 +        </mediaobject>
  25.534 +      </informalfigure>
  25.535 +
  25.536 +    </sect2>
  25.537 +    <sect2>
  25.538 +      <title>Why <command role="hg-cmd">hg backout</command> works as
  25.539 +	it does</title>
  25.540 +
  25.541 +      <para>Here's a brief description of how the <command
  25.542 +	  role="hg-cmd">hg backout</command> command works.</para>
  25.543 +      <orderedlist>
  25.544 +	<listitem><para>It ensures that the working directory is
  25.545 +	    <quote>clean</quote>, i.e. that the output of <command
  25.546 +	      role="hg-cmd">hg status</command> would be empty.</para>
  25.547 +	</listitem>
  25.548 +	<listitem><para>It remembers the current parent of the working
  25.549 +	    directory.  Let's call this changeset
  25.550 +	    <literal>orig</literal></para>
  25.551 +	</listitem>
  25.552 +	<listitem><para>It does the equivalent of a <command
  25.553 +	      role="hg-cmd">hg update</command> to sync the working
  25.554 +	    directory to the changeset you want to back out.  Let's
  25.555 +	    call this changeset <literal>backout</literal></para>
  25.556 +	</listitem>
  25.557 +	<listitem><para>It finds the parent of that changeset.  Let's
  25.558 +	    call that changeset <literal>parent</literal>.</para>
  25.559 +	</listitem>
  25.560 +	<listitem><para>For each file that the
  25.561 +	    <literal>backout</literal> changeset affected, it does the
  25.562 +	    equivalent of a <command role="hg-cmd">hg revert -r
  25.563 +	      parent</command> on that file, to restore it to the
  25.564 +	    contents it had before that changeset was
  25.565 +	    committed.</para>
  25.566 +	</listitem>
  25.567 +	<listitem><para>It commits the result as a new changeset.
  25.568 +	    This changeset has <literal>backout</literal> as its
  25.569 +	    parent.</para>
  25.570 +	</listitem>
  25.571 +	<listitem><para>If you specify <option
  25.572 +	      role="hg-opt-backout">--merge</option> on the command
  25.573 +	    line, it merges with <literal>orig</literal>, and commits
  25.574 +	    the result of the merge.</para>
  25.575 +	</listitem></orderedlist>
  25.576 +
  25.577 +      <para>An alternative way to implement the <command
  25.578 +	  role="hg-cmd">hg backout</command> command would be to
  25.579 +	<command role="hg-cmd">hg export</command> the
  25.580 +	to-be-backed-out changeset as a diff, then use the <option
  25.581 +	  role="cmd-opt-patch">--reverse</option> option to the
  25.582 +	<command>patch</command> command to reverse the effect of the
  25.583 +	change without fiddling with the working directory.  This
  25.584 +	sounds much simpler, but it would not work nearly as
  25.585 +	well.</para>
  25.586 +
  25.587 +      <para>The reason that <command role="hg-cmd">hg
  25.588 +	  backout</command> does an update, a commit, a merge, and
  25.589 +	another commit is to give the merge machinery the best chance
  25.590 +	to do a good job when dealing with all the changes
  25.591 +	<emphasis>between</emphasis> the change you're backing out and
  25.592 +	the current tip.</para>
  25.593 +
  25.594 +      <para>If you're backing out a changeset that's 100 revisions
  25.595 +	back in your project's history, the chances that the
  25.596 +	<command>patch</command> command will be able to apply a
  25.597 +	reverse diff cleanly are not good, because intervening changes
  25.598 +	are likely to have <quote>broken the context</quote> that
  25.599 +	<command>patch</command> uses to determine whether it can
  25.600 +	apply a patch (if this sounds like gibberish, see <xref
  25.601 +	  linkend="sec.mq.patch"/> for a
  25.602 +	discussion of the <command>patch</command> command).  Also,
  25.603 +	Mercurial's merge machinery will handle files and directories
  25.604 +	being renamed, permission changes, and modifications to binary
  25.605 +	files, none of which <command>patch</command> can deal
  25.606 +	with.</para>
  25.607 +
  25.608 +    </sect2>
  25.609 +  </sect1>
  25.610 +  <sect1 id="sec.undo.aaaiiieee">
  25.611 +    <title>Changes that should never have been</title>
  25.612 +
  25.613 +    <para>Most of the time, the <command role="hg-cmd">hg
  25.614 +	backout</command> command is exactly what you need if you want
  25.615 +      to undo the effects of a change.  It leaves a permanent record
  25.616 +      of exactly what you did, both when committing the original
  25.617 +      changeset and when you cleaned up after it.</para>
  25.618 +
  25.619 +    <para>On rare occasions, though, you may find that you've
  25.620 +      committed a change that really should not be present in the
  25.621 +      repository at all.  For example, it would be very unusual, and
  25.622 +      usually considered a mistake, to commit a software project's
  25.623 +      object files as well as its source files.  Object files have
  25.624 +      almost no intrinsic value, and they're <emphasis>big</emphasis>,
  25.625 +      so they increase the size of the repository and the amount of
  25.626 +      time it takes to clone or pull changes.</para>
  25.627 +
  25.628 +    <para>Before I discuss the options that you have if you commit a
  25.629 +      <quote>brown paper bag</quote> change (the kind that's so bad
  25.630 +      that you want to pull a brown paper bag over your head), let me
  25.631 +      first discuss some approaches that probably won't work.</para>
  25.632 +
  25.633 +    <para>Since Mercurial treats history as accumulative&emdash;every
  25.634 +      change builds on top of all changes that preceded it&emdash;you
  25.635 +      generally can't just make disastrous changes disappear.  The one
  25.636 +      exception is when you've just committed a change, and it hasn't
  25.637 +      been pushed or pulled into another repository.  That's when you
  25.638 +      can safely use the <command role="hg-cmd">hg rollback</command>
  25.639 +      command, as I detailed in section <xref
  25.640 +	linkend="sec.undo.rollback"/>.</para>
  25.641 +
  25.642 +    <para>After you've pushed a bad change to another repository, you
  25.643 +      <emphasis>could</emphasis> still use <command role="hg-cmd">hg
  25.644 +	rollback</command> to make your local copy of the change
  25.645 +      disappear, but it won't have the consequences you want.  The
  25.646 +      change will still be present in the remote repository, so it
  25.647 +      will reappear in your local repository the next time you
  25.648 +      pull.</para>
  25.649 +
  25.650 +    <para>If a situation like this arises, and you know which
  25.651 +      repositories your bad change has propagated into, you can
  25.652 +      <emphasis>try</emphasis> to get rid of the changeefrom
  25.653 +      <emphasis>every</emphasis> one of those repositories.  This is,
  25.654 +      of course, not a satisfactory solution: if you miss even a
  25.655 +      single repository while you're expunging, the change is still
  25.656 +      <quote>in the wild</quote>, and could propagate further.</para>
  25.657 +
  25.658 +    <para>If you've committed one or more changes
  25.659 +      <emphasis>after</emphasis> the change that you'd like to see
  25.660 +      disappear, your options are further reduced. Mercurial doesn't
  25.661 +      provide a way to <quote>punch a hole</quote> in history, leaving
  25.662 +      changesets intact.</para>
  25.663 +
  25.664 +    <para>XXX This needs filling out.  The
  25.665 +      <literal>hg-replay</literal> script in the
  25.666 +      <literal>examples</literal> directory works, but doesn't handle
  25.667 +      merge changesets.  Kind of an important omission.</para>
  25.668 +
  25.669 +    <sect2>
  25.670 +      <title>Protect yourself from <quote>escaped</quote>
  25.671 +	changes</title>
  25.672 +
  25.673 +      <para>If you've committed some changes to your local repository
  25.674 +	and they've been pushed or pulled somewhere else, this isn't
  25.675 +	necessarily a disaster.  You can protect yourself ahead of
  25.676 +	time against some classes of bad changeset.  This is
  25.677 +	particularly easy if your team usually pulls changes from a
  25.678 +	central repository.</para>
  25.679 +
  25.680 +      <para>By configuring some hooks on that repository to validate
  25.681 +	incoming changesets (see chapter <xref linkend="chap.hook"/>),
  25.682 +	you can
  25.683 +	automatically prevent some kinds of bad changeset from being
  25.684 +	pushed to the central repository at all.  With such a
  25.685 +	configuration in place, some kinds of bad changeset will
  25.686 +	naturally tend to <quote>die out</quote> because they can't
  25.687 +	propagate into the central repository.  Better yet, this
  25.688 +	happens without any need for explicit intervention.</para>
  25.689 +
  25.690 +      <para>For instance, an incoming change hook that verifies that a
  25.691 +	changeset will actually compile can prevent people from
  25.692 +	inadvertantly <quote>breaking the build</quote>.</para>
  25.693 +
  25.694 +    </sect2>
  25.695 +  </sect1>
  25.696 +  <sect1 id="sec.undo.bisect">
  25.697 +    <title>Finding the source of a bug</title>
  25.698 +
  25.699 +    <para>While it's all very well to be able to back out a changeset
  25.700 +      that introduced a bug, this requires that you know which
  25.701 +      changeset to back out.  Mercurial provides an invaluable
  25.702 +      command, called <command role="hg-cmd">hg bisect</command>, that
  25.703 +      helps you to automate this process and accomplish it very
  25.704 +      efficiently.</para>
  25.705 +
  25.706 +    <para>The idea behind the <command role="hg-cmd">hg
  25.707 +	bisect</command> command is that a changeset has introduced
  25.708 +      some change of behaviour that you can identify with a simple
  25.709 +      binary test.  You don't know which piece of code introduced the
  25.710 +      change, but you know how to test for the presence of the bug.
  25.711 +      The <command role="hg-cmd">hg bisect</command> command uses your
  25.712 +      test to direct its search for the changeset that introduced the
  25.713 +      code that caused the bug.</para>
  25.714 +
  25.715 +    <para>Here are a few scenarios to help you understand how you
  25.716 +      might apply this command.</para>
  25.717 +    <itemizedlist>
  25.718 +      <listitem><para>The most recent version of your software has a
  25.719 +	  bug that you remember wasn't present a few weeks ago, but
  25.720 +	  you don't know when it was introduced.  Here, your binary
  25.721 +	  test checks for the presence of that bug.</para>
  25.722 +      </listitem>
  25.723 +      <listitem><para>You fixed a bug in a rush, and now it's time to
  25.724 +	  close the entry in your team's bug database.  The bug
  25.725 +	  database requires a changeset ID when you close an entry,
  25.726 +	  but you don't remember which changeset you fixed the bug in.
  25.727 +	  Once again, your binary test checks for the presence of the
  25.728 +	  bug.</para>
  25.729 +      </listitem>
  25.730 +      <listitem><para>Your software works correctly, but runs 15%
  25.731 +	  slower than the last time you measured it.  You want to know
  25.732 +	  which changeset introduced the performance regression.  In
  25.733 +	  this case, your binary test measures the performance of your
  25.734 +	  software, to see whether it's <quote>fast</quote> or
  25.735 +	  <quote>slow</quote>.</para>
  25.736 +      </listitem>
  25.737 +      <listitem><para>The sizes of the components of your project that
  25.738 +	  you ship exploded recently, and you suspect that something
  25.739 +	  changed in the way you build your project.</para>
  25.740 +      </listitem></itemizedlist>
  25.741 +
  25.742 +    <para>From these examples, it should be clear that the <command
  25.743 +	role="hg-cmd">hg bisect</command> command is not useful only
  25.744 +      for finding the sources of bugs.  You can use it to find any
  25.745 +      <quote>emergent property</quote> of a repository (anything that
  25.746 +      you can't find from a simple text search of the files in the
  25.747 +      tree) for which you can write a binary test.</para>
  25.748 +
  25.749 +    <para>We'll introduce a little bit of terminology here, just to
  25.750 +      make it clear which parts of the search process are your
  25.751 +      responsibility, and which are Mercurial's.  A
  25.752 +      <emphasis>test</emphasis> is something that
  25.753 +      <emphasis>you</emphasis> run when <command role="hg-cmd">hg
  25.754 +	bisect</command> chooses a changeset.  A
  25.755 +      <emphasis>probe</emphasis> is what <command role="hg-cmd">hg
  25.756 +	bisect</command> runs to tell whether a revision is good.
  25.757 +      Finally, we'll use the word <quote>bisect</quote>, as both a
  25.758 +      noun and a verb, to stand in for the phrase <quote>search using
  25.759 +	the <command role="hg-cmd">hg bisect</command>
  25.760 +	command</quote>.</para>
  25.761 +
  25.762 +    <para>One simple way to automate the searching process would be
  25.763 +      simply to probe every changeset.  However, this scales poorly.
  25.764 +      If it took ten minutes to test a single changeset, and you had
  25.765 +      10,000 changesets in your repository, the exhaustive approach
  25.766 +      would take on average 35 <emphasis>days</emphasis> to find the
  25.767 +      changeset that introduced a bug.  Even if you knew that the bug
  25.768 +      was introduced by one of the last 500 changesets, and limited
  25.769 +      your search to those, you'd still be looking at over 40 hours to
  25.770 +      find the changeset that introduced your bug.</para>
  25.771 +
  25.772 +    <para>What the <command role="hg-cmd">hg bisect</command> command
  25.773 +      does is use its knowledge of the <quote>shape</quote> of your
  25.774 +      project's revision history to perform a search in time
  25.775 +      proportional to the <emphasis>logarithm</emphasis> of the number
  25.776 +      of changesets to check (the kind of search it performs is called
  25.777 +      a dichotomic search).  With this approach, searching through
  25.778 +      10,000 changesets will take less than three hours, even at ten
  25.779 +      minutes per test (the search will require about 14 tests).
  25.780 +      Limit your search to the last hundred changesets, and it will
  25.781 +      take only about an hour (roughly seven tests).</para>
  25.782 +
  25.783 +    <para>The <command role="hg-cmd">hg bisect</command> command is
  25.784 +      aware of the <quote>branchy</quote> nature of a Mercurial
  25.785 +      project's revision history, so it has no problems dealing with
  25.786 +      branches, merges, or multiple heads in a repository.  It can
  25.787 +      prune entire branches of history with a single probe, which is
  25.788 +      how it operates so efficiently.</para>
  25.789 +
  25.790 +    <sect2>
  25.791 +      <title>Using the <command role="hg-cmd">hg bisect</command>
  25.792 +	command</title>
  25.793 +
  25.794 +      <para>Here's an example of <command role="hg-cmd">hg
  25.795 +	  bisect</command> in action.</para>
  25.796 +
  25.797 +      <note>
  25.798 +	<para>  In versions 0.9.5 and earlier of Mercurial, <command
  25.799 +	    role="hg-cmd">hg bisect</command> was not a core command:
  25.800 +	  it was distributed with Mercurial as an extension. This
  25.801 +	  section describes the built-in command, not the old
  25.802 +	  extension.</para>
  25.803 +      </note>
  25.804 +
  25.805 +      <para>Now let's create a repository, so that we can try out the
  25.806 +	<command role="hg-cmd">hg bisect</command> command in
  25.807 +	isolation.</para>
  25.808 +
  25.809 +      &interaction.bisect.init;
  25.810 +
  25.811 +      <para>We'll simulate a project that has a bug in it in a
  25.812 +	simple-minded way: create trivial changes in a loop, and
  25.813 +	nominate one specific change that will have the
  25.814 +	<quote>bug</quote>.  This loop creates 35 changesets, each
  25.815 +	adding a single file to the repository. We'll represent our
  25.816 +	<quote>bug</quote> with a file that contains the text <quote>i
  25.817 +	  have a gub</quote>.</para>
  25.818 +
  25.819 +      &interaction.bisect.commits;
  25.820 +
  25.821 +      <para>The next thing that we'd like to do is figure out how to
  25.822 +	use the <command role="hg-cmd">hg bisect</command> command.
  25.823 +	We can use Mercurial's normal built-in help mechanism for
  25.824 +	this.</para>
  25.825 +
  25.826 +      &interaction.bisect.help;
  25.827 +
  25.828 +      <para>The <command role="hg-cmd">hg bisect</command> command
  25.829 +	works in steps.  Each step proceeds as follows.</para>
  25.830 +      <orderedlist>
  25.831 +	<listitem><para>You run your binary test.</para>
  25.832 +	  <itemizedlist>
  25.833 +	    <listitem><para>If the test succeeded, you tell <command
  25.834 +		  role="hg-cmd">hg bisect</command> by running the
  25.835 +		<command role="hg-cmd">hg bisect good</command>
  25.836 +		command.</para>
  25.837 +	    </listitem>
  25.838 +	    <listitem><para>If it failed, run the <command
  25.839 +		  role="hg-cmd">hg bisect bad</command>
  25.840 +		command.</para></listitem></itemizedlist>
  25.841 +	</listitem>
  25.842 +	<listitem><para>The command uses your information to decide
  25.843 +	    which changeset to test next.</para>
  25.844 +	</listitem>
  25.845 +	<listitem><para>It updates the working directory to that
  25.846 +	    changeset, and the process begins again.</para>
  25.847 +	</listitem></orderedlist>
  25.848 +      <para>The process ends when <command role="hg-cmd">hg
  25.849 +	  bisect</command> identifies a unique changeset that marks
  25.850 +	the point where your test transitioned from
  25.851 +	<quote>succeeding</quote> to <quote>failing</quote>.</para>
  25.852 +
  25.853 +      <para>To start the search, we must run the <command
  25.854 +	  role="hg-cmd">hg bisect --reset</command> command.</para>
  25.855 +
  25.856 +      &interaction.bisect.search.init;
  25.857 +
  25.858 +      <para>In our case, the binary test we use is simple: we check to
  25.859 +	see if any file in the repository contains the string <quote>i
  25.860 +	  have a gub</quote>.  If it does, this changeset contains the
  25.861 +	change that <quote>caused the bug</quote>.  By convention, a
  25.862 +	changeset that has the property we're searching for is
  25.863 +	<quote>bad</quote>, while one that doesn't is
  25.864 +	<quote>good</quote>.</para>
  25.865 +
  25.866 +      <para>Most of the time, the revision to which the working
  25.867 +	directory is synced (usually the tip) already exhibits the
  25.868 +	problem introduced by the buggy change, so we'll mark it as
  25.869 +	<quote>bad</quote>.</para>
  25.870 +
  25.871 +      &interaction.bisect.search.bad-init;
  25.872 +
  25.873 +      <para>Our next task is to nominate a changeset that we know
  25.874 +	<emphasis>doesn't</emphasis> have the bug; the <command
  25.875 +	  role="hg-cmd">hg bisect</command> command will
  25.876 +	<quote>bracket</quote> its search between the first pair of
  25.877 +	good and bad changesets.  In our case, we know that revision
  25.878 +	10 didn't have the bug.  (I'll have more words about choosing
  25.879 +	the first <quote>good</quote> changeset later.)</para>
  25.880 +
  25.881 +      &interaction.bisect.search.good-init;
  25.882 +
  25.883 +      <para>Notice that this command printed some output.</para>
  25.884 +      <itemizedlist>
  25.885 +	<listitem><para>It told us how many changesets it must
  25.886 +	    consider before it can identify the one that introduced
  25.887 +	    the bug, and how many tests that will require.</para>
  25.888 +	</listitem>
  25.889 +	<listitem><para>It updated the working directory to the next
  25.890 +	    changeset to test, and told us which changeset it's
  25.891 +	    testing.</para>
  25.892 +	</listitem></itemizedlist>
  25.893 +
  25.894 +      <para>We now run our test in the working directory.  We use the
  25.895 +	<command>grep</command> command to see if our
  25.896 +	<quote>bad</quote> file is present in the working directory.
  25.897 +	If it is, this revision is bad; if not, this revision is good.
  25.898 +	&interaction.bisect.search.step1;</para>
  25.899 +
  25.900 +      <para>This test looks like a perfect candidate for automation,
  25.901 +	so let's turn it into a shell function.</para>
  25.902 +      &interaction.bisect.search.mytest;
  25.903 +
  25.904 +      <para>We can now run an entire test step with a single command,
  25.905 +	<literal>mytest</literal>.</para>
  25.906 +
  25.907 +      &interaction.bisect.search.step2;
  25.908 +
  25.909 +      <para>A few more invocations of our canned test step command,
  25.910 +	and we're done.</para>
  25.911 +
  25.912 +      &interaction.bisect.search.rest;
  25.913 +
  25.914 +      <para>Even though we had 40 changesets to search through, the
  25.915 +	<command role="hg-cmd">hg bisect</command> command let us find
  25.916 +	the changeset that introduced our <quote>bug</quote> with only
  25.917 +	five tests.  Because the number of tests that the <command
  25.918 +	  role="hg-cmd">hg bisect</command> command performs grows
  25.919 +	logarithmically with the number of changesets to search, the
  25.920 +	advantage that it has over the <quote>brute force</quote>
  25.921 +	search approach increases with every changeset you add.</para>
  25.922 +
  25.923 +    </sect2>
  25.924 +    <sect2>
  25.925 +      <title>Cleaning up after your search</title>
  25.926 +
  25.927 +      <para>When you're finished using the <command role="hg-cmd">hg
  25.928 +	  bisect</command> command in a repository, you can use the
  25.929 +	<command role="hg-cmd">hg bisect reset</command> command to
  25.930 +	drop the information it was using to drive your search.  The
  25.931 +	command doesn't use much space, so it doesn't matter if you
  25.932 +	forget to run this command.  However, <command
  25.933 +	  role="hg-cmd">hg bisect</command> won't let you start a new
  25.934 +	search in that repository until you do a <command
  25.935 +	  role="hg-cmd">hg bisect reset</command>.</para>
  25.936 +
  25.937 +      &interaction.bisect.search.reset;
  25.938 +
  25.939 +    </sect2>
  25.940 +  </sect1>
  25.941 +  <sect1>
  25.942 +    <title>Tips for finding bugs effectively</title>
  25.943 +
  25.944 +    <sect2>
  25.945 +      <title>Give consistent input</title>
  25.946 +
  25.947 +      <para>The <command role="hg-cmd">hg bisect</command> command
  25.948 +	requires that you correctly report the result of every test
  25.949 +	you perform.  If you tell it that a test failed when it really
  25.950 +	succeeded, it <emphasis>might</emphasis> be able to detect the
  25.951 +	inconsistency.  If it can identify an inconsistency in your
  25.952 +	reports, it will tell you that a particular changeset is both
  25.953 +	good and bad. However, it can't do this perfectly; it's about
  25.954 +	as likely to report the wrong changeset as the source of the
  25.955 +	bug.</para>
  25.956 +
  25.957 +    </sect2>
  25.958 +    <sect2>
  25.959 +      <title>Automate as much as possible</title>
  25.960 +
  25.961 +      <para>When I started using the <command role="hg-cmd">hg
  25.962 +	  bisect</command> command, I tried a few times to run my
  25.963 +	tests by hand, on the command line.  This is an approach that
  25.964 +	I, at least, am not suited to.  After a few tries, I found
  25.965 +	that I was making enough mistakes that I was having to restart
  25.966 +	my searches several times before finally getting correct
  25.967 +	results.</para>
  25.968 +
  25.969 +      <para>My initial problems with driving the <command
  25.970 +	  role="hg-cmd">hg bisect</command> command by hand occurred
  25.971 +	even with simple searches on small repositories; if the
  25.972 +	problem you're looking for is more subtle, or the number of
  25.973 +	tests that <command role="hg-cmd">hg bisect</command> must
  25.974 +	perform increases, the likelihood of operator error ruining
  25.975 +	the search is much higher.  Once I started automating my
  25.976 +	tests, I had much better results.</para>
  25.977 +
  25.978 +      <para>The key to automated testing is twofold:</para>
  25.979 +      <itemizedlist>
  25.980 +	<listitem><para>always test for the same symptom, and</para>
  25.981 +	</listitem>
  25.982 +	<listitem><para>always feed consistent input to the <command
  25.983 +	      role="hg-cmd">hg bisect</command> command.</para>
  25.984 +	</listitem></itemizedlist>
  25.985 +      <para>In my tutorial example above, the <command>grep</command>
  25.986 +	command tests for the symptom, and the <literal>if</literal>
  25.987 +	statement takes the result of this check and ensures that we
  25.988 +	always feed the same input to the <command role="hg-cmd">hg
  25.989 +	  bisect</command> command.  The <literal>mytest</literal>
  25.990 +	function marries these together in a reproducible way, so that
  25.991 +	every test is uniform and consistent.</para>
  25.992 +
  25.993 +    </sect2>
  25.994 +    <sect2>
  25.995 +      <title>Check your results</title>
  25.996 +
  25.997 +      <para>Because the output of a <command role="hg-cmd">hg
  25.998 +	  bisect</command> search is only as good as the input you
  25.999 +	give it, don't take the changeset it reports as the absolute
 25.1000 +	truth.  A simple way to cross-check its report is to manually
 25.1001 +	run your test at each of the following changesets:</para>
 25.1002 +      <itemizedlist>
 25.1003 +	<listitem><para>The changeset that it reports as the first bad
 25.1004 +	    revision.  Your test should still report this as
 25.1005 +	    bad.</para>
 25.1006 +	</listitem>
 25.1007 +	<listitem><para>The parent of that changeset (either parent,
 25.1008 +	    if it's a merge). Your test should report this changeset
 25.1009 +	    as good.</para>
 25.1010 +	</listitem>
 25.1011 +	<listitem><para>A child of that changeset.  Your test should
 25.1012 +	    report this changeset as bad.</para>
 25.1013 +	</listitem></itemizedlist>
 25.1014 +
 25.1015 +    </sect2>
 25.1016 +    <sect2>
 25.1017 +      <title>Beware interference between bugs</title>
 25.1018 +
 25.1019 +      <para>It's possible that your search for one bug could be
 25.1020 +	disrupted by the presence of another.  For example, let's say
 25.1021 +	your software crashes at revision 100, and worked correctly at
 25.1022 +	revision 50.  Unknown to you, someone else introduced a
 25.1023 +	different crashing bug at revision 60, and fixed it at
 25.1024 +	revision 80.  This could distort your results in one of
 25.1025 +	several ways.</para>
 25.1026 +
 25.1027 +      <para>It is possible that this other bug completely
 25.1028 +	<quote>masks</quote> yours, which is to say that it occurs
 25.1029 +	before your bug has a chance to manifest itself.  If you can't
 25.1030 +	avoid that other bug (for example, it prevents your project
 25.1031 +	from building), and so can't tell whether your bug is present
 25.1032 +	in a particular changeset, the <command role="hg-cmd">hg
 25.1033 +	  bisect</command> command cannot help you directly.  Instead,
 25.1034 +	you can mark a changeset as untested by running <command
 25.1035 +	  role="hg-cmd">hg bisect --skip</command>.</para>
 25.1036 +
 25.1037 +      <para>A different problem could arise if your test for a bug's
 25.1038 +	presence is not specific enough.  If you check for <quote>my
 25.1039 +	  program crashes</quote>, then both your crashing bug and an
 25.1040 +	unrelated crashing bug that masks it will look like the same
 25.1041 +	thing, and mislead <command role="hg-cmd">hg
 25.1042 +	  bisect</command>.</para>
 25.1043 +
 25.1044 +      <para>Another useful situation in which to use <command
 25.1045 +	  role="hg-cmd">hg bisect --skip</command> is if you can't
 25.1046 +	test a revision because your project was in a broken and hence
 25.1047 +	untestable state at that revision, perhaps because someone
 25.1048 +	checked in a change that prevented the project from
 25.1049 +	building.</para>
 25.1050 +
 25.1051 +    </sect2>
 25.1052 +    <sect2>
 25.1053 +      <title>Bracket your search lazily</title>
 25.1054 +
 25.1055 +      <para>Choosing the first <quote>good</quote> and
 25.1056 +	<quote>bad</quote> changesets that will mark the end points of
 25.1057 +	your search is often easy, but it bears a little discussion
 25.1058 +	nevertheless.  From the perspective of <command
 25.1059 +	  role="hg-cmd">hg bisect</command>, the <quote>newest</quote>
 25.1060 +	changeset is conventionally <quote>bad</quote>, and the older
 25.1061 +	changeset is <quote>good</quote>.</para>
 25.1062 +
 25.1063 +      <para>If you're having trouble remembering when a suitable
 25.1064 +	<quote>good</quote> change was, so that you can tell <command
 25.1065 +	  role="hg-cmd">hg bisect</command>, you could do worse than
 25.1066 +	testing changesets at random.  Just remember to eliminate
 25.1067 +	contenders that can't possibly exhibit the bug (perhaps
 25.1068 +	because the feature with the bug isn't present yet) and those
 25.1069 +	where another problem masks the bug (as I discussed
 25.1070 +	above).</para>
 25.1071 +
 25.1072 +      <para>Even if you end up <quote>early</quote> by thousands of
 25.1073 +	changesets or months of history, you will only add a handful
 25.1074 +	of tests to the total number that <command role="hg-cmd">hg
 25.1075 +	  bisect</command> must perform, thanks to its logarithmic
 25.1076 +	behaviour.</para>
 25.1077 +
 25.1078 +    </sect2>
 25.1079 +  </sect1>
 25.1080 +</chapter>
 25.1081 +
 25.1082 +<!--
 25.1083 +local variables: 
 25.1084 +sgml-parent-document: ("00book.xml" "book" "chapter")
 25.1085 +end:
 25.1086 +-->
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/en/ch09-hook.xml	Fri Mar 20 16:43:35 2009 +0800
    26.3 @@ -0,0 +1,2037 @@
    26.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    26.5 +
    26.6 +<chapter id="chap.hook">
    26.7 +  <?dbhtml filename="handling-repository-events-with-hooks.html"?>
    26.8 +  <title>Handling repository events with hooks</title>
    26.9 +
   26.10 +  <para>Mercurial offers a powerful mechanism to let you perform
   26.11 +    automated actions in response to events that occur in a
   26.12 +    repository.  In some cases, you can even control Mercurial's
   26.13 +    response to those events.</para>
   26.14 +
   26.15 +  <para>The name Mercurial uses for one of these actions is a
   26.16 +    <emphasis>hook</emphasis>. Hooks are called
   26.17 +    <quote>triggers</quote> in some revision control systems, but the
   26.18 +    two names refer to the same idea.</para>
   26.19 +
   26.20 +  <sect1>
   26.21 +    <title>An overview of hooks in Mercurial</title>
   26.22 +
   26.23 +    <para>Here is a brief list of the hooks that Mercurial supports.
   26.24 +      We will revisit each of these hooks in more detail later, in
   26.25 +      section <xref linkend="sec.hook.ref"/>.</para>
   26.26 +
   26.27 +    <itemizedlist>
   26.28 +      <listitem><para><literal role="hook">changegroup</literal>: This
   26.29 +	  is run after a group of changesets has been brought into the
   26.30 +	  repository from elsewhere.</para>
   26.31 +      </listitem>
   26.32 +      <listitem><para><literal role="hook">commit</literal>: This is
   26.33 +	  run after a new changeset has been created in the local
   26.34 +	  repository.</para>
   26.35 +      </listitem>
   26.36 +      <listitem><para><literal role="hook">incoming</literal>: This is
   26.37 +	  run once for each new changeset that is brought into the
   26.38 +	  repository from elsewhere.  Notice the difference from
   26.39 +	  <literal role="hook">changegroup</literal>, which is run
   26.40 +	  once per <emphasis>group</emphasis> of changesets brought
   26.41 +	  in.</para>
   26.42 +      </listitem>
   26.43 +      <listitem><para><literal role="hook">outgoing</literal>: This is
   26.44 +	  run after a group of changesets has been transmitted from
   26.45 +	  this repository.</para>
   26.46 +      </listitem>
   26.47 +      <listitem><para><literal role="hook">prechangegroup</literal>:
   26.48 +	  This is run before starting to bring a group of changesets
   26.49 +	  into the repository.
   26.50 +	</para>
   26.51 +      </listitem>
   26.52 +      <listitem><para><literal role="hook">precommit</literal>:
   26.53 +	  Controlling. This is run before starting a commit.
   26.54 +	</para>
   26.55 +      </listitem>
   26.56 +      <listitem><para><literal role="hook">preoutgoing</literal>:
   26.57 +	  Controlling. This is run before starting to transmit a group
   26.58 +	  of changesets from this repository.
   26.59 +	</para>
   26.60 +      </listitem>
   26.61 +      <listitem><para><literal role="hook">pretag</literal>:
   26.62 +	  Controlling. This is run before creating a tag.
   26.63 +	</para>
   26.64 +      </listitem>
   26.65 +      <listitem><para><literal
   26.66 +	    role="hook">pretxnchangegroup</literal>: Controlling. This
   26.67 +	  is run after a group of changesets has been brought into the
   26.68 +	  local repository from another, but before the transaction
   26.69 +	  completes that will make the changes permanent in the
   26.70 +	  repository.
   26.71 +	</para>
   26.72 +      </listitem>
   26.73 +      <listitem><para><literal role="hook">pretxncommit</literal>:
   26.74 +	  Controlling. This is run after a new changeset has been
   26.75 +	  created in the local repository, but before the transaction
   26.76 +	  completes that will make it permanent.
   26.77 +	</para>
   26.78 +      </listitem>
   26.79 +      <listitem><para><literal role="hook">preupdate</literal>:
   26.80 +	  Controlling. This is run before starting an update or merge
   26.81 +	  of the working directory.
   26.82 +	</para>
   26.83 +      </listitem>
   26.84 +      <listitem><para><literal role="hook">tag</literal>: This is run
   26.85 +	  after a tag is created.
   26.86 +	</para>
   26.87 +      </listitem>
   26.88 +      <listitem><para><literal role="hook">update</literal>: This is
   26.89 +	  run after an update or merge of the working directory has
   26.90 +	  finished.
   26.91 +	</para>
   26.92 +      </listitem></itemizedlist>
   26.93 +    <para>Each of the hooks whose description begins with the word
   26.94 +      <quote>Controlling</quote> has the ability to determine whether
   26.95 +      an activity can proceed.  If the hook succeeds, the activity may
   26.96 +      proceed; if it fails, the activity is either not permitted or
   26.97 +      undone, depending on the hook.
   26.98 +    </para>
   26.99 +
  26.100 +  </sect1>
  26.101 +  <sect1>
  26.102 +    <title>Hooks and security</title>
  26.103 +
  26.104 +    <sect2>
  26.105 +      <title>Hooks are run with your privileges</title>
  26.106 +
  26.107 +      <para>When you run a Mercurial command in a repository, and the
  26.108 +	command causes a hook to run, that hook runs on
  26.109 +	<emphasis>your</emphasis> system, under
  26.110 +	<emphasis>your</emphasis> user account, with
  26.111 +	<emphasis>your</emphasis> privilege level.  Since hooks are
  26.112 +	arbitrary pieces of executable code, you should treat them
  26.113 +	with an appropriate level of suspicion.  Do not install a hook
  26.114 +	unless you are confident that you know who created it and what
  26.115 +	it does.
  26.116 +      </para>
  26.117 +
  26.118 +      <para>In some cases, you may be exposed to hooks that you did
  26.119 +	not install yourself.  If you work with Mercurial on an
  26.120 +	unfamiliar system, Mercurial will run hooks defined in that
  26.121 +	system's global <filename role="special">~/.hgrc</filename>
  26.122 +	file.
  26.123 +      </para>
  26.124 +
  26.125 +      <para>If you are working with a repository owned by another
  26.126 +	user, Mercurial can run hooks defined in that user's
  26.127 +	repository, but it will still run them as <quote>you</quote>.
  26.128 +	For example, if you <command role="hg-cmd">hg pull</command>
  26.129 +	from that repository, and its <filename
  26.130 +	  role="special">.hg/hgrc</filename> defines a local <literal
  26.131 +	  role="hook">outgoing</literal> hook, that hook will run
  26.132 +	under your user account, even though you don't own that
  26.133 +	repository.
  26.134 +      </para>
  26.135 +
  26.136 +      <note>
  26.137 +	<para>  This only applies if you are pulling from a repository
  26.138 +	  on a local or network filesystem.  If you're pulling over
  26.139 +	  http or ssh, any <literal role="hook">outgoing</literal>
  26.140 +	  hook will run under whatever account is executing the server
  26.141 +	  process, on the server.
  26.142 +	</para>
  26.143 +      </note>
  26.144 +
  26.145 +      <para>XXX To see what hooks are defined in a repository, use the
  26.146 +	<command role="hg-cmd">hg config hooks</command> command.  If
  26.147 +	you are working in one repository, but talking to another that
  26.148 +	you do not own (e.g. using <command role="hg-cmd">hg
  26.149 +	  pull</command> or <command role="hg-cmd">hg
  26.150 +	  incoming</command>), remember that it is the other
  26.151 +	repository's hooks you should be checking, not your own.
  26.152 +      </para>
  26.153 +
  26.154 +    </sect2>
  26.155 +    <sect2>
  26.156 +      <title>Hooks do not propagate</title>
  26.157 +
  26.158 +      <para>In Mercurial, hooks are not revision controlled, and do
  26.159 +	not propagate when you clone, or pull from, a repository.  The
  26.160 +	reason for this is simple: a hook is a completely arbitrary
  26.161 +	piece of executable code.  It runs under your user identity,
  26.162 +	with your privilege level, on your machine.
  26.163 +      </para>
  26.164 +
  26.165 +      <para>It would be extremely reckless for any distributed
  26.166 +	revision control system to implement revision-controlled
  26.167 +	hooks, as this would offer an easily exploitable way to
  26.168 +	subvert the accounts of users of the revision control system.
  26.169 +      </para>
  26.170 +
  26.171 +      <para>Since Mercurial does not propagate hooks, if you are
  26.172 +	collaborating with other people on a common project, you
  26.173 +	should not assume that they are using the same Mercurial hooks
  26.174 +	as you are, or that theirs are correctly configured.  You
  26.175 +	should document the hooks you expect people to use.
  26.176 +      </para>
  26.177 +
  26.178 +      <para>In a corporate intranet, this is somewhat easier to
  26.179 +	control, as you can for example provide a
  26.180 +	<quote>standard</quote> installation of Mercurial on an NFS
  26.181 +	filesystem, and use a site-wide <filename role="special">~/.hgrc</filename> file to define hooks that all users will
  26.182 +	see.  However, this too has its limits; see below.
  26.183 +      </para>
  26.184 +
  26.185 +    </sect2>
  26.186 +    <sect2>
  26.187 +      <title>Hooks can be overridden</title>
  26.188 +
  26.189 +      <para>Mercurial allows you to override a hook definition by
  26.190 +	redefining the hook.  You can disable it by setting its value
  26.191 +	to the empty string, or change its behaviour as you wish.
  26.192 +      </para>
  26.193 +
  26.194 +      <para>If you deploy a system- or site-wide <filename
  26.195 +	  role="special">~/.hgrc</filename> file that defines some
  26.196 +	hooks, you should thus understand that your users can disable
  26.197 +	or override those hooks.
  26.198 +      </para>
  26.199 +
  26.200 +    </sect2>
  26.201 +    <sect2>
  26.202 +      <title>Ensuring that critical hooks are run</title>
  26.203 +
  26.204 +      <para>Sometimes you may want to enforce a policy that you do not
  26.205 +	want others to be able to work around.  For example, you may
  26.206 +	have a requirement that every changeset must pass a rigorous
  26.207 +	set of tests.  Defining this requirement via a hook in a
  26.208 +	site-wide <filename role="special">~/.hgrc</filename> won't
  26.209 +	work for remote users on laptops, and of course local users
  26.210 +	can subvert it at will by overriding the hook.
  26.211 +      </para>
  26.212 +
  26.213 +      <para>Instead, you can set up your policies for use of Mercurial
  26.214 +	so that people are expected to propagate changes through a
  26.215 +	well-known <quote>canonical</quote> server that you have
  26.216 +	locked down and configured appropriately.
  26.217 +      </para>
  26.218 +
  26.219 +      <para>One way to do this is via a combination of social
  26.220 +	engineering and technology.  Set up a restricted-access
  26.221 +	account; users can push changes over the network to
  26.222 +	repositories managed by this account, but they cannot log into
  26.223 +	the account and run normal shell commands.  In this scenario,
  26.224 +	a user can commit a changeset that contains any old garbage
  26.225 +	they want.
  26.226 +      </para>
  26.227 +
  26.228 +      <para>When someone pushes a changeset to the server that
  26.229 +	everyone pulls from, the server will test the changeset before
  26.230 +	it accepts it as permanent, and reject it if it fails to pass
  26.231 +	the test suite.  If people only pull changes from this
  26.232 +	filtering server, it will serve to ensure that all changes
  26.233 +	that people pull have been automatically vetted.
  26.234 +      </para>
  26.235 +
  26.236 +    </sect2>
  26.237 +  </sect1>
  26.238 +  <sect1>
  26.239 +    <title>Care with <literal>pretxn</literal> hooks in a
  26.240 +      shared-access repository</title>
  26.241 +
  26.242 +    <para>If you want to use hooks to do some automated work in a
  26.243 +      repository that a number of people have shared access to, you
  26.244 +      need to be careful in how you do this.
  26.245 +    </para>
  26.246 +
  26.247 +    <para>Mercurial only locks a repository when it is writing to the
  26.248 +      repository, and only the parts of Mercurial that write to the
  26.249 +      repository pay attention to locks.  Write locks are necessary to
  26.250 +      prevent multiple simultaneous writers from scribbling on each
  26.251 +      other's work, corrupting the repository.
  26.252 +    </para>
  26.253 +
  26.254 +    <para>Because Mercurial is careful with the order in which it
  26.255 +      reads and writes data, it does not need to acquire a lock when
  26.256 +      it wants to read data from the repository.  The parts of
  26.257 +      Mercurial that read from the repository never pay attention to
  26.258 +      locks.  This lockless reading scheme greatly increases
  26.259 +      performance and concurrency.
  26.260 +    </para>
  26.261 +
  26.262 +    <para>With great performance comes a trade-off, though, one which
  26.263 +      has the potential to cause you trouble unless you're aware of
  26.264 +      it.  To describe this requires a little detail about how
  26.265 +      Mercurial adds changesets to a repository and reads those
  26.266 +      changes.
  26.267 +    </para>
  26.268 +
  26.269 +    <para>When Mercurial <emphasis>writes</emphasis> metadata, it
  26.270 +      writes it straight into the destination file.  It writes file
  26.271 +      data first, then manifest data (which contains pointers to the
  26.272 +      new file data), then changelog data (which contains pointers to
  26.273 +      the new manifest data).  Before the first write to each file, it
  26.274 +      stores a record of where the end of the file was in its
  26.275 +      transaction log.  If the transaction must be rolled back,
  26.276 +      Mercurial simply truncates each file back to the size it was
  26.277 +      before the transaction began.
  26.278 +    </para>
  26.279 +
  26.280 +    <para>When Mercurial <emphasis>reads</emphasis> metadata, it reads
  26.281 +      the changelog first, then everything else.  Since a reader will
  26.282 +      only access parts of the manifest or file metadata that it can
  26.283 +      see in the changelog, it can never see partially written data.
  26.284 +    </para>
  26.285 +
  26.286 +    <para>Some controlling hooks (<literal
  26.287 +	role="hook">pretxncommit</literal> and <literal
  26.288 +	role="hook">pretxnchangegroup</literal>) run when a
  26.289 +      transaction is almost complete. All of the metadata has been
  26.290 +      written, but Mercurial can still roll the transaction back and
  26.291 +      cause the newly-written data to disappear.
  26.292 +    </para>
  26.293 +
  26.294 +    <para>If one of these hooks runs for long, it opens a window of
  26.295 +      time during which a reader can see the metadata for changesets
  26.296 +      that are not yet permanent, and should not be thought of as
  26.297 +      <quote>really there</quote>.  The longer the hook runs, the
  26.298 +      longer that window is open.
  26.299 +    </para>
  26.300 +
  26.301 +    <sect2>
  26.302 +      <title>The problem illustrated</title>
  26.303 +
  26.304 +      <para>In principle, a good use for the <literal
  26.305 +	  role="hook">pretxnchangegroup</literal> hook would be to
  26.306 +	automatically build and test incoming changes before they are
  26.307 +	accepted into a central repository.  This could let you
  26.308 +	guarantee that nobody can push changes to this repository that
  26.309 +	<quote>break the build</quote>. But if a client can pull
  26.310 +	changes while they're being tested, the usefulness of the test
  26.311 +	is zero; an unsuspecting someone can pull untested changes,
  26.312 +	potentially breaking their build.
  26.313 +      </para>
  26.314 +
  26.315 +      <para>The safest technological answer to this challenge is to
  26.316 +	set up such a <quote>gatekeeper</quote> repository as
  26.317 +	<emphasis>unidirectional</emphasis>.  Let it take changes
  26.318 +	pushed in from the outside, but do not allow anyone to pull
  26.319 +	changes from it (use the <literal
  26.320 +	  role="hook">preoutgoing</literal> hook to lock it down).
  26.321 +	Configure a <literal role="hook">changegroup</literal> hook so
  26.322 +	that if a build or test succeeds, the hook will push the new
  26.323 +	changes out to another repository that people
  26.324 +	<emphasis>can</emphasis> pull from.
  26.325 +      </para>
  26.326 +
  26.327 +      <para>In practice, putting a centralised bottleneck like this in
  26.328 +	place is not often a good idea, and transaction visibility has
  26.329 +	nothing to do with the problem.  As the size of a
  26.330 +	project&emdash;and the time it takes to build and
  26.331 +	test&emdash;grows, you rapidly run into a wall with this
  26.332 +	<quote>try before you buy</quote> approach, where you have
  26.333 +	more changesets to test than time in which to deal with them.
  26.334 +	The inevitable result is frustration on the part of all
  26.335 +	involved.
  26.336 +      </para>
  26.337 +
  26.338 +      <para>An approach that scales better is to get people to build
  26.339 +	and test before they push, then run automated builds and tests
  26.340 +	centrally <emphasis>after</emphasis> a push, to be sure all is
  26.341 +	well.  The advantage of this approach is that it does not
  26.342 +	impose a limit on the rate at which the repository can accept
  26.343 +	changes.
  26.344 +      </para>
  26.345 +
  26.346 +    </sect2>
  26.347 +  </sect1>
  26.348 +  <sect1 id="sec.hook.simple">
  26.349 +    <title>A short tutorial on using hooks</title>
  26.350 +
  26.351 +    <para>It is easy to write a Mercurial hook.  Let's start with a
  26.352 +      hook that runs when you finish a <command role="hg-cmd">hg
  26.353 +	commit</command>, and simply prints the hash of the changeset
  26.354 +      you just created.  The hook is called <literal
  26.355 +	role="hook">commit</literal>.
  26.356 +    </para>
  26.357 +
  26.358 +    <para>All hooks follow the pattern in this example.</para>
  26.359 +
  26.360 +&interaction.hook.simple.init;
  26.361 +
  26.362 +    <para>You add an entry to the <literal
  26.363 +	role="rc-hooks">hooks</literal> section of your <filename
  26.364 +	role="special">~/.hgrc</filename>.  On the left is the name of
  26.365 +      the event to trigger on; on the right is the action to take.  As
  26.366 +      you can see, you can run an arbitrary shell command in a hook.
  26.367 +      Mercurial passes extra information to the hook using environment
  26.368 +      variables (look for <envar>HG_NODE</envar> in the example).
  26.369 +    </para>
  26.370 +
  26.371 +    <sect2>
  26.372 +      <title>Performing multiple actions per event</title>
  26.373 +
  26.374 +      <para>Quite often, you will want to define more than one hook
  26.375 +	for a particular kind of event, as shown below.</para>
  26.376 +
  26.377 +&interaction.hook.simple.ext;
  26.378 +
  26.379 +      <para>Mercurial lets you do this by adding an
  26.380 +	<emphasis>extension</emphasis> to the end of a hook's name.
  26.381 +	You extend a hook's name by giving the name of the hook,
  26.382 +	followed by a full stop (the
  26.383 +	<quote><literal>.</literal></quote> character), followed by
  26.384 +	some more text of your choosing.  For example, Mercurial will
  26.385 +	run both <literal>commit.foo</literal> and
  26.386 +	<literal>commit.bar</literal> when the
  26.387 +	<literal>commit</literal> event occurs.
  26.388 +      </para>
  26.389 +
  26.390 +      <para>To give a well-defined order of execution when there are
  26.391 +	multiple hooks defined for an event, Mercurial sorts hooks by
  26.392 +	extension, and executes the hook commands in this sorted
  26.393 +	order.  In the above example, it will execute
  26.394 +	<literal>commit.bar</literal> before
  26.395 +	<literal>commit.foo</literal>, and <literal>commit</literal>
  26.396 +	before both.
  26.397 +      </para>
  26.398 +
  26.399 +      <para>It is a good idea to use a somewhat descriptive extension
  26.400 +	when you define a new hook.  This will help you to remember
  26.401 +	what the hook was for.  If the hook fails, you'll get an error
  26.402 +	message that contains the hook name and extension, so using a
  26.403 +	descriptive extension could give you an immediate hint as to
  26.404 +	why the hook failed (see section <xref
  26.405 +	  linkend="sec.hook.perm"/> for an example).
  26.406 +      </para>
  26.407 +
  26.408 +    </sect2>
  26.409 +    <sect2 id="sec.hook.perm">
  26.410 +      <title>Controlling whether an activity can proceed</title>
  26.411 +
  26.412 +      <para>In our earlier examples, we used the <literal
  26.413 +	  role="hook">commit</literal> hook, which is run after a
  26.414 +	commit has completed.  This is one of several Mercurial hooks
  26.415 +	that run after an activity finishes.  Such hooks have no way
  26.416 +	of influencing the activity itself.
  26.417 +      </para>
  26.418 +
  26.419 +      <para>Mercurial defines a number of events that occur before an
  26.420 +	activity starts; or after it starts, but before it finishes.
  26.421 +	Hooks that trigger on these events have the added ability to
  26.422 +	choose whether the activity can continue, or will abort.
  26.423 +      </para>
  26.424 +
  26.425 +      <para>The <literal role="hook">pretxncommit</literal> hook runs
  26.426 +	after a commit has all but completed.  In other words, the
  26.427 +	metadata representing the changeset has been written out to
  26.428 +	disk, but the transaction has not yet been allowed to
  26.429 +	complete.  The <literal role="hook">pretxncommit</literal>
  26.430 +	hook has the ability to decide whether the transaction can
  26.431 +	complete, or must be rolled back.
  26.432 +      </para>
  26.433 +
  26.434 +      <para>If the <literal role="hook">pretxncommit</literal> hook
  26.435 +	exits with a status code of zero, the transaction is allowed
  26.436 +	to complete; the commit finishes; and the <literal
  26.437 +	  role="hook">commit</literal> hook is run.  If the <literal
  26.438 +	  role="hook">pretxncommit</literal> hook exits with a
  26.439 +	non-zero status code, the transaction is rolled back; the
  26.440 +	metadata representing the changeset is erased; and the
  26.441 +	<literal role="hook">commit</literal> hook is not run.
  26.442 +      </para>
  26.443 +
  26.444 +&interaction.hook.simple.pretxncommit;
  26.445 +
  26.446 +      <para>The hook in the example above checks that a commit comment
  26.447 +	contains a bug ID.  If it does, the commit can complete.  If
  26.448 +	not, the commit is rolled back.
  26.449 +      </para>
  26.450 +
  26.451 +    </sect2>
  26.452 +  </sect1>
  26.453 +  <sect1>
  26.454 +    <title>Writing your own hooks</title>
  26.455 +
  26.456 +    <para>When you are writing a hook, you might find it useful to run
  26.457 +      Mercurial either with the <option
  26.458 +	role="hg-opt-global">-v</option> option, or the <envar
  26.459 +	role="rc-item-ui">verbose</envar> config item set to
  26.460 +      <quote>true</quote>.  When you do so, Mercurial will print a
  26.461 +      message before it calls each hook.
  26.462 +    </para>
  26.463 +
  26.464 +    <sect2 id="sec.hook.lang">
  26.465 +      <title>Choosing how your hook should run</title>
  26.466 +
  26.467 +      <para>You can write a hook either as a normal
  26.468 +	program&emdash;typically a shell script&emdash;or as a Python
  26.469 +	function that is executed within the Mercurial process.
  26.470 +      </para>
  26.471 +
  26.472 +      <para>Writing a hook as an external program has the advantage
  26.473 +	that it requires no knowledge of Mercurial's internals.  You
  26.474 +	can call normal Mercurial commands to get any added
  26.475 +	information you need.  The trade-off is that external hooks
  26.476 +	are slower than in-process hooks.
  26.477 +      </para>
  26.478 +
  26.479 +      <para>An in-process Python hook has complete access to the
  26.480 +	Mercurial API, and does not <quote>shell out</quote> to
  26.481 +	another process, so it is inherently faster than an external
  26.482 +	hook.  It is also easier to obtain much of the information
  26.483 +	that a hook requires by using the Mercurial API than by
  26.484 +	running Mercurial commands.
  26.485 +      </para>
  26.486 +
  26.487 +      <para>If you are comfortable with Python, or require high
  26.488 +	performance, writing your hooks in Python may be a good
  26.489 +	choice.  However, when you have a straightforward hook to
  26.490 +	write and you don't need to care about performance (probably
  26.491 +	the majority of hooks), a shell script is perfectly fine.
  26.492 +      </para>
  26.493 +
  26.494 +    </sect2>
  26.495 +    <sect2 id="sec.hook.param">
  26.496 +      <title>Hook parameters</title>
  26.497 +
  26.498 +      <para>Mercurial calls each hook with a set of well-defined
  26.499 +	parameters.  In Python, a parameter is passed as a keyword
  26.500 +	argument to your hook function.  For an external program, a
  26.501 +	parameter is passed as an environment variable.
  26.502 +      </para>
  26.503 +
  26.504 +      <para>Whether your hook is written in Python or as a shell
  26.505 +	script, the hook-specific parameter names and values will be
  26.506 +	the same.  A boolean parameter will be represented as a
  26.507 +	boolean value in Python, but as the number 1 (for
  26.508 +	<quote>true</quote>) or 0 (for <quote>false</quote>) as an
  26.509 +	environment variable for an external hook.  If a hook
  26.510 +	parameter is named <literal>foo</literal>, the keyword
  26.511 +	argument for a Python hook will also be named
  26.512 +	<literal>foo</literal>, while the environment variable for an
  26.513 +	external hook will be named <literal>HG_FOO</literal>.
  26.514 +      </para>
  26.515 +
  26.516 +    </sect2>
  26.517 +    <sect2>
  26.518 +      <title>Hook return values and activity control</title>
  26.519 +
  26.520 +      <para>A hook that executes successfully must exit with a status
  26.521 +	of zero if external, or return boolean <quote>false</quote> if
  26.522 +	in-process.  Failure is indicated with a non-zero exit status
  26.523 +	from an external hook, or an in-process hook returning boolean
  26.524 +	<quote>true</quote>.  If an in-process hook raises an
  26.525 +	exception, the hook is considered to have failed.
  26.526 +      </para>
  26.527 +
  26.528 +      <para>For a hook that controls whether an activity can proceed,
  26.529 +	zero/false means <quote>allow</quote>, while
  26.530 +	non-zero/true/exception means <quote>deny</quote>.
  26.531 +      </para>
  26.532 +
  26.533 +    </sect2>
  26.534 +    <sect2>
  26.535 +      <title>Writing an external hook</title>
  26.536 +
  26.537 +      <para>When you define an external hook in your <filename
  26.538 +	  role="special">~/.hgrc</filename> and the hook is run, its
  26.539 +	value is passed to your shell, which interprets it.  This
  26.540 +	means that you can use normal shell constructs in the body of
  26.541 +	the hook.
  26.542 +      </para>
  26.543 +
  26.544 +      <para>An executable hook is always run with its current
  26.545 +	directory set to a repository's root directory.
  26.546 +      </para>
  26.547 +
  26.548 +      <para>Each hook parameter is passed in as an environment
  26.549 +	variable; the name is upper-cased, and prefixed with the
  26.550 +	string <quote><literal>HG_</literal></quote>.
  26.551 +      </para>
  26.552 +
  26.553 +      <para>With the exception of hook parameters, Mercurial does not
  26.554 +	set or modify any environment variables when running a hook.
  26.555 +	This is useful to remember if you are writing a site-wide hook
  26.556 +	that may be run by a number of different users with differing
  26.557 +	environment variables set. In multi-user situations, you
  26.558 +	should not rely on environment variables being set to the
  26.559 +	values you have in your environment when testing the hook.
  26.560 +      </para>
  26.561 +
  26.562 +    </sect2>
  26.563 +    <sect2>
  26.564 +      <title>Telling Mercurial to use an in-process hook</title>
  26.565 +
  26.566 +      <para>The <filename role="special">~/.hgrc</filename> syntax
  26.567 +	for defining an in-process hook is slightly different than for
  26.568 +	an executable hook.  The value of the hook must start with the
  26.569 +	text <quote><literal>python:</literal></quote>, and continue
  26.570 +	with the fully-qualified name of a callable object to use as
  26.571 +	the hook's value.
  26.572 +      </para>
  26.573 +
  26.574 +      <para>The module in which a hook lives is automatically imported
  26.575 +	when a hook is run.  So long as you have the module name and
  26.576 +	<envar>PYTHONPATH</envar> right, it should <quote>just
  26.577 +	  work</quote>.
  26.578 +      </para>
  26.579 +
  26.580 +      <para>The following <filename role="special">~/.hgrc</filename>
  26.581 +	example snippet illustrates the syntax and meaning of the
  26.582 +	notions we just described.
  26.583 +      </para>
  26.584 +      <programlisting>[hooks]
  26.585 +commit.example = python:mymodule.submodule.myhook</programlisting>
  26.586 +      <para>When Mercurial runs the <literal>commit.example</literal>
  26.587 +	hook, it imports <literal>mymodule.submodule</literal>, looks
  26.588 +	for the callable object named <literal>myhook</literal>, and
  26.589 +	calls it.
  26.590 +      </para>
  26.591 +
  26.592 +    </sect2>
  26.593 +    <sect2>
  26.594 +      <title>Writing an in-process hook</title>
  26.595 +
  26.596 +      <para>The simplest in-process hook does nothing, but illustrates
  26.597 +	the basic shape of the hook API:
  26.598 +      </para>
  26.599 +      <programlisting>def myhook(ui, repo, **kwargs):
  26.600 +    pass</programlisting>
  26.601 +      <para>The first argument to a Python hook is always a <literal
  26.602 +	  role="py-mod-mercurial.ui">ui</literal> object.  The second
  26.603 +	is a repository object; at the moment, it is always an
  26.604 +	instance of <literal
  26.605 +	  role="py-mod-mercurial.localrepo">localrepository</literal>.
  26.606 +	Following these two arguments are other keyword arguments.
  26.607 +	Which ones are passed in depends on the hook being called, but
  26.608 +	a hook can ignore arguments it doesn't care about by dropping
  26.609 +	them into a keyword argument dict, as with
  26.610 +	<literal>**kwargs</literal> above.
  26.611 +      </para>
  26.612 +
  26.613 +    </sect2>
  26.614 +  </sect1>
  26.615 +  <sect1>
  26.616 +    <title>Some hook examples</title>
  26.617 +
  26.618 +    <sect2>
  26.619 +      <title>Writing meaningful commit messages</title>
  26.620 +
  26.621 +      <para>It's hard to imagine a useful commit message being very
  26.622 +	short. The simple <literal role="hook">pretxncommit</literal>
  26.623 +	hook of the example below will prevent you from committing a
  26.624 +	changeset with a message that is less than ten bytes long.
  26.625 +      </para>
  26.626 +
  26.627 +&interaction.hook.msglen.go;
  26.628 +
  26.629 +    </sect2>
  26.630 +    <sect2>
  26.631 +      <title>Checking for trailing whitespace</title>
  26.632 +
  26.633 +      <para>An interesting use of a commit-related hook is to help you
  26.634 +	to write cleaner code.  A simple example of <quote>cleaner
  26.635 +	  code</quote> is the dictum that a change should not add any
  26.636 +	new lines of text that contain <quote>trailing
  26.637 +	  whitespace</quote>.  Trailing whitespace is a series of
  26.638 +	space and tab characters at the end of a line of text.  In
  26.639 +	most cases, trailing whitespace is unnecessary, invisible
  26.640 +	noise, but it is occasionally problematic, and people often
  26.641 +	prefer to get rid of it.
  26.642 +      </para>
  26.643 +
  26.644 +      <para>You can use either the <literal
  26.645 +	  role="hook">precommit</literal> or <literal
  26.646 +	  role="hook">pretxncommit</literal> hook to tell whether you
  26.647 +	have a trailing whitespace problem.  If you use the <literal
  26.648 +	  role="hook">precommit</literal> hook, the hook will not know
  26.649 +	which files you are committing, so it will have to check every
  26.650 +	modified file in the repository for trailing white space.  If
  26.651 +	you want to commit a change to just the file
  26.652 +	<filename>foo</filename>, but the file
  26.653 +	<filename>bar</filename> contains trailing whitespace, doing a
  26.654 +	check in the <literal role="hook">precommit</literal> hook
  26.655 +	will prevent you from committing <filename>foo</filename> due
  26.656 +	to the problem with <filename>bar</filename>.  This doesn't
  26.657 +	seem right.
  26.658 +      </para>
  26.659 +
  26.660 +      <para>Should you choose the <literal
  26.661 +	  role="hook">pretxncommit</literal> hook, the check won't
  26.662 +	occur until just before the transaction for the commit
  26.663 +	completes.  This will allow you to check for problems only the
  26.664 +	exact files that are being committed.  However, if you entered
  26.665 +	the commit message interactively and the hook fails, the
  26.666 +	transaction will roll back; you'll have to re-enter the commit
  26.667 +	message after you fix the trailing whitespace and run <command
  26.668 +	  role="hg-cmd">hg commit</command> again.
  26.669 +      </para>
  26.670 +
  26.671 +&interaction.hook.ws.simple;
  26.672 +
  26.673 +      <para>In this example, we introduce a simple <literal
  26.674 +	  role="hook">pretxncommit</literal> hook that checks for
  26.675 +	trailing whitespace.  This hook is short, but not very
  26.676 +	helpful.  It exits with an error status if a change adds a
  26.677 +	line with trailing whitespace to any file, but does not print
  26.678 +	any information that might help us to identify the offending
  26.679 +	file or line.  It also has the nice property of not paying
  26.680 +	attention to unmodified lines; only lines that introduce new
  26.681 +	trailing whitespace cause problems.
  26.682 +      </para>
  26.683 +
  26.684 +      <para>The above version is much more complex, but also more
  26.685 +	useful.  It parses a unified diff to see if any lines add
  26.686 +	trailing whitespace, and prints the name of the file and the
  26.687 +	line number of each such occurrence.  Even better, if the
  26.688 +	change adds trailing whitespace, this hook saves the commit
  26.689 +	comment and prints the name of the save file before exiting
  26.690 +	and telling Mercurial to roll the transaction back, so you can
  26.691 +	use the <option role="hg-opt-commit">-l filename</option>
  26.692 +	option to <command role="hg-cmd">hg commit</command> to reuse
  26.693 +	the saved commit message once you've corrected the problem.
  26.694 +      </para>
  26.695 +
  26.696 +&interaction.hook.ws.better;
  26.697 +
  26.698 +      <para>As a final aside, note in the example above the use of
  26.699 +	<command>perl</command>'s in-place editing feature to get rid
  26.700 +	of trailing whitespace from a file.  This is concise and
  26.701 +	useful enough that I will reproduce it here.
  26.702 +      </para>
  26.703 +      <programlisting>perl -pi -e 's,\s+$,,' filename</programlisting>
  26.704 +
  26.705 +    </sect2>
  26.706 +  </sect1>
  26.707 +  <sect1>
  26.708 +    <title>Bundled hooks</title>
  26.709 +
  26.710 +    <para>Mercurial ships with several bundled hooks.  You can find
  26.711 +      them in the <filename class="directory">hgext</filename>
  26.712 +      directory of a Mercurial source tree.  If you are using a
  26.713 +      Mercurial binary package, the hooks will be located in the
  26.714 +      <filename class="directory">hgext</filename> directory of
  26.715 +      wherever your package installer put Mercurial.
  26.716 +    </para>
  26.717 +
  26.718 +    <sect2>
  26.719 +      <title><literal role="hg-ext">acl</literal>&emdash;access
  26.720 +	control for parts of a repository</title>
  26.721 +
  26.722 +      <para>The <literal role="hg-ext">acl</literal> extension lets
  26.723 +	you control which remote users are allowed to push changesets
  26.724 +	to a networked server.  You can protect any portion of a
  26.725 +	repository (including the entire repo), so that a specific
  26.726 +	remote user can push changes that do not affect the protected
  26.727 +	portion.
  26.728 +      </para>
  26.729 +
  26.730 +      <para>This extension implements access control based on the
  26.731 +	identity of the user performing a push,
  26.732 +	<emphasis>not</emphasis> on who committed the changesets
  26.733 +	they're pushing.  It makes sense to use this hook only if you
  26.734 +	have a locked-down server environment that authenticates
  26.735 +	remote users, and you want to be sure that only specific users
  26.736 +	are allowed to push changes to that server.
  26.737 +      </para>
  26.738 +
  26.739 +      <sect3>
  26.740 +	<title>Configuring the <literal role="hook">acl</literal>
  26.741 +	  hook</title>
  26.742 +
  26.743 +	<para>In order to manage incoming changesets, the <literal
  26.744 +	    role="hg-ext">acl</literal> hook must be used as a
  26.745 +	  <literal role="hook">pretxnchangegroup</literal> hook.  This
  26.746 +	  lets it see which files are modified by each incoming
  26.747 +	  changeset, and roll back a group of changesets if they
  26.748 +	  modify <quote>forbidden</quote> files.  Example:
  26.749 +	</para>
  26.750 +	<programlisting>[hooks]
  26.751 +pretxnchangegroup.acl = python:hgext.acl.hook</programlisting>
  26.752 +
  26.753 +	<para>The <literal role="hg-ext">acl</literal> extension is
  26.754 +	  configured using three sections.
  26.755 +	</para>
  26.756 +
  26.757 +	<para>The <literal role="rc-acl">acl</literal> section has
  26.758 +	  only one entry, <envar role="rc-item-acl">sources</envar>,
  26.759 +	  which lists the sources of incoming changesets that the hook
  26.760 +	  should pay attention to.  You don't normally need to
  26.761 +	  configure this section.
  26.762 +	</para>
  26.763 +	<itemizedlist>
  26.764 +	  <listitem><para><envar role="rc-item-acl">serve</envar>:
  26.765 +	      Control incoming changesets that are arriving from a
  26.766 +	      remote repository over http or ssh.  This is the default
  26.767 +	      value of <envar role="rc-item-acl">sources</envar>, and
  26.768 +	      usually the only setting you'll need for this
  26.769 +	      configuration item.
  26.770 +	    </para>
  26.771 +	  </listitem>
  26.772 +	  <listitem><para><envar role="rc-item-acl">pull</envar>:
  26.773 +	      Control incoming changesets that are arriving via a pull
  26.774 +	      from a local repository.
  26.775 +	    </para>
  26.776 +	  </listitem>
  26.777 +	  <listitem><para><envar role="rc-item-acl">push</envar>:
  26.778 +	      Control incoming changesets that are arriving via a push
  26.779 +	      from a local repository.
  26.780 +	    </para>
  26.781 +	  </listitem>
  26.782 +	  <listitem><para><envar role="rc-item-acl">bundle</envar>:
  26.783 +	      Control incoming changesets that are arriving from
  26.784 +	      another repository via a bundle.
  26.785 +	    </para>
  26.786 +	  </listitem></itemizedlist>
  26.787 +
  26.788 +	<para>The <literal role="rc-acl.allow">acl.allow</literal>
  26.789 +	  section controls the users that are allowed to add
  26.790 +	  changesets to the repository.  If this section is not
  26.791 +	  present, all users that are not explicitly denied are
  26.792 +	  allowed.  If this section is present, all users that are not
  26.793 +	  explicitly allowed are denied (so an empty section means
  26.794 +	  that all users are denied).
  26.795 +	</para>
  26.796 +
  26.797 +	<para>The <literal role="rc-acl.deny">acl.deny</literal>
  26.798 +	  section determines which users are denied from adding
  26.799 +	  changesets to the repository.  If this section is not
  26.800 +	  present or is empty, no users are denied.
  26.801 +	</para>
  26.802 +
  26.803 +	<para>The syntaxes for the <literal
  26.804 +	    role="rc-acl.allow">acl.allow</literal> and <literal
  26.805 +	    role="rc-acl.deny">acl.deny</literal> sections are
  26.806 +	  identical.  On the left of each entry is a glob pattern that
  26.807 +	  matches files or directories, relative to the root of the
  26.808 +	  repository; on the right, a user name.
  26.809 +	</para>
  26.810 +
  26.811 +	<para>In the following example, the user
  26.812 +	  <literal>docwriter</literal> can only push changes to the
  26.813 +	  <filename class="directory">docs</filename> subtree of the
  26.814 +	  repository, while <literal>intern</literal> can push changes
  26.815 +	  to any file or directory except <filename
  26.816 +	    class="directory">source/sensitive</filename>.
  26.817 +	</para>
  26.818 +	<programlisting>[acl.allow]
  26.819 +docs/** = docwriter
  26.820 +[acl.deny]
  26.821 +source/sensitive/** = intern</programlisting>
  26.822 +
  26.823 +      </sect3>
  26.824 +      <sect3>
  26.825 +	<title>Testing and troubleshooting</title>
  26.826 +
  26.827 +	<para>If you want to test the <literal
  26.828 +	    role="hg-ext">acl</literal> hook, run it with Mercurial's
  26.829 +	  debugging output enabled.  Since you'll probably be running
  26.830 +	  it on a server where it's not convenient (or sometimes
  26.831 +	  possible) to pass in the <option
  26.832 +	    role="hg-opt-global">--debug</option> option, don't forget
  26.833 +	  that you can enable debugging output in your <filename
  26.834 +	    role="special">~/.hgrc</filename>:
  26.835 +	</para>
  26.836 +	<programlisting>[ui]
  26.837 +debug = true</programlisting>
  26.838 +	<para>With this enabled, the <literal
  26.839 +	    role="hg-ext">acl</literal> hook will print enough
  26.840 +	  information to let you figure out why it is allowing or
  26.841 +	  forbidding pushes from specific users.
  26.842 +	</para>
  26.843 +
  26.844 +      </sect3>
  26.845 +    </sect2>
  26.846 +    <sect2>
  26.847 +      <title><literal
  26.848 +	  role="hg-ext">bugzilla</literal>&emdash;integration with
  26.849 +	Bugzilla</title>
  26.850 +
  26.851 +      <para>The <literal role="hg-ext">bugzilla</literal> extension
  26.852 +	adds a comment to a Bugzilla bug whenever it finds a reference
  26.853 +	to that bug ID in a commit comment.  You can install this hook
  26.854 +	on a shared server, so that any time a remote user pushes
  26.855 +	changes to this server, the hook gets run.
  26.856 +      </para>
  26.857 +
  26.858 +      <para>It adds a comment to the bug that looks like this (you can
  26.859 +	configure the contents of the comment&emdash;see below):
  26.860 +      </para>
  26.861 +      <programlisting>Changeset aad8b264143a, made by Joe User
  26.862 +	&lt;joe.user@domain.com&gt; in the frobnitz repository, refers
  26.863 +	to this bug. For complete details, see
  26.864 +	http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a
  26.865 +	Changeset description: Fix bug 10483 by guarding against some
  26.866 +	NULL pointers</programlisting>
  26.867 +      <para>The value of this hook is that it automates the process of
  26.868 +	updating a bug any time a changeset refers to it.  If you
  26.869 +	configure the hook properly, it makes it easy for people to
  26.870 +	browse straight from a Bugzilla bug to a changeset that refers
  26.871 +	to that bug.
  26.872 +      </para>
  26.873 +
  26.874 +      <para>You can use the code in this hook as a starting point for
  26.875 +	some more exotic Bugzilla integration recipes.  Here are a few
  26.876 +	possibilities:
  26.877 +      </para>
  26.878 +      <itemizedlist>
  26.879 +	<listitem><para>Require that every changeset pushed to the
  26.880 +	    server have a valid bug ID in its commit comment.  In this
  26.881 +	    case, you'd want to configure the hook as a <literal
  26.882 +	      role="hook">pretxncommit</literal> hook.  This would
  26.883 +	    allow the hook to reject changes that didn't contain bug
  26.884 +	    IDs.
  26.885 +	  </para>
  26.886 +	</listitem>
  26.887 +	<listitem><para>Allow incoming changesets to automatically
  26.888 +	    modify the <emphasis>state</emphasis> of a bug, as well as
  26.889 +	    simply adding a comment.  For example, the hook could
  26.890 +	    recognise the string <quote>fixed bug 31337</quote> as
  26.891 +	    indicating that it should update the state of bug 31337 to
  26.892 +	    <quote>requires testing</quote>.
  26.893 +	  </para>
  26.894 +	</listitem></itemizedlist>
  26.895 +
  26.896 +      <sect3 id="sec.hook.bugzilla.config">
  26.897 +	<title>Configuring the <literal role="hook">bugzilla</literal>
  26.898 +	  hook</title>
  26.899 +
  26.900 +	<para>You should configure this hook in your server's
  26.901 +	  <filename role="special">~/.hgrc</filename> as an <literal
  26.902 +	    role="hook">incoming</literal> hook, for example as
  26.903 +	  follows:
  26.904 +	</para>
  26.905 +	<programlisting>[hooks]
  26.906 +incoming.bugzilla = python:hgext.bugzilla.hook</programlisting>
  26.907 +
  26.908 +	<para>Because of the specialised nature of this hook, and
  26.909 +	  because Bugzilla was not written with this kind of
  26.910 +	  integration in mind, configuring this hook is a somewhat
  26.911 +	  involved process.
  26.912 +	</para>
  26.913 +
  26.914 +	<para>Before you begin, you must install the MySQL bindings
  26.915 +	  for Python on the host(s) where you'll be running the hook.
  26.916 +	  If this is not available as a binary package for your
  26.917 +	  system, you can download it from
  26.918 +	  <citation>web:mysql-python</citation>.
  26.919 +	</para>
  26.920 +
  26.921 +	<para>Configuration information for this hook lives in the
  26.922 +	  <literal role="rc-bugzilla">bugzilla</literal> section of
  26.923 +	  your <filename role="special">~/.hgrc</filename>.
  26.924 +	</para>
  26.925 +	<itemizedlist>
  26.926 +	  <listitem><para><envar
  26.927 +		role="rc-item-bugzilla">version</envar>: The version
  26.928 +	      of Bugzilla installed on the server.  The database
  26.929 +	      schema that Bugzilla uses changes occasionally, so this
  26.930 +	      hook has to know exactly which schema to use. At the
  26.931 +	      moment, the only version supported is
  26.932 +	      <literal>2.16</literal>.
  26.933 +	    </para>
  26.934 +	  </listitem>
  26.935 +	  <listitem><para><envar role="rc-item-bugzilla">host</envar>:
  26.936 +	      The hostname of the MySQL server that stores your
  26.937 +	      Bugzilla data.  The database must be configured to allow
  26.938 +	      connections from whatever host you are running the
  26.939 +	      <literal role="hook">bugzilla</literal> hook on.
  26.940 +	    </para>
  26.941 +	  </listitem>
  26.942 +	  <listitem><para><envar role="rc-item-bugzilla">user</envar>:
  26.943 +	      The username with which to connect to the MySQL server.
  26.944 +	      The database must be configured to allow this user to
  26.945 +	      connect from whatever host you are running the <literal
  26.946 +		role="hook">bugzilla</literal> hook on.  This user
  26.947 +	      must be able to access and modify Bugzilla tables.  The
  26.948 +	      default value of this item is <literal>bugs</literal>,
  26.949 +	      which is the standard name of the Bugzilla user in a
  26.950 +	      MySQL database.
  26.951 +	    </para>
  26.952 +	  </listitem>
  26.953 +	  <listitem><para><envar
  26.954 +		role="rc-item-bugzilla">password</envar>: The MySQL
  26.955 +	      password for the user you configured above.  This is
  26.956 +	      stored as plain text, so you should make sure that
  26.957 +	      unauthorised users cannot read the <filename
  26.958 +		role="special">~/.hgrc</filename> file where you
  26.959 +	      store this information.
  26.960 +	    </para>
  26.961 +	  </listitem>
  26.962 +	  <listitem><para><envar role="rc-item-bugzilla">db</envar>:
  26.963 +	      The name of the Bugzilla database on the MySQL server.
  26.964 +	      The default value of this item is
  26.965 +	      <literal>bugs</literal>, which is the standard name of
  26.966 +	      the MySQL database where Bugzilla stores its data.
  26.967 +	    </para>
  26.968 +	  </listitem>
  26.969 +	  <listitem><para><envar
  26.970 +		role="rc-item-bugzilla">notify</envar>: If you want
  26.971 +	      Bugzilla to send out a notification email to subscribers
  26.972 +	      after this hook has added a comment to a bug, you will
  26.973 +	      need this hook to run a command whenever it updates the
  26.974 +	      database.  The command to run depends on where you have
  26.975 +	      installed Bugzilla, but it will typically look something
  26.976 +	      like this, if you have Bugzilla installed in <filename
  26.977 +		class="directory">/var/www/html/bugzilla</filename>:
  26.978 +	    </para>
  26.979 +	    <programlisting>cd /var/www/html/bugzilla &amp;&amp;
  26.980 +	      ./processmail %s nobody@nowhere.com</programlisting>
  26.981 +	  </listitem>
  26.982 +	  <listitem><para>  The Bugzilla
  26.983 +	      <literal>processmail</literal> program expects to be
  26.984 +	      given a bug ID (the hook replaces
  26.985 +	      <quote><literal>%s</literal></quote> with the bug ID)
  26.986 +	      and an email address.  It also expects to be able to
  26.987 +	      write to some files in the directory that it runs in.
  26.988 +	      If Bugzilla and this hook are not installed on the same
  26.989 +	      machine, you will need to find a way to run
  26.990 +	      <literal>processmail</literal> on the server where
  26.991 +	      Bugzilla is installed.
  26.992 +	    </para>
  26.993 +	  </listitem></itemizedlist>
  26.994 +
  26.995 +      </sect3>
  26.996 +      <sect3>
  26.997 +	<title>Mapping committer names to Bugzilla user names</title>
  26.998 +
  26.999 +	<para>By default, the <literal
 26.1000 +	    role="hg-ext">bugzilla</literal> hook tries to use the
 26.1001 +	  email address of a changeset's committer as the Bugzilla
 26.1002 +	  user name with which to update a bug.  If this does not suit
 26.1003 +	  your needs, you can map committer email addresses to
 26.1004 +	  Bugzilla user names using a <literal
 26.1005 +	    role="rc-usermap">usermap</literal> section.
 26.1006 +	</para>
 26.1007 +
 26.1008 +	<para>Each item in the <literal
 26.1009 +	    role="rc-usermap">usermap</literal> section contains an
 26.1010 +	  email address on the left, and a Bugzilla user name on the
 26.1011 +	  right.
 26.1012 +	</para>
 26.1013 +	<programlisting>[usermap]
 26.1014 +jane.user@example.com = jane</programlisting>
 26.1015 +	<para>You can either keep the <literal
 26.1016 +	    role="rc-usermap">usermap</literal> data in a normal
 26.1017 +	  <filename role="special">~/.hgrc</filename>, or tell the
 26.1018 +	  <literal role="hg-ext">bugzilla</literal> hook to read the
 26.1019 +	  information from an external <filename>usermap</filename>
 26.1020 +	  file.  In the latter case, you can store
 26.1021 +	  <filename>usermap</filename> data by itself in (for example)
 26.1022 +	  a user-modifiable repository.  This makes it possible to let
 26.1023 +	  your users maintain their own <envar
 26.1024 +	    role="rc-item-bugzilla">usermap</envar> entries.  The main
 26.1025 +	  <filename role="special">~/.hgrc</filename> file might look
 26.1026 +	  like this:
 26.1027 +	</para>
 26.1028 +	<programlisting># regular hgrc file refers to external usermap file
 26.1029 +[bugzilla]
 26.1030 +usermap = /home/hg/repos/userdata/bugzilla-usermap.conf</programlisting>
 26.1031 +	<para>While the <filename>usermap</filename> file that it
 26.1032 +	  refers to might look like this:
 26.1033 +	</para>
 26.1034 +	<programlisting># bugzilla-usermap.conf - inside a hg repository
 26.1035 +[usermap] stephanie@example.com = steph</programlisting>
 26.1036 +
 26.1037 +      </sect3>
 26.1038 +      <sect3>
 26.1039 +	<title>Configuring the text that gets added to a bug</title>
 26.1040 +
 26.1041 +	<para>You can configure the text that this hook adds as a
 26.1042 +	  comment; you specify it in the form of a Mercurial template.
 26.1043 +	  Several <filename role="special">~/.hgrc</filename> entries
 26.1044 +	  (still in the <literal role="rc-bugzilla">bugzilla</literal>
 26.1045 +	  section) control this behaviour.
 26.1046 +	</para>
 26.1047 +	<itemizedlist>
 26.1048 +	  <listitem><para><literal>strip</literal>: The number of
 26.1049 +	      leading path elements to strip from a repository's path
 26.1050 +	      name to construct a partial path for a URL. For example,
 26.1051 +	      if the repositories on your server live under <filename
 26.1052 +		class="directory">/home/hg/repos</filename>, and you
 26.1053 +	      have a repository whose path is <filename
 26.1054 +		class="directory">/home/hg/repos/app/tests</filename>,
 26.1055 +	      then setting <literal>strip</literal> to
 26.1056 +	      <literal>4</literal> will give a partial path of
 26.1057 +	      <filename class="directory">app/tests</filename>.  The
 26.1058 +	      hook will make this partial path available when
 26.1059 +	      expanding a template, as <literal>webroot</literal>.
 26.1060 +	    </para>
 26.1061 +	  </listitem>
 26.1062 +	  <listitem><para><literal>template</literal>: The text of the
 26.1063 +	      template to use.  In addition to the usual
 26.1064 +	      changeset-related variables, this template can use
 26.1065 +	      <literal>hgweb</literal> (the value of the
 26.1066 +	      <literal>hgweb</literal> configuration item above) and
 26.1067 +	      <literal>webroot</literal> (the path constructed using
 26.1068 +	      <literal>strip</literal> above).
 26.1069 +	    </para>
 26.1070 +	  </listitem></itemizedlist>
 26.1071 +
 26.1072 +	<para>In addition, you can add a <envar
 26.1073 +	    role="rc-item-web">baseurl</envar> item to the <literal
 26.1074 +	    role="rc-web">web</literal> section of your <filename
 26.1075 +	    role="special">~/.hgrc</filename>.  The <literal
 26.1076 +	    role="hg-ext">bugzilla</literal> hook will make this
 26.1077 +	  available when expanding a template, as the base string to
 26.1078 +	  use when constructing a URL that will let users browse from
 26.1079 +	  a Bugzilla comment to view a changeset.  Example:
 26.1080 +	</para>
 26.1081 +	<programlisting>[web]
 26.1082 +baseurl = http://hg.domain.com/</programlisting>
 26.1083 +
 26.1084 +	<para>Here is an example set of <literal
 26.1085 +	    role="hg-ext">bugzilla</literal> hook config information.
 26.1086 +	</para>
 26.1087 +
 26.1088 +	<programlisting>&ch10-bugzilla-config.lst;</programlisting>
 26.1089 +
 26.1090 +      </sect3>
 26.1091 +      <sect3>
 26.1092 +	<title>Testing and troubleshooting</title>
 26.1093 +
 26.1094 +	<para>The most common problems with configuring the <literal
 26.1095 +	    role="hg-ext">bugzilla</literal> hook relate to running
 26.1096 +	  Bugzilla's <filename>processmail</filename> script and
 26.1097 +	  mapping committer names to user names.
 26.1098 +	</para>
 26.1099 +
 26.1100 +	<para>Recall from section <xref
 26.1101 +	    linkend="sec.hook.bugzilla.config"/> above that the user
 26.1102 +	  that runs the Mercurial process on the server is also the
 26.1103 +	  one that will run the <filename>processmail</filename>
 26.1104 +	  script.  The <filename>processmail</filename> script
 26.1105 +	  sometimes causes Bugzilla to write to files in its
 26.1106 +	  configuration directory, and Bugzilla's configuration files
 26.1107 +	  are usually owned by the user that your web server runs
 26.1108 +	  under.
 26.1109 +	</para>
 26.1110 +
 26.1111 +	<para>You can cause <filename>processmail</filename> to be run
 26.1112 +	  with the suitable user's identity using the
 26.1113 +	  <command>sudo</command> command.  Here is an example entry
 26.1114 +	  for a <filename>sudoers</filename> file.
 26.1115 +	</para>
 26.1116 +	<programlisting>hg_user = (httpd_user)
 26.1117 +NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s</programlisting>
 26.1118 +	<para>This allows the <literal>hg_user</literal> user to run a
 26.1119 +	  <filename>processmail-wrapper</filename> program under the
 26.1120 +	  identity of <literal>httpd_user</literal>.
 26.1121 +	</para>
 26.1122 +
 26.1123 +	<para>This indirection through a wrapper script is necessary,
 26.1124 +	  because <filename>processmail</filename> expects to be run
 26.1125 +	  with its current directory set to wherever you installed
 26.1126 +	  Bugzilla; you can't specify that kind of constraint in a
 26.1127 +	  <filename>sudoers</filename> file.  The contents of the
 26.1128 +	  wrapper script are simple:
 26.1129 +	</para>
 26.1130 +	<programlisting>#!/bin/sh
 26.1131 +cd `dirname $0` &amp;&amp; ./processmail "$1" nobody@example.com</programlisting>
 26.1132 +	<para>It doesn't seem to matter what email address you pass to
 26.1133 +	  <filename>processmail</filename>.
 26.1134 +	</para>
 26.1135 +
 26.1136 +	<para>If your <literal role="rc-usermap">usermap</literal> is
 26.1137 +	  not set up correctly, users will see an error message from
 26.1138 +	  the <literal role="hg-ext">bugzilla</literal> hook when they
 26.1139 +	  push changes to the server.  The error message will look
 26.1140 +	  like this:
 26.1141 +	</para>
 26.1142 +	<programlisting>cannot find bugzilla user id for john.q.public@example.com</programlisting>
 26.1143 +	<para>What this means is that the committer's address,
 26.1144 +	  <literal>john.q.public@example.com</literal>, is not a valid
 26.1145 +	  Bugzilla user name, nor does it have an entry in your
 26.1146 +	  <literal role="rc-usermap">usermap</literal> that maps it to
 26.1147 +	  a valid Bugzilla user name.
 26.1148 +	</para>
 26.1149 +
 26.1150 +      </sect3>
 26.1151 +    </sect2>
 26.1152 +    <sect2>
 26.1153 +      <title><literal role="hg-ext">notify</literal>&emdash;send email
 26.1154 +	notifications</title>
 26.1155 +
 26.1156 +      <para>Although Mercurial's built-in web server provides RSS
 26.1157 +	feeds of changes in every repository, many people prefer to
 26.1158 +	receive change notifications via email.  The <literal
 26.1159 +	  role="hg-ext">notify</literal> hook lets you send out
 26.1160 +	notifications to a set of email addresses whenever changesets
 26.1161 +	arrive that those subscribers are interested in.
 26.1162 +      </para>
 26.1163 +
 26.1164 +      <para>As with the <literal role="hg-ext">bugzilla</literal>
 26.1165 +	hook, the <literal role="hg-ext">notify</literal> hook is
 26.1166 +	template-driven, so you can customise the contents of the
 26.1167 +	notification messages that it sends.
 26.1168 +      </para>
 26.1169 +
 26.1170 +      <para>By default, the <literal role="hg-ext">notify</literal>
 26.1171 +	hook includes a diff of every changeset that it sends out; you
 26.1172 +	can limit the size of the diff, or turn this feature off
 26.1173 +	entirely.  It is useful for letting subscribers review changes
 26.1174 +	immediately, rather than clicking to follow a URL.
 26.1175 +      </para>
 26.1176 +
 26.1177 +      <sect3>
 26.1178 +	<title>Configuring the <literal role="hg-ext">notify</literal>
 26.1179 +	  hook</title>
 26.1180 +
 26.1181 +	<para>You can set up the <literal
 26.1182 +	    role="hg-ext">notify</literal> hook to send one email
 26.1183 +	  message per incoming changeset, or one per incoming group of
 26.1184 +	  changesets (all those that arrived in a single pull or
 26.1185 +	  push).
 26.1186 +	</para>
 26.1187 +	<programlisting>[hooks]
 26.1188 +# send one email per group of changes
 26.1189 +changegroup.notify = python:hgext.notify.hook
 26.1190 +# send one email per change
 26.1191 +incoming.notify = python:hgext.notify.hook</programlisting>
 26.1192 +
 26.1193 +	<para>Configuration information for this hook lives in the
 26.1194 +	  <literal role="rc-notify">notify</literal> section of a
 26.1195 +	  <filename role="special">~/.hgrc</filename> file.
 26.1196 +	</para>
 26.1197 +	<itemizedlist>
 26.1198 +	  <listitem><para><envar role="rc-item-notify">test</envar>:
 26.1199 +	      By default, this hook does not send out email at all;
 26.1200 +	      instead, it prints the message that it
 26.1201 +	      <emphasis>would</emphasis> send.  Set this item to
 26.1202 +	      <literal>false</literal> to allow email to be sent. The
 26.1203 +	      reason that sending of email is turned off by default is
 26.1204 +	      that it takes several tries to configure this extension
 26.1205 +	      exactly as you would like, and it would be bad form to
 26.1206 +	      spam subscribers with a number of <quote>broken</quote>
 26.1207 +	      notifications while you debug your configuration.
 26.1208 +	    </para>
 26.1209 +	  </listitem>
 26.1210 +	  <listitem><para><envar role="rc-item-notify">config</envar>:
 26.1211 +	      The path to a configuration file that contains
 26.1212 +	      subscription information.  This is kept separate from
 26.1213 +	      the main <filename role="special">~/.hgrc</filename> so
 26.1214 +	      that you can maintain it in a repository of its own.
 26.1215 +	      People can then clone that repository, update their
 26.1216 +	      subscriptions, and push the changes back to your server.
 26.1217 +	    </para>
 26.1218 +	  </listitem>
 26.1219 +	  <listitem><para><envar role="rc-item-notify">strip</envar>:
 26.1220 +	      The number of leading path separator characters to strip
 26.1221 +	      from a repository's path, when deciding whether a
 26.1222 +	      repository has subscribers.  For example, if the
 26.1223 +	      repositories on your server live in <filename
 26.1224 +		class="directory">/home/hg/repos</filename>, and
 26.1225 +	      <literal role="hg-ext">notify</literal> is considering a
 26.1226 +	      repository named <filename
 26.1227 +		class="directory">/home/hg/repos/shared/test</filename>, 
 26.1228 +	      setting <envar role="rc-item-notify">strip</envar> to
 26.1229 +	      <literal>4</literal> will cause <literal
 26.1230 +		role="hg-ext">notify</literal> to trim the path it
 26.1231 +	      considers down to <filename
 26.1232 +		class="directory">shared/test</filename>, and it will
 26.1233 +	      match subscribers against that.
 26.1234 +	    </para>
 26.1235 +	  </listitem>
 26.1236 +	  <listitem><para><envar
 26.1237 +		role="rc-item-notify">template</envar>: The template
 26.1238 +	      text to use when sending messages.  This specifies both
 26.1239 +	      the contents of the message header and its body.
 26.1240 +	    </para>
 26.1241 +	  </listitem>
 26.1242 +	  <listitem><para><envar
 26.1243 +		role="rc-item-notify">maxdiff</envar>: The maximum
 26.1244 +	      number of lines of diff data to append to the end of a
 26.1245 +	      message.  If a diff is longer than this, it is
 26.1246 +	      truncated.  By default, this is set to 300.  Set this to
 26.1247 +	      <literal>0</literal> to omit diffs from notification
 26.1248 +	      emails.
 26.1249 +	    </para>
 26.1250 +	  </listitem>
 26.1251 +	  <listitem><para><envar
 26.1252 +		role="rc-item-notify">sources</envar>: A list of
 26.1253 +	      sources of changesets to consider.  This lets you limit
 26.1254 +	      <literal role="hg-ext">notify</literal> to only sending
 26.1255 +	      out email about changes that remote users pushed into
 26.1256 +	      this repository via a server, for example.  See section
 26.1257 +	      <xref
 26.1258 +		linkend="sec.hook.sources"/> for the sources you can
 26.1259 +	      specify here.
 26.1260 +	    </para>
 26.1261 +	  </listitem></itemizedlist>
 26.1262 +
 26.1263 +	<para>If you set the <envar role="rc-item-web">baseurl</envar>
 26.1264 +	  item in the <literal role="rc-web">web</literal> section,
 26.1265 +	  you can use it in a template; it will be available as
 26.1266 +	  <literal>webroot</literal>.
 26.1267 +	</para>
 26.1268 +
 26.1269 +	<para>Here is an example set of <literal
 26.1270 +	    role="hg-ext">notify</literal> configuration information.
 26.1271 +	</para>
 26.1272 +
 26.1273 +	<programlisting>&ch10-notify-config.lst;</programlisting>
 26.1274 +
 26.1275 +	<para>This will produce a message that looks like the
 26.1276 +	  following:
 26.1277 +	</para>
 26.1278 +
 26.1279 +	<programlisting>&ch10-notify-config-mail.lst;</programlisting>
 26.1280 +
 26.1281 +      </sect3>
 26.1282 +      <sect3>
 26.1283 +	<title>Testing and troubleshooting</title>
 26.1284 +
 26.1285 +	<para>Do not forget that by default, the <literal
 26.1286 +		role="hg-ext">notify</literal> extension <emphasis>will not
 26.1287 +	  send any mail</emphasis> until you explicitly configure it to do so,
 26.1288 +	  by setting <envar role="rc-item-notify">test</envar> to
 26.1289 +	  <literal>false</literal>.  Until you do that, it simply
 26.1290 +	  prints the message it <emphasis>would</emphasis> send.
 26.1291 +	</para>
 26.1292 +
 26.1293 +      </sect3>
 26.1294 +    </sect2>
 26.1295 +  </sect1>
 26.1296 +  <sect1 id="sec.hook.ref">
 26.1297 +    <title>Information for writers of hooks</title>
 26.1298 +
 26.1299 +    <sect2>
 26.1300 +      <title>In-process hook execution</title>
 26.1301 +
 26.1302 +      <para>An in-process hook is called with arguments of the
 26.1303 +	following form:
 26.1304 +      </para>
 26.1305 +      <programlisting>def myhook(ui, repo, **kwargs): pass</programlisting>
 26.1306 +      <para>The <literal>ui</literal> parameter is a <literal
 26.1307 +	  role="py-mod-mercurial.ui">ui</literal> object. The
 26.1308 +	<literal>repo</literal> parameter is a <literal
 26.1309 +	  role="py-mod-mercurial.localrepo">localrepository</literal>
 26.1310 +	object.  The names and values of the
 26.1311 +	<literal>**kwargs</literal> parameters depend on the hook
 26.1312 +	being invoked, with the following common features:
 26.1313 +      </para>
 26.1314 +      <itemizedlist>
 26.1315 +	<listitem><para>If a parameter is named
 26.1316 +	    <literal>node</literal> or <literal>parentN</literal>, it
 26.1317 +	    will contain a hexadecimal changeset ID. The empty string
 26.1318 +	    is used to represent <quote>null changeset ID</quote>
 26.1319 +	    instead of a string of zeroes.
 26.1320 +	  </para>
 26.1321 +	</listitem>
 26.1322 +	<listitem><para>If a parameter is named
 26.1323 +	    <literal>url</literal>, it will contain the URL of a
 26.1324 +	    remote repository, if that can be determined.
 26.1325 +	  </para>
 26.1326 +	</listitem>
 26.1327 +	<listitem><para>Boolean-valued parameters are represented as
 26.1328 +	    Python <literal>bool</literal> objects.
 26.1329 +	  </para>
 26.1330 +	</listitem></itemizedlist>
 26.1331 +
 26.1332 +      <para>An in-process hook is called without a change to the
 26.1333 +	process's working directory (unlike external hooks, which are
 26.1334 +	run in the root of the repository).  It must not change the
 26.1335 +	process's working directory, or it will cause any calls it
 26.1336 +	makes into the Mercurial API to fail.
 26.1337 +      </para>
 26.1338 +
 26.1339 +      <para>If a hook returns a boolean <quote>false</quote> value, it
 26.1340 +	is considered to have succeeded.  If it returns a boolean
 26.1341 +	<quote>true</quote> value or raises an exception, it is
 26.1342 +	considered to have failed.  A useful way to think of the
 26.1343 +	calling convention is <quote>tell me if you fail</quote>.
 26.1344 +      </para>
 26.1345 +
 26.1346 +      <para>Note that changeset IDs are passed into Python hooks as
 26.1347 +	hexadecimal strings, not the binary hashes that Mercurial's
 26.1348 +	APIs normally use.  To convert a hash from hex to binary, use
 26.1349 +	the <literal>bin</literal> function.
 26.1350 +      </para>
 26.1351 +
 26.1352 +    </sect2>
 26.1353 +    <sect2>
 26.1354 +      <title>External hook execution</title>
 26.1355 +
 26.1356 +      <para>An external hook is passed to the shell of the user
 26.1357 +	running Mercurial. Features of that shell, such as variable
 26.1358 +	substitution and command redirection, are available.  The hook
 26.1359 +	is run in the root directory of the repository (unlike
 26.1360 +	in-process hooks, which are run in the same directory that
 26.1361 +	Mercurial was run in).
 26.1362 +      </para>
 26.1363 +
 26.1364 +      <para>Hook parameters are passed to the hook as environment
 26.1365 +	variables.  Each environment variable's name is converted in
 26.1366 +	upper case and prefixed with the string
 26.1367 +	<quote><literal>HG_</literal></quote>.  For example, if the
 26.1368 +	name of a parameter is <quote><literal>node</literal></quote>,
 26.1369 +	the name of the environment variable representing that
 26.1370 +	parameter will be <quote><literal>HG_NODE</literal></quote>.
 26.1371 +      </para>
 26.1372 +
 26.1373 +      <para>A boolean parameter is represented as the string
 26.1374 +	<quote><literal>1</literal></quote> for <quote>true</quote>,
 26.1375 +	<quote><literal>0</literal></quote> for <quote>false</quote>.
 26.1376 +	If an environment variable is named <envar>HG_NODE</envar>,
 26.1377 +	<envar>HG_PARENT1</envar> or <envar>HG_PARENT2</envar>, it
 26.1378 +	contains a changeset ID represented as a hexadecimal string.
 26.1379 +	The empty string is used to represent <quote>null changeset
 26.1380 +	  ID</quote> instead of a string of zeroes.  If an environment
 26.1381 +	variable is named <envar>HG_URL</envar>, it will contain the
 26.1382 +	URL of a remote repository, if that can be determined.
 26.1383 +      </para>
 26.1384 +
 26.1385 +      <para>If a hook exits with a status of zero, it is considered to
 26.1386 +	have succeeded.  If it exits with a non-zero status, it is
 26.1387 +	considered to have failed.
 26.1388 +      </para>
 26.1389 +
 26.1390 +    </sect2>
 26.1391 +    <sect2>
 26.1392 +      <title>Finding out where changesets come from</title>
 26.1393 +
 26.1394 +      <para>A hook that involves the transfer of changesets between a
 26.1395 +	local repository and another may be able to find out
 26.1396 +	information about the <quote>far side</quote>.  Mercurial
 26.1397 +	knows <emphasis>how</emphasis> changes are being transferred,
 26.1398 +	and in many cases <emphasis>where</emphasis> they are being
 26.1399 +	transferred to or from.
 26.1400 +      </para>
 26.1401 +
 26.1402 +      <sect3 id="sec.hook.sources">
 26.1403 +	<title>Sources of changesets</title>
 26.1404 +
 26.1405 +	<para>Mercurial will tell a hook what means are, or were, used
 26.1406 +	  to transfer changesets between repositories.  This is
 26.1407 +	  provided by Mercurial in a Python parameter named
 26.1408 +	  <literal>source</literal>, or an environment variable named
 26.1409 +	  <envar>HG_SOURCE</envar>.
 26.1410 +	</para>
 26.1411 +
 26.1412 +	<itemizedlist>
 26.1413 +	  <listitem><para><literal>serve</literal>: Changesets are
 26.1414 +	      transferred to or from a remote repository over http or
 26.1415 +	      ssh.
 26.1416 +	    </para>
 26.1417 +	  </listitem>
 26.1418 +	  <listitem><para><literal>pull</literal>: Changesets are
 26.1419 +	      being transferred via a pull from one repository into
 26.1420 +	      another.
 26.1421 +	    </para>
 26.1422 +	  </listitem>
 26.1423 +	  <listitem><para><literal>push</literal>: Changesets are
 26.1424 +	      being transferred via a push from one repository into
 26.1425 +	      another.
 26.1426 +	    </para>
 26.1427 +	  </listitem>
 26.1428 +	  <listitem><para><literal>bundle</literal>: Changesets are
 26.1429 +	      being transferred to or from a bundle.
 26.1430 +	    </para>
 26.1431 +	  </listitem></itemizedlist>
 26.1432 +
 26.1433 +      </sect3>
 26.1434 +      <sect3 id="sec.hook.url">
 26.1435 +	<title>Where changes are going&emdash;remote repository
 26.1436 +	  URLs</title>
 26.1437 +
 26.1438 +	<para>When possible, Mercurial will tell a hook the location
 26.1439 +	  of the <quote>far side</quote> of an activity that transfers
 26.1440 +	  changeset data between repositories.  This is provided by
 26.1441 +	  Mercurial in a Python parameter named
 26.1442 +	  <literal>url</literal>, or an environment variable named
 26.1443 +	  <envar>HG_URL</envar>.
 26.1444 +	</para>
 26.1445 +
 26.1446 +	<para>This information is not always known.  If a hook is
 26.1447 +	  invoked in a repository that is being served via http or
 26.1448 +	  ssh, Mercurial cannot tell where the remote repository is,
 26.1449 +	  but it may know where the client is connecting from.  In
 26.1450 +	  such cases, the URL will take one of the following forms:
 26.1451 +	</para>
 26.1452 +	<itemizedlist>
 26.1453 +	  <listitem><para><literal>remote:ssh:1.2.3.4</literal>&emdash;remote 
 26.1454 +	      ssh client, at the IP address
 26.1455 +	      <literal>1.2.3.4</literal>.
 26.1456 +	    </para>
 26.1457 +	  </listitem>
 26.1458 +	  <listitem><para><literal>remote:http:1.2.3.4</literal>&emdash;remote 
 26.1459 +	      http client, at the IP address
 26.1460 +	      <literal>1.2.3.4</literal>.  If the client is using SSL,
 26.1461 +	      this will be of the form
 26.1462 +	      <literal>remote:https:1.2.3.4</literal>.
 26.1463 +	    </para>
 26.1464 +	  </listitem>
 26.1465 +	  <listitem><para>Empty&emdash;no information could be
 26.1466 +	      discovered about the remote client.
 26.1467 +	    </para>
 26.1468 +	  </listitem></itemizedlist>
 26.1469 +
 26.1470 +      </sect3>
 26.1471 +    </sect2>
 26.1472 +  </sect1>
 26.1473 +  <sect1>
 26.1474 +    <title>Hook reference</title>
 26.1475 +
 26.1476 +    <sect2 id="sec.hook.changegroup">
 26.1477 +      <title><literal role="hook">changegroup</literal>&emdash;after
 26.1478 +	remote changesets added</title>
 26.1479 +
 26.1480 +      <para>This hook is run after a group of pre-existing changesets
 26.1481 +	has been added to the repository, for example via a <command
 26.1482 +	  role="hg-cmd">hg pull</command> or <command role="hg-cmd">hg
 26.1483 +	  unbundle</command>.  This hook is run once per operation
 26.1484 +	that added one or more changesets.  This is in contrast to the
 26.1485 +	<literal role="hook">incoming</literal> hook, which is run
 26.1486 +	once per changeset, regardless of whether the changesets
 26.1487 +	arrive in a group.
 26.1488 +      </para>
 26.1489 +
 26.1490 +      <para>Some possible uses for this hook include kicking off an
 26.1491 +	automated build or test of the added changesets, updating a
 26.1492 +	bug database, or notifying subscribers that a repository
 26.1493 +	contains new changes.
 26.1494 +      </para>
 26.1495 +
 26.1496 +      <para>Parameters to this hook:
 26.1497 +      </para>
 26.1498 +      <itemizedlist>
 26.1499 +	<listitem><para><literal>node</literal>: A changeset ID.  The
 26.1500 +	    changeset ID of the first changeset in the group that was
 26.1501 +	    added.  All changesets between this and
 26.1502 +	    <literal role="tag">tip</literal>, inclusive, were added by a single
 26.1503 +	    <command role="hg-cmd">hg pull</command>, <command
 26.1504 +	      role="hg-cmd">hg push</command> or <command
 26.1505 +	      role="hg-cmd">hg unbundle</command>.
 26.1506 +	  </para>
 26.1507 +	</listitem>
 26.1508 +	<listitem><para><literal>source</literal>: A string.  The
 26.1509 +	    source of these changes.  See section <xref
 26.1510 +	      linkend="sec.hook.sources"/> for details.
 26.1511 +	  </para>
 26.1512 +	</listitem>
 26.1513 +	<listitem><para><literal>url</literal>: A URL.  The location
 26.1514 +	    of the remote repository, if known.  See section <xref
 26.1515 +	      linkend="sec.hook.url"/> for more
 26.1516 +	    information.
 26.1517 +	  </para>
 26.1518 +	</listitem></itemizedlist>
 26.1519 +
 26.1520 +      <para>See also: <literal role="hook">incoming</literal> (section
 26.1521 +	<xref linkend="sec.hook.incoming"/>), <literal
 26.1522 +	  role="hook">prechangegroup</literal> (section <xref
 26.1523 +	  linkend="sec.hook.prechangegroup"/>), <literal
 26.1524 +	  role="hook">pretxnchangegroup</literal> (section <xref
 26.1525 +	  linkend="sec.hook.pretxnchangegroup"/>)
 26.1526 +      </para>
 26.1527 +
 26.1528 +    </sect2>
 26.1529 +    <sect2 id="sec.hook.commit">
 26.1530 +      <title><literal role="hook">commit</literal>&emdash;after a new
 26.1531 +	changeset is created</title>
 26.1532 +
 26.1533 +      <para>This hook is run after a new changeset has been created.
 26.1534 +      </para>
 26.1535 +
 26.1536 +      <para>Parameters to this hook:
 26.1537 +      </para>
 26.1538 +      <itemizedlist>
 26.1539 +	<listitem><para><literal>node</literal>: A changeset ID.  The
 26.1540 +	    changeset ID of the newly committed changeset.
 26.1541 +	  </para>
 26.1542 +	</listitem>
 26.1543 +	<listitem><para><literal>parent1</literal>: A changeset ID.
 26.1544 +	    The changeset ID of the first parent of the newly
 26.1545 +	    committed changeset.
 26.1546 +	  </para>
 26.1547 +	</listitem>
 26.1548 +	<listitem><para><literal>parent2</literal>: A changeset ID.
 26.1549 +	    The changeset ID of the second parent of the newly
 26.1550 +	    committed changeset.
 26.1551 +	  </para>
 26.1552 +	</listitem></itemizedlist>
 26.1553 +
 26.1554 +      <para>See also: <literal role="hook">precommit</literal>
 26.1555 +	(section <xref linkend="sec.hook.precommit"/>), <literal
 26.1556 +	  role="hook">pretxncommit</literal> (section <xref
 26.1557 +	  linkend="sec.hook.pretxncommit"/>)
 26.1558 +      </para>
 26.1559 +
 26.1560 +    </sect2>
 26.1561 +    <sect2 id="sec.hook.incoming">
 26.1562 +      <title><literal role="hook">incoming</literal>&emdash;after one
 26.1563 +	remote changeset is added</title>
 26.1564 +
 26.1565 +      <para>This hook is run after a pre-existing changeset has been
 26.1566 +	added to the repository, for example via a <command
 26.1567 +	  role="hg-cmd">hg push</command>.  If a group of changesets
 26.1568 +	was added in a single operation, this hook is called once for
 26.1569 +	each added changeset.
 26.1570 +      </para>
 26.1571 +
 26.1572 +      <para>You can use this hook for the same purposes as the
 26.1573 +	<literal role="hook">changegroup</literal> hook (section <xref
 26.1574 +	  linkend="sec.hook.changegroup"/>); it's simply
 26.1575 +	more convenient sometimes to run a hook once per group of
 26.1576 +	changesets, while other times it's handier once per changeset.
 26.1577 +      </para>
 26.1578 +
 26.1579 +      <para>Parameters to this hook:
 26.1580 +      </para>
 26.1581 +      <itemizedlist>
 26.1582 +	<listitem><para><literal>node</literal>: A changeset ID.  The
 26.1583 +	    ID of the newly added changeset.
 26.1584 +	  </para>
 26.1585 +	</listitem>
 26.1586 +	<listitem><para><literal>source</literal>: A string.  The
 26.1587 +	    source of these changes.  See section <xref
 26.1588 +	      linkend="sec.hook.sources"/> for details.
 26.1589 +	  </para>
 26.1590 +	</listitem>
 26.1591 +	<listitem><para><literal>url</literal>: A URL.  The location
 26.1592 +	    of the remote repository, if known.  See section <xref
 26.1593 +	      linkend="sec.hook.url"/> for more
 26.1594 +	    information.
 26.1595 +	  </para>
 26.1596 +	</listitem></itemizedlist>
 26.1597 +
 26.1598 +      <para>See also: <literal role="hook">changegroup</literal>
 26.1599 +	(section <xref linkend="sec.hook.changegroup"/>) <literal
 26.1600 +	  role="hook">prechangegroup</literal> (section <xref
 26.1601 +	  linkend="sec.hook.prechangegroup"/>), <literal
 26.1602 +	  role="hook">pretxnchangegroup</literal> (section <xref
 26.1603 +	  linkend="sec.hook.pretxnchangegroup"/>)
 26.1604 +      </para>
 26.1605 +
 26.1606 +    </sect2>
 26.1607 +    <sect2 id="sec.hook.outgoing">
 26.1608 +      <title><literal role="hook">outgoing</literal>&emdash;after
 26.1609 +	changesets are propagated</title>
 26.1610 +
 26.1611 +      <para>This hook is run after a group of changesets has been
 26.1612 +	propagated out of this repository, for example by a <command
 26.1613 +	  role="hg-cmd">hg push</command> or <command role="hg-cmd">hg
 26.1614 +	  bundle</command> command.
 26.1615 +      </para>
 26.1616 +
 26.1617 +      <para>One possible use for this hook is to notify administrators
 26.1618 +	that changes have been pulled.
 26.1619 +      </para>
 26.1620 +
 26.1621 +      <para>Parameters to this hook:
 26.1622 +      </para>
 26.1623 +      <itemizedlist>
 26.1624 +	<listitem><para><literal>node</literal>: A changeset ID.  The
 26.1625 +	    changeset ID of the first changeset of the group that was
 26.1626 +	    sent.
 26.1627 +	  </para>
 26.1628 +	</listitem>
 26.1629 +	<listitem><para><literal>source</literal>: A string.  The
 26.1630 +	    source of the of the operation (see section <xref
 26.1631 +	      linkend="sec.hook.sources"/>).  If a remote
 26.1632 +	    client pulled changes from this repository,
 26.1633 +	    <literal>source</literal> will be
 26.1634 +	    <literal>serve</literal>.  If the client that obtained
 26.1635 +	    changes from this repository was local,
 26.1636 +	    <literal>source</literal> will be
 26.1637 +	    <literal>bundle</literal>, <literal>pull</literal>, or
 26.1638 +	    <literal>push</literal>, depending on the operation the
 26.1639 +	    client performed.
 26.1640 +	  </para>
 26.1641 +	</listitem>
 26.1642 +	<listitem><para><literal>url</literal>: A URL.  The location
 26.1643 +	    of the remote repository, if known.  See section <xref
 26.1644 +	      linkend="sec.hook.url"/> for more
 26.1645 +	    information.
 26.1646 +	  </para>
 26.1647 +	</listitem></itemizedlist>
 26.1648 +
 26.1649 +      <para>See also: <literal role="hook">preoutgoing</literal>
 26.1650 +	(section <xref linkend="sec.hook.preoutgoing"/>)
 26.1651 +      </para>
 26.1652 +
 26.1653 +    </sect2>
 26.1654 +    <sect2 id="sec.hook.prechangegroup">
 26.1655 +      <title><literal
 26.1656 +	  role="hook">prechangegroup</literal>&emdash;before starting
 26.1657 +	to add remote changesets</title>
 26.1658 +
 26.1659 +      <para>This controlling hook is run before Mercurial begins to
 26.1660 +	add a group of changesets from another repository.
 26.1661 +      </para>
 26.1662 +
 26.1663 +      <para>This hook does not have any information about the
 26.1664 +	changesets to be added, because it is run before transmission
 26.1665 +	of those changesets is allowed to begin.  If this hook fails,
 26.1666 +	the changesets will not be transmitted.
 26.1667 +      </para>
 26.1668 +
 26.1669 +      <para>One use for this hook is to prevent external changes from
 26.1670 +	being added to a repository.  For example, you could use this
 26.1671 +	to <quote>freeze</quote> a server-hosted branch temporarily or
 26.1672 +	permanently so that users cannot push to it, while still
 26.1673 +	allowing a local administrator to modify the repository.
 26.1674 +      </para>
 26.1675 +
 26.1676 +      <para>Parameters to this hook:
 26.1677 +      </para>
 26.1678 +      <itemizedlist>
 26.1679 +	<listitem><para><literal>source</literal>: A string.  The
 26.1680 +	    source of these changes.  See section <xref
 26.1681 +	      linkend="sec.hook.sources"/> for details.
 26.1682 +	  </para>
 26.1683 +	</listitem>
 26.1684 +	<listitem><para><literal>url</literal>: A URL.  The location
 26.1685 +	    of the remote repository, if known.  See section <xref
 26.1686 +	      linkend="sec.hook.url"/> for more
 26.1687 +	    information.
 26.1688 +	  </para>
 26.1689 +	</listitem></itemizedlist>
 26.1690 +
 26.1691 +      <para>See also: <literal role="hook">changegroup</literal>
 26.1692 +	(section <xref linkend="sec.hook.changegroup"/>), <literal
 26.1693 +	  role="hook">incoming</literal> (section <xref
 26.1694 +	  linkend="sec.hook.incoming"/>), , <literal
 26.1695 +	  role="hook">pretxnchangegroup</literal> (section <xref
 26.1696 +	  linkend="sec.hook.pretxnchangegroup"/>)
 26.1697 +      </para>
 26.1698 +
 26.1699 +    </sect2>
 26.1700 +    <sect2 id="sec.hook.precommit">
 26.1701 +      <title><literal role="hook">precommit</literal>&emdash;before
 26.1702 +	starting to commit a changeset</title>
 26.1703 +
 26.1704 +      <para>This hook is run before Mercurial begins to commit a new
 26.1705 +	changeset. It is run before Mercurial has any of the metadata
 26.1706 +	for the commit, such as the files to be committed, the commit
 26.1707 +	message, or the commit date.
 26.1708 +      </para>
 26.1709 +
 26.1710 +      <para>One use for this hook is to disable the ability to commit
 26.1711 +	new changesets, while still allowing incoming changesets.
 26.1712 +	Another is to run a build or test, and only allow the commit
 26.1713 +	to begin if the build or test succeeds.
 26.1714 +      </para>
 26.1715 +
 26.1716 +      <para>Parameters to this hook:
 26.1717 +      </para>
 26.1718 +      <itemizedlist>
 26.1719 +	<listitem><para><literal>parent1</literal>: A changeset ID.
 26.1720 +	    The changeset ID of the first parent of the working
 26.1721 +	    directory.
 26.1722 +	  </para>
 26.1723 +	</listitem>
 26.1724 +	<listitem><para><literal>parent2</literal>: A changeset ID.
 26.1725 +	    The changeset ID of the second parent of the working
 26.1726 +	    directory.
 26.1727 +	  </para>
 26.1728 +	</listitem></itemizedlist>
 26.1729 +      <para>If the commit proceeds, the parents of the working
 26.1730 +	directory will become the parents of the new changeset.
 26.1731 +      </para>
 26.1732 +
 26.1733 +      <para>See also: <literal role="hook">commit</literal> (section
 26.1734 +	<xref linkend="sec.hook.commit"/>), <literal
 26.1735 +	  role="hook">pretxncommit</literal> (section <xref
 26.1736 +	  linkend="sec.hook.pretxncommit"/>)
 26.1737 +      </para>
 26.1738 +
 26.1739 +    </sect2>
 26.1740 +    <sect2 id="sec.hook.preoutgoing">
 26.1741 +      <title><literal role="hook">preoutgoing</literal>&emdash;before
 26.1742 +	starting to propagate changesets</title>
 26.1743 +
 26.1744 +      <para>This hook is invoked before Mercurial knows the identities
 26.1745 +	of the changesets to be transmitted.
 26.1746 +      </para>
 26.1747 +
 26.1748 +      <para>One use for this hook is to prevent changes from being
 26.1749 +	transmitted to another repository.
 26.1750 +      </para>
 26.1751 +
 26.1752 +      <para>Parameters to this hook:
 26.1753 +      </para>
 26.1754 +      <itemizedlist>
 26.1755 +	<listitem><para><literal>source</literal>: A string.  The
 26.1756 +	    source of the operation that is attempting to obtain
 26.1757 +	    changes from this repository (see section <xref
 26.1758 +	      linkend="sec.hook.sources"/>).  See the documentation
 26.1759 +	    for the <literal>source</literal> parameter to the
 26.1760 +	    <literal role="hook">outgoing</literal> hook, in section
 26.1761 +	    <xref linkend="sec.hook.outgoing"/>, for possible values
 26.1762 +	    of
 26.1763 +	    this parameter.
 26.1764 +	  </para>
 26.1765 +	</listitem>
 26.1766 +	<listitem><para><literal>url</literal>: A URL.  The location
 26.1767 +	    of the remote repository, if known.  See section <xref
 26.1768 +	      linkend="sec.hook.url"/> for more
 26.1769 +	    information.
 26.1770 +	  </para>
 26.1771 +	</listitem></itemizedlist>
 26.1772 +
 26.1773 +      <para>See also: <literal role="hook">outgoing</literal> (section
 26.1774 +	<xref linkend="sec.hook.outgoing"/>)
 26.1775 +      </para>
 26.1776 +
 26.1777 +    </sect2>
 26.1778 +    <sect2 id="sec.hook.pretag">
 26.1779 +      <title><literal role="hook">pretag</literal>&emdash;before
 26.1780 +	tagging a changeset</title>
 26.1781 +
 26.1782 +      <para>This controlling hook is run before a tag is created.  If
 26.1783 +	the hook succeeds, creation of the tag proceeds.  If the hook
 26.1784 +	fails, the tag is not created.
 26.1785 +      </para>
 26.1786 +
 26.1787 +      <para>Parameters to this hook:
 26.1788 +      </para>
 26.1789 +      <itemizedlist>
 26.1790 +	<listitem><para><literal>local</literal>: A boolean.  Whether
 26.1791 +	    the tag is local to this repository instance (i.e. stored
 26.1792 +	    in <filename role="special">.hg/localtags</filename>) or
 26.1793 +	    managed by Mercurial (stored in <filename
 26.1794 +	      role="special">.hgtags</filename>).
 26.1795 +	  </para>
 26.1796 +	</listitem>
 26.1797 +	<listitem><para><literal>node</literal>: A changeset ID.  The
 26.1798 +	    ID of the changeset to be tagged.
 26.1799 +	  </para>
 26.1800 +	</listitem>
 26.1801 +	<listitem><para><literal>tag</literal>: A string.  The name of
 26.1802 +	    the tag to be created.
 26.1803 +	  </para>
 26.1804 +	</listitem></itemizedlist>
 26.1805 +
 26.1806 +      <para>If the tag to be created is revision-controlled, the
 26.1807 +	<literal role="hook">precommit</literal> and <literal
 26.1808 +	  role="hook">pretxncommit</literal> hooks (sections <xref
 26.1809 +	  linkend="sec.hook.commit"/> and <xref
 26.1810 +	  linkend="sec.hook.pretxncommit"/>) will also be run.
 26.1811 +      </para>
 26.1812 +
 26.1813 +      <para>See also: <literal role="hook">tag</literal> (section
 26.1814 +	<xref linkend="sec.hook.tag"/>)
 26.1815 +      </para>
 26.1816 +    </sect2>
 26.1817 +    <sect2 id="sec.hook.pretxnchangegroup">
 26.1818 +      <title><literal
 26.1819 +	  role="hook">pretxnchangegroup</literal>&emdash;before
 26.1820 +	completing addition of remote changesets</title>
 26.1821 +
 26.1822 +      <para>This controlling hook is run before a
 26.1823 +	transaction&emdash;that manages the addition of a group of new
 26.1824 +	changesets from outside the repository&emdash;completes.  If
 26.1825 +	the hook succeeds, the transaction completes, and all of the
 26.1826 +	changesets become permanent within this repository.  If the
 26.1827 +	hook fails, the transaction is rolled back, and the data for
 26.1828 +	the changesets is erased.
 26.1829 +      </para>
 26.1830 +
 26.1831 +      <para>This hook can access the metadata associated with the
 26.1832 +	almost-added changesets, but it should not do anything
 26.1833 +	permanent with this data. It must also not modify the working
 26.1834 +	directory.
 26.1835 +      </para>
 26.1836 +
 26.1837 +      <para>While this hook is running, if other Mercurial processes
 26.1838 +	access this repository, they will be able to see the
 26.1839 +	almost-added changesets as if they are permanent.  This may
 26.1840 +	lead to race conditions if you do not take steps to avoid
 26.1841 +	them.
 26.1842 +      </para>
 26.1843 +
 26.1844 +      <para>This hook can be used to automatically vet a group of
 26.1845 +	changesets.  If the hook fails, all of the changesets are
 26.1846 +	<quote>rejected</quote> when the transaction rolls back.
 26.1847 +      </para>
 26.1848 +
 26.1849 +      <para>Parameters to this hook:
 26.1850 +      </para>
 26.1851 +      <itemizedlist>
 26.1852 +	<listitem><para><literal>node</literal>: A changeset ID.  The
 26.1853 +	    changeset ID of the first changeset in the group that was
 26.1854 +	    added.  All changesets between this and
 26.1855 +	    <literal role="tag">tip</literal>,
 26.1856 +	    inclusive, were added by a single <command
 26.1857 +	      role="hg-cmd">hg pull</command>, <command
 26.1858 +	      role="hg-cmd">hg push</command> or <command
 26.1859 +	      role="hg-cmd">hg unbundle</command>.
 26.1860 +	  </para>
 26.1861 +	</listitem>
 26.1862 +	<listitem><para><literal>source</literal>: A string.  The
 26.1863 +	    source of these changes.  See section <xref
 26.1864 +	      linkend="sec.hook.sources"/> for details.
 26.1865 +	  </para>
 26.1866 +	</listitem>
 26.1867 +	<listitem><para><literal>url</literal>: A URL.  The location
 26.1868 +	    of the remote repository, if known.  See section <xref
 26.1869 +	      linkend="sec.hook.url"/> for more
 26.1870 +	    information.
 26.1871 +	  </para>
 26.1872 +	</listitem></itemizedlist>
 26.1873 +
 26.1874 +      <para>See also: <literal role="hook">changegroup</literal>
 26.1875 +	(section <xref linkend="sec.hook.changegroup"/>), <literal
 26.1876 +	  role="hook">incoming</literal> (section <xref
 26.1877 +	  linkend="sec.hook.incoming"/>), <literal
 26.1878 +	  role="hook">prechangegroup</literal> (section <xref
 26.1879 +	  linkend="sec.hook.prechangegroup"/>)
 26.1880 +      </para>
 26.1881 +
 26.1882 +    </sect2>
 26.1883 +    <sect2 id="sec.hook.pretxncommit">
 26.1884 +      <title><literal role="hook">pretxncommit</literal>&emdash;before
 26.1885 +	completing commit of new changeset</title>
 26.1886 +
 26.1887 +      <para>This controlling hook is run before a
 26.1888 +	transaction&emdash;that manages a new commit&emdash;completes.
 26.1889 +	If the hook succeeds, the transaction completes and the
 26.1890 +	changeset becomes permanent within this repository.  If the
 26.1891 +	hook fails, the transaction is rolled back, and the commit
 26.1892 +	data is erased.
 26.1893 +      </para>
 26.1894 +
 26.1895 +      <para>This hook can access the metadata associated with the
 26.1896 +	almost-new changeset, but it should not do anything permanent
 26.1897 +	with this data.  It must also not modify the working
 26.1898 +	directory.
 26.1899 +      </para>
 26.1900 +
 26.1901 +      <para>While this hook is running, if other Mercurial processes
 26.1902 +	access this repository, they will be able to see the
 26.1903 +	almost-new changeset as if it is permanent.  This may lead to
 26.1904 +	race conditions if you do not take steps to avoid them.
 26.1905 +      </para>
 26.1906 +
 26.1907 +      <para>Parameters to this hook:
 26.1908 +      </para>
 26.1909 +      <itemizedlist>
 26.1910 +	<listitem><para><literal>node</literal>: A changeset ID.  The
 26.1911 +	    changeset ID of the newly committed changeset.
 26.1912 +	  </para>
 26.1913 +	</listitem>
 26.1914 +	<listitem><para><literal>parent1</literal>: A changeset ID.
 26.1915 +	    The changeset ID of the first parent of the newly
 26.1916 +	    committed changeset.
 26.1917 +	  </para>
 26.1918 +	</listitem>
 26.1919 +	<listitem><para><literal>parent2</literal>: A changeset ID.
 26.1920 +	    The changeset ID of the second parent of the newly
 26.1921 +	    committed changeset.
 26.1922 +	  </para>
 26.1923 +	</listitem></itemizedlist>
 26.1924 +
 26.1925 +      <para>See also: <literal role="hook">precommit</literal>
 26.1926 +	(section <xref linkend="sec.hook.precommit"/>)
 26.1927 +      </para>
 26.1928 +
 26.1929 +    </sect2>
 26.1930 +    <sect2 id="sec.hook.preupdate">
 26.1931 +      <title><literal role="hook">preupdate</literal>&emdash;before
 26.1932 +	updating or merging working directory</title>
 26.1933 +
 26.1934 +      <para>This controlling hook is run before an update or merge of
 26.1935 +	the working directory begins.  It is run only if Mercurial's
 26.1936 +	normal pre-update checks determine that the update or merge
 26.1937 +	can proceed.  If the hook succeeds, the update or merge may
 26.1938 +	proceed; if it fails, the update or merge does not start.
 26.1939 +      </para>
 26.1940 +
 26.1941 +      <para>Parameters to this hook:
 26.1942 +      </para>
 26.1943 +      <itemizedlist>
 26.1944 +	<listitem><para><literal>parent1</literal>: A changeset ID.
 26.1945 +	    The ID of the parent that the working directory is to be
 26.1946 +	    updated to.  If the working directory is being merged, it
 26.1947 +	    will not change this parent.
 26.1948 +	  </para>
 26.1949 +	</listitem>
 26.1950 +	<listitem><para><literal>parent2</literal>: A changeset ID.
 26.1951 +	    Only set if the working directory is being merged.  The ID
 26.1952 +	    of the revision that the working directory is being merged
 26.1953 +	    with.
 26.1954 +	  </para>
 26.1955 +	</listitem></itemizedlist>
 26.1956 +
 26.1957 +      <para>See also: <literal role="hook">update</literal> (section
 26.1958 +	<xref linkend="sec.hook.update"/>)
 26.1959 +      </para>
 26.1960 +
 26.1961 +    </sect2>
 26.1962 +    <sect2 id="sec.hook.tag">
 26.1963 +      <title><literal role="hook">tag</literal>&emdash;after tagging a
 26.1964 +	changeset</title>
 26.1965 +
 26.1966 +      <para>This hook is run after a tag has been created.
 26.1967 +      </para>
 26.1968 +
 26.1969 +      <para>Parameters to this hook:
 26.1970 +      </para>
 26.1971 +      <itemizedlist>
 26.1972 +	<listitem><para><literal>local</literal>: A boolean.  Whether
 26.1973 +	    the new tag is local to this repository instance (i.e.
 26.1974 +	    stored in <filename
 26.1975 +	      role="special">.hg/localtags</filename>) or managed by
 26.1976 +	    Mercurial (stored in <filename
 26.1977 +	      role="special">.hgtags</filename>).
 26.1978 +	  </para>
 26.1979 +	</listitem>
 26.1980 +	<listitem><para><literal>node</literal>: A changeset ID.  The
 26.1981 +	    ID of the changeset that was tagged.
 26.1982 +	  </para>
 26.1983 +	</listitem>
 26.1984 +	<listitem><para><literal>tag</literal>: A string.  The name of
 26.1985 +	    the tag that was created.
 26.1986 +	  </para>
 26.1987 +	</listitem></itemizedlist>
 26.1988 +
 26.1989 +      <para>If the created tag is revision-controlled, the <literal
 26.1990 +	  role="hook">commit</literal> hook (section <xref
 26.1991 +	  linkend="sec.hook.commit"/>) is run before this hook.
 26.1992 +      </para>
 26.1993 +
 26.1994 +      <para>See also: <literal role="hook">pretag</literal> (section
 26.1995 +	<xref linkend="sec.hook.pretag"/>)
 26.1996 +      </para>
 26.1997 +
 26.1998 +    </sect2>
 26.1999 +    <sect2 id="sec.hook.update">
 26.2000 +      <title><literal role="hook">update</literal>&emdash;after
 26.2001 +	updating or merging working directory</title>
 26.2002 +
 26.2003 +      <para>This hook is run after an update or merge of the working
 26.2004 +	directory completes.  Since a merge can fail (if the external
 26.2005 +	<command>hgmerge</command> command fails to resolve conflicts
 26.2006 +	in a file), this hook communicates whether the update or merge
 26.2007 +	completed cleanly.
 26.2008 +      </para>
 26.2009 +
 26.2010 +      <itemizedlist>
 26.2011 +	<listitem><para><literal>error</literal>: A boolean.
 26.2012 +	    Indicates whether the update or merge completed
 26.2013 +	    successfully.
 26.2014 +	  </para>
 26.2015 +	</listitem>
 26.2016 +	<listitem><para><literal>parent1</literal>: A changeset ID.
 26.2017 +	    The ID of the parent that the working directory was
 26.2018 +	    updated to.  If the working directory was merged, it will
 26.2019 +	    not have changed this parent.
 26.2020 +	  </para>
 26.2021 +	</listitem>
 26.2022 +	<listitem><para><literal>parent2</literal>: A changeset ID.
 26.2023 +	    Only set if the working directory was merged.  The ID of
 26.2024 +	    the revision that the working directory was merged with.
 26.2025 +	  </para>
 26.2026 +	</listitem></itemizedlist>
 26.2027 +
 26.2028 +      <para>See also: <literal role="hook">preupdate</literal>
 26.2029 +	(section <xref linkend="sec.hook.preupdate"/>)
 26.2030 +      </para>
 26.2031 +
 26.2032 +    </sect2>
 26.2033 +  </sect1>
 26.2034 +</chapter>
 26.2035 +
 26.2036 +<!--
 26.2037 +local variables: 
 26.2038 +sgml-parent-document: ("00book.xml" "book" "chapter")
 26.2039 +end:
 26.2040 +-->
    27.1 --- a/en/ch09-undo.xml	Fri Mar 20 15:40:06 2009 +0800
    27.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.3 @@ -1,1083 +0,0 @@
    27.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    27.5 -
    27.6 -<chapter id="chap.undo">
    27.7 -  <?dbhtml filename="finding-and-fixing-mistakes.html"?>
    27.8 -  <title>Finding and fixing mistakes</title>
    27.9 -
   27.10 -  <para>To err might be human, but to really handle the consequences
   27.11 -    well takes a top-notch revision control system.  In this chapter,
   27.12 -    we'll discuss some of the techniques you can use when you find
   27.13 -    that a problem has crept into your project.  Mercurial has some
   27.14 -    highly capable features that will help you to isolate the sources
   27.15 -    of problems, and to handle them appropriately.</para>
   27.16 -
   27.17 -  <sect1>
   27.18 -    <title>Erasing local history</title>
   27.19 -
   27.20 -    <sect2>
   27.21 -      <title>The accidental commit</title>
   27.22 -
   27.23 -      <para>I have the occasional but persistent problem of typing
   27.24 -	rather more quickly than I can think, which sometimes results
   27.25 -	in me committing a changeset that is either incomplete or
   27.26 -	plain wrong.  In my case, the usual kind of incomplete
   27.27 -	changeset is one in which I've created a new source file, but
   27.28 -	forgotten to <command role="hg-cmd">hg add</command> it.  A
   27.29 -	<quote>plain wrong</quote> changeset is not as common, but no
   27.30 -	less annoying.</para>
   27.31 -
   27.32 -    </sect2>
   27.33 -    <sect2 id="sec.undo.rollback">
   27.34 -      <title>Rolling back a transaction</title>
   27.35 -
   27.36 -      <para>In section <xref linkend="sec.concepts.txn"/>, I mentioned
   27.37 -	that Mercurial treats each modification of a repository as a
   27.38 -	<emphasis>transaction</emphasis>.  Every time you commit a
   27.39 -	changeset or pull changes from another repository, Mercurial
   27.40 -	remembers what you did.  You can undo, or <emphasis>roll
   27.41 -	  back</emphasis>, exactly one of these actions using the
   27.42 -	<command role="hg-cmd">hg rollback</command> command.  (See
   27.43 -	section <xref linkend="sec.undo.rollback-after-push"/> for an
   27.44 -	important caveat about the use of this command.)</para>
   27.45 -
   27.46 -      <para>Here's a mistake that I often find myself making:
   27.47 -	committing a change in which I've created a new file, but
   27.48 -	forgotten to <command role="hg-cmd">hg add</command>
   27.49 -	it.</para>
   27.50 -
   27.51 -      &interaction.rollback.commit;
   27.52 -
   27.53 -      <para>Looking at the output of <command role="hg-cmd">hg
   27.54 -	  status</command> after the commit immediately confirms the
   27.55 -	error.</para>
   27.56 -
   27.57 -      &interaction.rollback.status;
   27.58 -
   27.59 -      <para>The commit captured the changes to the file
   27.60 -	<filename>a</filename>, but not the new file
   27.61 -	<filename>b</filename>.  If I were to push this changeset to a
   27.62 -	repository that I shared with a colleague, the chances are
   27.63 -	high that something in <filename>a</filename> would refer to
   27.64 -	<filename>b</filename>, which would not be present in their
   27.65 -	repository when they pulled my changes.  I would thus become
   27.66 -	the object of some indignation.</para>
   27.67 -
   27.68 -      <para>However, luck is with me&emdash;I've caught my error
   27.69 -	before I pushed the changeset.  I use the <command
   27.70 -	  role="hg-cmd">hg rollback</command> command, and Mercurial
   27.71 -	makes that last changeset vanish.</para>
   27.72 -
   27.73 -      &interaction.rollback.rollback;
   27.74 -
   27.75 -      <para>Notice that the changeset is no longer present in the
   27.76 -	repository's history, and the working directory once again
   27.77 -	thinks that the file <filename>a</filename> is modified.  The
   27.78 -	commit and rollback have left the working directory exactly as
   27.79 -	it was prior to the commit; the changeset has been completely
   27.80 -	erased.  I can now safely <command role="hg-cmd">hg
   27.81 -	  add</command> the file <filename>b</filename>, and rerun my
   27.82 -	commit.</para>
   27.83 -
   27.84 -      &interaction.rollback.add;
   27.85 -
   27.86 -    </sect2>
   27.87 -    <sect2>
   27.88 -      <title>The erroneous pull</title>
   27.89 -
   27.90 -      <para>It's common practice with Mercurial to maintain separate
   27.91 -	development branches of a project in different repositories.
   27.92 -	Your development team might have one shared repository for
   27.93 -	your project's <quote>0.9</quote> release, and another,
   27.94 -	containing different changes, for the <quote>1.0</quote>
   27.95 -	release.</para>
   27.96 -
   27.97 -      <para>Given this, you can imagine that the consequences could be
   27.98 -	messy if you had a local <quote>0.9</quote> repository, and
   27.99 -	accidentally pulled changes from the shared <quote>1.0</quote>
  27.100 -	repository into it.  At worst, you could be paying
  27.101 -	insufficient attention, and push those changes into the shared
  27.102 -	<quote>0.9</quote> tree, confusing your entire team (but don't
  27.103 -	worry, we'll return to this horror scenario later).  However,
  27.104 -	it's more likely that you'll notice immediately, because
  27.105 -	Mercurial will display the URL it's pulling from, or you will
  27.106 -	see it pull a suspiciously large number of changes into the
  27.107 -	repository.</para>
  27.108 -
  27.109 -      <para>The <command role="hg-cmd">hg rollback</command> command
  27.110 -	will work nicely to expunge all of the changesets that you
  27.111 -	just pulled.  Mercurial groups all changes from one <command
  27.112 -	  role="hg-cmd">hg pull</command> into a single transaction,
  27.113 -	so one <command role="hg-cmd">hg rollback</command> is all you
  27.114 -	need to undo this mistake.</para>
  27.115 -
  27.116 -    </sect2>
  27.117 -    <sect2 id="sec.undo.rollback-after-push">
  27.118 -      <title>Rolling back is useless once you've pushed</title>
  27.119 -
  27.120 -      <para>The value of the <command role="hg-cmd">hg
  27.121 -	  rollback</command> command drops to zero once you've pushed
  27.122 -	your changes to another repository.  Rolling back a change
  27.123 -	makes it disappear entirely, but <emphasis>only</emphasis> in
  27.124 -	the repository in which you perform the <command
  27.125 -	  role="hg-cmd">hg rollback</command>.  Because a rollback
  27.126 -	eliminates history, there's no way for the disappearance of a
  27.127 -	change to propagate between repositories.</para>
  27.128 -
  27.129 -      <para>If you've pushed a change to another
  27.130 -	repository&emdash;particularly if it's a shared
  27.131 -	repository&emdash;it has essentially <quote>escaped into the
  27.132 -	  wild,</quote> and you'll have to recover from your mistake
  27.133 -	in a different way.  What will happen if you push a changeset
  27.134 -	somewhere, then roll it back, then pull from the repository
  27.135 -	you pushed to, is that the changeset will reappear in your
  27.136 -	repository.</para>
  27.137 -
  27.138 -      <para>(If you absolutely know for sure that the change you want
  27.139 -	to roll back is the most recent change in the repository that
  27.140 -	you pushed to, <emphasis>and</emphasis> you know that nobody
  27.141 -	else could have pulled it from that repository, you can roll
  27.142 -	back the changeset there, too, but you really should really
  27.143 -	not rely on this working reliably.  If you do this, sooner or
  27.144 -	later a change really will make it into a repository that you
  27.145 -	don't directly control (or have forgotten about), and come
  27.146 -	back to bite you.)</para>
  27.147 -
  27.148 -    </sect2>
  27.149 -    <sect2>
  27.150 -      <title>You can only roll back once</title>
  27.151 -
  27.152 -      <para>Mercurial stores exactly one transaction in its
  27.153 -	transaction log; that transaction is the most recent one that
  27.154 -	occurred in the repository. This means that you can only roll
  27.155 -	back one transaction.  If you expect to be able to roll back
  27.156 -	one transaction, then its predecessor, this is not the
  27.157 -	behaviour you will get.</para>
  27.158 -
  27.159 -      &interaction.rollback.twice;
  27.160 -
  27.161 -      <para>Once you've rolled back one transaction in a repository,
  27.162 -	you can't roll back again in that repository until you perform
  27.163 -	another commit or pull.</para>
  27.164 -
  27.165 -    </sect2>
  27.166 -  </sect1>
  27.167 -  <sect1>
  27.168 -    <title>Reverting the mistaken change</title>
  27.169 -
  27.170 -    <para>If you make a modification to a file, and decide that you
  27.171 -      really didn't want to change the file at all, and you haven't
  27.172 -      yet committed your changes, the <command role="hg-cmd">hg
  27.173 -	revert</command> command is the one you'll need.  It looks at
  27.174 -      the changeset that's the parent of the working directory, and
  27.175 -      restores the contents of the file to their state as of that
  27.176 -      changeset. (That's a long-winded way of saying that, in the
  27.177 -      normal case, it undoes your modifications.)</para>
  27.178 -
  27.179 -    <para>Let's illustrate how the <command role="hg-cmd">hg
  27.180 -	revert</command> command works with yet another small example.
  27.181 -      We'll begin by modifying a file that Mercurial is already
  27.182 -      tracking.</para>
  27.183 -
  27.184 -    &interaction.daily.revert.modify;
  27.185 -
  27.186 -    <para>If we don't
  27.187 -      want that change, we can simply <command role="hg-cmd">hg
  27.188 -	revert</command> the file.</para>
  27.189 -
  27.190 -      &interaction.daily.revert.unmodify;
  27.191 -
  27.192 -    <para>The <command role="hg-cmd">hg revert</command> command
  27.193 -      provides us with an extra degree of safety by saving our
  27.194 -      modified file with a <filename>.orig</filename>
  27.195 -      extension.</para>
  27.196 -
  27.197 -    &interaction.daily.revert.status;
  27.198 -
  27.199 -    <para>Here is a summary of the cases that the <command
  27.200 -	role="hg-cmd">hg revert</command> command can deal with.  We
  27.201 -      will describe each of these in more detail in the section that
  27.202 -      follows.</para>
  27.203 -    <itemizedlist>
  27.204 -      <listitem><para>If you modify a file, it will restore the file
  27.205 -	  to its unmodified state.</para>
  27.206 -      </listitem>
  27.207 -      <listitem><para>If you <command role="hg-cmd">hg add</command> a
  27.208 -	  file, it will undo the <quote>added</quote> state of the
  27.209 -	  file, but leave the file itself untouched.</para>
  27.210 -      </listitem>
  27.211 -      <listitem><para>If you delete a file without telling Mercurial,
  27.212 -	  it will restore the file to its unmodified contents.</para>
  27.213 -      </listitem>
  27.214 -      <listitem><para>If you use the <command role="hg-cmd">hg
  27.215 -	    remove</command> command to remove a file, it will undo
  27.216 -	  the <quote>removed</quote> state of the file, and restore
  27.217 -	  the file to its unmodified contents.</para>
  27.218 -      </listitem></itemizedlist>
  27.219 -
  27.220 -    <sect2 id="sec.undo.mgmt">
  27.221 -      <title>File management errors</title>
  27.222 -
  27.223 -      <para>The <command role="hg-cmd">hg revert</command> command is
  27.224 -	useful for more than just modified files.  It lets you reverse
  27.225 -	the results of all of Mercurial's file management
  27.226 -	commands&emdash;<command role="hg-cmd">hg add</command>,
  27.227 -	<command role="hg-cmd">hg remove</command>, and so on.</para>
  27.228 -
  27.229 -      <para>If you <command role="hg-cmd">hg add</command> a file,
  27.230 -	then decide that in fact you don't want Mercurial to track it,
  27.231 -	use <command role="hg-cmd">hg revert</command> to undo the
  27.232 -	add.  Don't worry; Mercurial will not modify the file in any
  27.233 -	way.  It will just <quote>unmark</quote> the file.</para>
  27.234 -
  27.235 -      &interaction.daily.revert.add;
  27.236 -
  27.237 -      <para>Similarly, if you ask Mercurial to <command
  27.238 -	  role="hg-cmd">hg remove</command> a file, you can use
  27.239 -	<command role="hg-cmd">hg revert</command> to restore it to
  27.240 -	the contents it had as of the parent of the working directory.
  27.241 -	&interaction.daily.revert.remove; This works just as
  27.242 -	well for a file that you deleted by hand, without telling
  27.243 -	Mercurial (recall that in Mercurial terminology, this kind of
  27.244 -	file is called <quote>missing</quote>).</para>
  27.245 -
  27.246 -      &interaction.daily.revert.missing;
  27.247 -
  27.248 -      <para>If you revert a <command role="hg-cmd">hg copy</command>,
  27.249 -	the copied-to file remains in your working directory
  27.250 -	afterwards, untracked.  Since a copy doesn't affect the
  27.251 -	copied-from file in any way, Mercurial doesn't do anything
  27.252 -	with the copied-from file.</para>
  27.253 -
  27.254 -      &interaction.daily.revert.copy;
  27.255 -
  27.256 -      <sect3>
  27.257 -	<title>A slightly special case: reverting a rename</title>
  27.258 -
  27.259 -	<para>If you <command role="hg-cmd">hg rename</command> a
  27.260 -	  file, there is one small detail that you should remember.
  27.261 -	  When you <command role="hg-cmd">hg revert</command> a
  27.262 -	  rename, it's not enough to provide the name of the
  27.263 -	  renamed-to file, as you can see here.</para>
  27.264 -
  27.265 -	&interaction.daily.revert.rename;
  27.266 -
  27.267 -	<para>As you can see from the output of <command
  27.268 -	    role="hg-cmd">hg status</command>, the renamed-to file is
  27.269 -	  no longer identified as added, but the
  27.270 -	  renamed-<emphasis>from</emphasis> file is still removed!
  27.271 -	  This is counter-intuitive (at least to me), but at least
  27.272 -	  it's easy to deal with.</para>
  27.273 -
  27.274 -	&interaction.daily.revert.rename-orig;
  27.275 -
  27.276 -	<para>So remember, to revert a <command role="hg-cmd">hg
  27.277 -	    rename</command>, you must provide
  27.278 -	  <emphasis>both</emphasis> the source and destination
  27.279 -	  names.</para>
  27.280 -
  27.281 -	<para>% TODO: the output doesn't look like it will be
  27.282 -	  removed!</para>
  27.283 -
  27.284 -	<para>(By the way, if you rename a file, then modify the
  27.285 -	  renamed-to file, then revert both components of the rename,
  27.286 -	  when Mercurial restores the file that was removed as part of
  27.287 -	  the rename, it will be unmodified. If you need the
  27.288 -	  modifications in the renamed-to file to show up in the
  27.289 -	  renamed-from file, don't forget to copy them over.)</para>
  27.290 -
  27.291 -	<para>These fiddly aspects of reverting a rename arguably
  27.292 -	  constitute a small bug in Mercurial.</para>
  27.293 -
  27.294 -      </sect3>
  27.295 -    </sect2>
  27.296 -  </sect1>
  27.297 -  <sect1>
  27.298 -    <title>Dealing with committed changes</title>
  27.299 -
  27.300 -    <para>Consider a case where you have committed a change $a$, and
  27.301 -      another change $b$ on top of it; you then realise that change
  27.302 -      $a$ was incorrect.  Mercurial lets you <quote>back out</quote>
  27.303 -      an entire changeset automatically, and building blocks that let
  27.304 -      you reverse part of a changeset by hand.</para>
  27.305 -
  27.306 -    <para>Before you read this section, here's something to keep in
  27.307 -      mind: the <command role="hg-cmd">hg backout</command> command
  27.308 -      undoes changes by <emphasis>adding</emphasis> history, not by
  27.309 -      modifying or erasing it.  It's the right tool to use if you're
  27.310 -      fixing bugs, but not if you're trying to undo some change that
  27.311 -      has catastrophic consequences.  To deal with those, see section
  27.312 -      <xref linkend="sec.undo.aaaiiieee"/>.</para>
  27.313 -
  27.314 -    <sect2>
  27.315 -      <title>Backing out a changeset</title>
  27.316 -
  27.317 -      <para>The <command role="hg-cmd">hg backout</command> command
  27.318 -	lets you <quote>undo</quote> the effects of an entire
  27.319 -	changeset in an automated fashion.  Because Mercurial's
  27.320 -	history is immutable, this command <emphasis>does
  27.321 -	  not</emphasis> get rid of the changeset you want to undo.
  27.322 -	Instead, it creates a new changeset that
  27.323 -	<emphasis>reverses</emphasis> the effect of the to-be-undone
  27.324 -	changeset.</para>
  27.325 -
  27.326 -      <para>The operation of the <command role="hg-cmd">hg
  27.327 -	  backout</command> command is a little intricate, so let's
  27.328 -	illustrate it with some examples.  First, we'll create a
  27.329 -	repository with some simple changes.</para>
  27.330 -
  27.331 -      &interaction.backout.init;
  27.332 -
  27.333 -      <para>The <command role="hg-cmd">hg backout</command> command
  27.334 -	takes a single changeset ID as its argument; this is the
  27.335 -	changeset to back out.  Normally, <command role="hg-cmd">hg
  27.336 -	  backout</command> will drop you into a text editor to write
  27.337 -	a commit message, so you can record why you're backing the
  27.338 -	change out.  In this example, we provide a commit message on
  27.339 -	the command line using the <option
  27.340 -	  role="hg-opt-backout">-m</option> option.</para>
  27.341 -
  27.342 -    </sect2>
  27.343 -    <sect2>
  27.344 -      <title>Backing out the tip changeset</title>
  27.345 -
  27.346 -      <para>We're going to start by backing out the last changeset we
  27.347 -	committed.</para>
  27.348 -
  27.349 -      &interaction.backout.simple;
  27.350 -
  27.351 -      <para>You can see that the second line from
  27.352 -	<filename>myfile</filename> is no longer present.  Taking a
  27.353 -	look at the output of <command role="hg-cmd">hg log</command>
  27.354 -	gives us an idea of what the <command role="hg-cmd">hg
  27.355 -	  backout</command> command has done.
  27.356 -	&interaction.backout.simple.log; Notice that the new changeset
  27.357 -	that <command role="hg-cmd">hg backout</command> has created
  27.358 -	is a child of the changeset we backed out.  It's easier to see
  27.359 -	this in figure <xref
  27.360 -	  endterm="fig.undo.backout.caption" linkend="fig.undo.backout"/>,
  27.361 -	which presents a graphical
  27.362 -	view of the change history.  As you can see, the history is
  27.363 -	nice and linear.</para>
  27.364 -
  27.365 -      <informalfigure id="fig.undo.backout">
  27.366 -        <mediaobject>
  27.367 -          <imageobject><imagedata fileref="images/undo-simple.png"/>
  27.368 -          </imageobject>
  27.369 -          <textobject><phrase>XXX add text</phrase></textobject>
  27.370 -          <caption><para id="fig.undo.backout.caption">Backing out
  27.371 -            a change using the 
  27.372 -            <command role="hg-cmd">hg backout</command>
  27.373 -            command</para></caption>
  27.374 -      </mediaobject>
  27.375 -      </informalfigure>
  27.376 -
  27.377 -    </sect2>
  27.378 -    <sect2>
  27.379 -      <title>Backing out a non-tip change</title>
  27.380 -
  27.381 -      <para>If you want to back out a change other than the last one
  27.382 -	you committed, pass the <option
  27.383 -	  role="hg-opt-backout">--merge</option> option to the
  27.384 -	<command role="hg-cmd">hg backout</command> command.</para>
  27.385 -
  27.386 -      &interaction.backout.non-tip.clone;
  27.387 -
  27.388 -      <para>This makes backing out any changeset a
  27.389 -	<quote>one-shot</quote> operation that's usually simple and
  27.390 -	fast.</para>
  27.391 -
  27.392 -      &interaction.backout.non-tip.backout;
  27.393 -
  27.394 -      <para>If you take a look at the contents of
  27.395 -	<filename>myfile</filename> after the backout finishes, you'll
  27.396 -	see that the first and third changes are present, but not the
  27.397 -	second.</para>
  27.398 -
  27.399 -      &interaction.backout.non-tip.cat;
  27.400 -
  27.401 -      <para>As the graphical history in figure <xref
  27.402 -	  endterm="fig.undo.backout-non-tip.caption"
  27.403 -	  linkend="fig.undo.backout-non-tip"/> illustrates, Mercurial
  27.404 -	actually commits <emphasis>two</emphasis> changes in this kind
  27.405 -	of situation (the box-shaped nodes are the ones that Mercurial
  27.406 -	commits automatically).  Before Mercurial begins the backout
  27.407 -	process, it first remembers what the current parent of the
  27.408 -	working directory is.  It then backs out the target changeset,
  27.409 -	and commits that as a changeset.  Finally, it merges back to
  27.410 -	the previous parent of the working directory, and commits the
  27.411 -	result of the merge.</para>
  27.412 -
  27.413 -      <para>% TODO: to me it looks like mercurial doesn't commit the
  27.414 -	second merge automatically!</para>
  27.415 -
  27.416 -      <informalfigure id="fig.undo.backout-non-tip">
  27.417 -        <mediaobject>
  27.418 -          <imageobject><imagedata fileref="images/undo-non-tip.png"/>
  27.419 -          </imageobject>
  27.420 -          <textobject><phrase>XXX add text</phrase></textobject>
  27.421 -          <caption><para id="fig.undo.backout-non-tip.caption">Automated
  27.422 -            backout of a non-tip change using the
  27.423 -            <command role="hg-cmd">hg backout</command> command</para></caption>
  27.424 -        </mediaobject>
  27.425 -      </informalfigure>
  27.426 -
  27.427 -      <para>The result is that you end up <quote>back where you
  27.428 -	  were</quote>, only with some extra history that undoes the
  27.429 -	effect of the changeset you wanted to back out.</para>
  27.430 -
  27.431 -      <sect3>
  27.432 -	<title>Always use the <option
  27.433 -	    role="hg-opt-backout">--merge</option> option</title>
  27.434 -
  27.435 -	<para>In fact, since the <option
  27.436 -	    role="hg-opt-backout">--merge</option> option will do the
  27.437 -	  <quote>right thing</quote> whether or not the changeset
  27.438 -	  you're backing out is the tip (i.e. it won't try to merge if
  27.439 -	  it's backing out the tip, since there's no need), you should
  27.440 -	  <emphasis>always</emphasis> use this option when you run the
  27.441 -	  <command role="hg-cmd">hg backout</command> command.</para>
  27.442 -
  27.443 -      </sect3>
  27.444 -    </sect2>
  27.445 -    <sect2>
  27.446 -      <title>Gaining more control of the backout process</title>
  27.447 -
  27.448 -      <para>While I've recommended that you always use the <option
  27.449 -	  role="hg-opt-backout">--merge</option> option when backing
  27.450 -	out a change, the <command role="hg-cmd">hg backout</command>
  27.451 -	command lets you decide how to merge a backout changeset.
  27.452 -	Taking control of the backout process by hand is something you
  27.453 -	will rarely need to do, but it can be useful to understand
  27.454 -	what the <command role="hg-cmd">hg backout</command> command
  27.455 -	is doing for you automatically.  To illustrate this, let's
  27.456 -	clone our first repository, but omit the backout change that
  27.457 -	it contains.</para>
  27.458 -
  27.459 -      &interaction.backout.manual.clone;
  27.460 -
  27.461 -      <para>As with our
  27.462 -	earlier example, We'll commit a third changeset, then back out
  27.463 -	its parent, and see what happens.</para>
  27.464 -
  27.465 -      &interaction.backout.manual.backout;
  27.466 -
  27.467 -      <para>Our new changeset is again a descendant of the changeset
  27.468 -	we backout out; it's thus a new head, <emphasis>not</emphasis>
  27.469 -	a descendant of the changeset that was the tip.  The <command
  27.470 -	  role="hg-cmd">hg backout</command> command was quite
  27.471 -	explicit in telling us this.</para>
  27.472 -
  27.473 -      &interaction.backout.manual.log;
  27.474 -
  27.475 -      <para>Again, it's easier to see what has happened by looking at
  27.476 -	a graph of the revision history, in figure <xref
  27.477 -	  endterm="fig.undo.backout-manual.caption"
  27.478 -	  linkend="fig.undo.backout-manual"/>.  This makes it clear
  27.479 -	that when we use <command role="hg-cmd">hg backout</command>
  27.480 -	to back out a change other than the tip, Mercurial adds a new
  27.481 -	head to the repository (the change it committed is
  27.482 -	box-shaped).</para>
  27.483 -
  27.484 -      <informalfigure id="fig.undo.backout-manual">
  27.485 -        <mediaobject>
  27.486 -          <imageobject><imagedata fileref="images/undo-manual.png"/>
  27.487 -          </imageobject>
  27.488 -          <textobject><phrase>XXX add text</phrase></textobject>
  27.489 -          <caption><para id="fig.undo.backout-manual.caption">Backing out a
  27.490 -            change using the <command role="hg-cmd">hg backout</command>
  27.491 -            command</para></caption>
  27.492 -        </mediaobject>
  27.493 -      </informalfigure>
  27.494 -
  27.495 -      <para>After the <command role="hg-cmd">hg backout</command>
  27.496 -	command has completed, it leaves the new
  27.497 -	<quote>backout</quote> changeset as the parent of the working
  27.498 -	directory.</para>
  27.499 -
  27.500 -      &interaction.backout.manual.parents;
  27.501 -
  27.502 -      <para>Now we have two isolated sets of changes.</para>
  27.503 -
  27.504 -      &interaction.backout.manual.heads;
  27.505 -
  27.506 -      <para>Let's think about what we expect to see as the contents of
  27.507 -	<filename>myfile</filename> now.  The first change should be
  27.508 -	present, because we've never backed it out.  The second change
  27.509 -	should be missing, as that's the change we backed out.  Since
  27.510 -	the history graph shows the third change as a separate head,
  27.511 -	we <emphasis>don't</emphasis> expect to see the third change
  27.512 -	present in <filename>myfile</filename>.</para>
  27.513 -
  27.514 -      &interaction.backout.manual.cat;
  27.515 -
  27.516 -      <para>To get the third change back into the file, we just do a
  27.517 -	normal merge of our two heads.</para>
  27.518 -
  27.519 -      &interaction.backout.manual.merge;
  27.520 -
  27.521 -      <para>Afterwards, the graphical history of our repository looks
  27.522 -	like figure
  27.523 -	<xref endterm="fig.undo.backout-manual-merge.caption"
  27.524 -	  linkend="fig.undo.backout-manual-merge"/>.</para>
  27.525 -
  27.526 -      <informalfigure id="fig.undo.backout-manual-merge">
  27.527 -        <mediaobject>
  27.528 -          <imageobject><imagedata fileref="images/undo-manual-merge.png"/>
  27.529 -          </imageobject>
  27.530 -          <textobject><phrase>XXX add text</phrase></textobject>
  27.531 -          <caption><para id="fig.undo.backout-manual-merge.caption">Manually
  27.532 -            merging a backout change</para></caption>
  27.533 -        </mediaobject>
  27.534 -      </informalfigure>
  27.535 -
  27.536 -    </sect2>
  27.537 -    <sect2>
  27.538 -      <title>Why <command role="hg-cmd">hg backout</command> works as
  27.539 -	it does</title>
  27.540 -
  27.541 -      <para>Here's a brief description of how the <command
  27.542 -	  role="hg-cmd">hg backout</command> command works.</para>
  27.543 -      <orderedlist>
  27.544 -	<listitem><para>It ensures that the working directory is
  27.545 -	    <quote>clean</quote>, i.e. that the output of <command
  27.546 -	      role="hg-cmd">hg status</command> would be empty.</para>
  27.547 -	</listitem>
  27.548 -	<listitem><para>It remembers the current parent of the working
  27.549 -	    directory.  Let's call this changeset
  27.550 -	    <literal>orig</literal></para>
  27.551 -	</listitem>
  27.552 -	<listitem><para>It does the equivalent of a <command
  27.553 -	      role="hg-cmd">hg update</command> to sync the working
  27.554 -	    directory to the changeset you want to back out.  Let's
  27.555 -	    call this changeset <literal>backout</literal></para>
  27.556 -	</listitem>
  27.557 -	<listitem><para>It finds the parent of that changeset.  Let's
  27.558 -	    call that changeset <literal>parent</literal>.</para>
  27.559 -	</listitem>
  27.560 -	<listitem><para>For each file that the
  27.561 -	    <literal>backout</literal> changeset affected, it does the
  27.562 -	    equivalent of a <command role="hg-cmd">hg revert -r
  27.563 -	      parent</command> on that file, to restore it to the
  27.564 -	    contents it had before that changeset was
  27.565 -	    committed.</para>
  27.566 -	</listitem>
  27.567 -	<listitem><para>It commits the result as a new changeset.
  27.568 -	    This changeset has <literal>backout</literal> as its
  27.569 -	    parent.</para>
  27.570 -	</listitem>
  27.571 -	<listitem><para>If you specify <option
  27.572 -	      role="hg-opt-backout">--merge</option> on the command
  27.573 -	    line, it merges with <literal>orig</literal>, and commits
  27.574 -	    the result of the merge.</para>
  27.575 -	</listitem></orderedlist>
  27.576 -
  27.577 -      <para>An alternative way to implement the <command
  27.578 -	  role="hg-cmd">hg backout</command> command would be to
  27.579 -	<command role="hg-cmd">hg export</command> the
  27.580 -	to-be-backed-out changeset as a diff, then use the <option
  27.581 -	  role="cmd-opt-patch">--reverse</option> option to the
  27.582 -	<command>patch</command> command to reverse the effect of the
  27.583 -	change without fiddling with the working directory.  This
  27.584 -	sounds much simpler, but it would not work nearly as
  27.585 -	well.</para>
  27.586 -
  27.587 -      <para>The reason that <command role="hg-cmd">hg
  27.588 -	  backout</command> does an update, a commit, a merge, and
  27.589 -	another commit is to give the merge machinery the best chance
  27.590 -	to do a good job when dealing with all the changes
  27.591 -	<emphasis>between</emphasis> the change you're backing out and
  27.592 -	the current tip.</para>
  27.593 -
  27.594 -      <para>If you're backing out a changeset that's 100 revisions
  27.595 -	back in your project's history, the chances that the
  27.596 -	<command>patch</command> command will be able to apply a
  27.597 -	reverse diff cleanly are not good, because intervening changes
  27.598 -	are likely to have <quote>broken the context</quote> that
  27.599 -	<command>patch</command> uses to determine whether it can
  27.600 -	apply a patch (if this sounds like gibberish, see <xref
  27.601 -	  linkend="sec.mq.patch"/> for a
  27.602 -	discussion of the <command>patch</command> command).  Also,
  27.603 -	Mercurial's merge machinery will handle files and directories
  27.604 -	being renamed, permission changes, and modifications to binary
  27.605 -	files, none of which <command>patch</command> can deal
  27.606 -	with.</para>
  27.607 -
  27.608 -    </sect2>
  27.609 -  </sect1>
  27.610 -  <sect1 id="sec.undo.aaaiiieee">
  27.611 -    <title>Changes that should never have been</title>
  27.612 -
  27.613 -    <para>Most of the time, the <command role="hg-cmd">hg
  27.614 -	backout</command> command is exactly what you need if you want
  27.615 -      to undo the effects of a change.  It leaves a permanent record
  27.616 -      of exactly what you did, both when committing the original
  27.617 -      changeset and when you cleaned up after it.</para>
  27.618 -
  27.619 -    <para>On rare occasions, though, you may find that you've
  27.620 -      committed a change that really should not be present in the
  27.621 -      repository at all.  For example, it would be very unusual, and
  27.622 -      usually considered a mistake, to commit a software project's
  27.623 -      object files as well as its source files.  Object files have
  27.624 -      almost no intrinsic value, and they're <emphasis>big</emphasis>,
  27.625 -      so they increase the size of the repository and the amount of
  27.626 -      time it takes to clone or pull changes.</para>
  27.627 -
  27.628 -    <para>Before I discuss the options that you have if you commit a
  27.629 -      <quote>brown paper bag</quote> change (the kind that's so bad
  27.630 -      that you want to pull a brown paper bag over your head), let me
  27.631 -      first discuss some approaches that probably won't work.</para>
  27.632 -
  27.633 -    <para>Since Mercurial treats history as accumulative&emdash;every
  27.634 -      change builds on top of all changes that preceded it&emdash;you
  27.635 -      generally can't just make disastrous changes disappear.  The one
  27.636 -      exception is when you've just committed a change, and it hasn't
  27.637 -      been pushed or pulled into another repository.  That's when you
  27.638 -      can safely use the <command role="hg-cmd">hg rollback</command>
  27.639 -      command, as I detailed in section <xref
  27.640 -	linkend="sec.undo.rollback"/>.</para>
  27.641 -
  27.642 -    <para>After you've pushed a bad change to another repository, you
  27.643 -      <emphasis>could</emphasis> still use <command role="hg-cmd">hg
  27.644 -	rollback</command> to make your local copy of the change
  27.645 -      disappear, but it won't have the consequences you want.  The
  27.646 -      change will still be present in the remote repository, so it
  27.647 -      will reappear in your local repository the next time you
  27.648 -      pull.</para>
  27.649 -
  27.650 -    <para>If a situation like this arises, and you know which
  27.651 -      repositories your bad change has propagated into, you can
  27.652 -      <emphasis>try</emphasis> to get rid of the changeefrom
  27.653 -      <emphasis>every</emphasis> one of those repositories.  This is,
  27.654 -      of course, not a satisfactory solution: if you miss even a
  27.655 -      single repository while you're expunging, the change is still
  27.656 -      <quote>in the wild</quote>, and could propagate further.</para>
  27.657 -
  27.658 -    <para>If you've committed one or more changes
  27.659 -      <emphasis>after</emphasis> the change that you'd like to see
  27.660 -      disappear, your options are further reduced. Mercurial doesn't
  27.661 -      provide a way to <quote>punch a hole</quote> in history, leaving
  27.662 -      changesets intact.</para>
  27.663 -
  27.664 -    <para>XXX This needs filling out.  The
  27.665 -      <literal>hg-replay</literal> script in the
  27.666 -      <literal>examples</literal> directory works, but doesn't handle
  27.667 -      merge changesets.  Kind of an important omission.</para>
  27.668 -
  27.669 -    <sect2>
  27.670 -      <title>Protect yourself from <quote>escaped</quote>
  27.671 -	changes</title>
  27.672 -
  27.673 -      <para>If you've committed some changes to your local repository
  27.674 -	and they've been pushed or pulled somewhere else, this isn't
  27.675 -	necessarily a disaster.  You can protect yourself ahead of
  27.676 -	time against some classes of bad changeset.  This is
  27.677 -	particularly easy if your team usually pulls changes from a
  27.678 -	central repository.</para>
  27.679 -
  27.680 -      <para>By configuring some hooks on that repository to validate
  27.681 -	incoming changesets (see chapter <xref linkend="chap.hook"/>),
  27.682 -	you can
  27.683 -	automatically prevent some kinds of bad changeset from being
  27.684 -	pushed to the central repository at all.  With such a
  27.685 -	configuration in place, some kinds of bad changeset will
  27.686 -	naturally tend to <quote>die out</quote> because they can't
  27.687 -	propagate into the central repository.  Better yet, this
  27.688 -	happens without any need for explicit intervention.</para>
  27.689 -
  27.690 -      <para>For instance, an incoming change hook that verifies that a
  27.691 -	changeset will actually compile can prevent people from
  27.692 -	inadvertantly <quote>breaking the build</quote>.</para>
  27.693 -
  27.694 -    </sect2>
  27.695 -  </sect1>
  27.696 -  <sect1 id="sec.undo.bisect">
  27.697 -    <title>Finding the source of a bug</title>
  27.698 -
  27.699 -    <para>While it's all very well to be able to back out a changeset
  27.700 -      that introduced a bug, this requires that you know which
  27.701 -      changeset to back out.  Mercurial provides an invaluable
  27.702 -      command, called <command role="hg-cmd">hg bisect</command>, that
  27.703 -      helps you to automate this process and accomplish it very
  27.704 -      efficiently.</para>
  27.705 -
  27.706 -    <para>The idea behind the <command role="hg-cmd">hg
  27.707 -	bisect</command> command is that a changeset has introduced
  27.708 -      some change of behaviour that you can identify with a simple
  27.709 -      binary test.  You don't know which piece of code introduced the
  27.710 -      change, but you know how to test for the presence of the bug.
  27.711 -      The <command role="hg-cmd">hg bisect</command> command uses your
  27.712 -      test to direct its search for the changeset that introduced the
  27.713 -      code that caused the bug.</para>
  27.714 -
  27.715 -    <para>Here are a few scenarios to help you understand how you
  27.716 -      might apply this command.</para>
  27.717 -    <itemizedlist>
  27.718 -      <listitem><para>The most recent version of your software has a
  27.719 -	  bug that you remember wasn't present a few weeks ago, but
  27.720 -	  you don't know when it was introduced.  Here, your binary
  27.721 -	  test checks for the presence of that bug.</para>
  27.722 -      </listitem>
  27.723 -      <listitem><para>You fixed a bug in a rush, and now it's time to
  27.724 -	  close the entry in your team's bug database.  The bug
  27.725 -	  database requires a changeset ID when you close an entry,
  27.726 -	  but you don't remember which changeset you fixed the bug in.
  27.727 -	  Once again, your binary test checks for the presence of the
  27.728 -	  bug.</para>
  27.729 -      </listitem>
  27.730 -      <listitem><para>Your software works correctly, but runs 15%
  27.731 -	  slower than the last time you measured it.  You want to know
  27.732 -	  which changeset introduced the performance regression.  In
  27.733 -	  this case, your binary test measures the performance of your
  27.734 -	  software, to see whether it's <quote>fast</quote> or
  27.735 -	  <quote>slow</quote>.</para>
  27.736 -      </listitem>
  27.737 -      <listitem><para>The sizes of the components of your project that
  27.738 -	  you ship exploded recently, and you suspect that something
  27.739 -	  changed in the way you build your project.</para>
  27.740 -      </listitem></itemizedlist>
  27.741 -
  27.742 -    <para>From these examples, it should be clear that the <command
  27.743 -	role="hg-cmd">hg bisect</command> command is not useful only
  27.744 -      for finding the sources of bugs.  You can use it to find any
  27.745 -      <quote>emergent property</quote> of a repository (anything that
  27.746 -      you can't find from a simple text search of the files in the
  27.747 -      tree) for which you can write a binary test.</para>
  27.748 -
  27.749 -    <para>We'll introduce a little bit of terminology here, just to
  27.750 -      make it clear which parts of the search process are your
  27.751 -      responsibility, and which are Mercurial's.  A
  27.752 -      <emphasis>test</emphasis> is something that
  27.753 -      <emphasis>you</emphasis> run when <command role="hg-cmd">hg
  27.754 -	bisect</command> chooses a changeset.  A
  27.755 -      <emphasis>probe</emphasis> is what <command role="hg-cmd">hg
  27.756 -	bisect</command> runs to tell whether a revision is good.
  27.757 -      Finally, we'll use the word <quote>bisect</quote>, as both a
  27.758 -      noun and a verb, to stand in for the phrase <quote>search using
  27.759 -	the <command role="hg-cmd">hg bisect</command>
  27.760 -	command</quote>.</para>
  27.761 -
  27.762 -    <para>One simple way to automate the searching process would be
  27.763 -      simply to probe every changeset.  However, this scales poorly.
  27.764 -      If it took ten minutes to test a single changeset, and you had
  27.765 -      10,000 changesets in your repository, the exhaustive approach
  27.766 -      would take on average 35 <emphasis>days</emphasis> to find the
  27.767 -      changeset that introduced a bug.  Even if you knew that the bug
  27.768 -      was introduced by one of the last 500 changesets, and limited
  27.769 -      your search to those, you'd still be looking at over 40 hours to
  27.770 -      find the changeset that introduced your bug.</para>
  27.771 -
  27.772 -    <para>What the <command role="hg-cmd">hg bisect</command> command
  27.773 -      does is use its knowledge of the <quote>shape</quote> of your
  27.774 -      project's revision history to perform a search in time
  27.775 -      proportional to the <emphasis>logarithm</emphasis> of the number
  27.776 -      of changesets to check (the kind of search it performs is called
  27.777 -      a dichotomic search).  With this approach, searching through
  27.778 -      10,000 changesets will take less than three hours, even at ten
  27.779 -      minutes per test (the search will require about 14 tests).
  27.780 -      Limit your search to the last hundred changesets, and it will
  27.781 -      take only about an hour (roughly seven tests).</para>
  27.782 -
  27.783 -    <para>The <command role="hg-cmd">hg bisect</command> command is
  27.784 -      aware of the <quote>branchy</quote> nature of a Mercurial
  27.785 -      project's revision history, so it has no problems dealing with
  27.786 -      branches, merges, or multiple heads in a repository.  It can
  27.787 -      prune entire branches of history with a single probe, which is
  27.788 -      how it operates so efficiently.</para>
  27.789 -
  27.790 -    <sect2>
  27.791 -      <title>Using the <command role="hg-cmd">hg bisect</command>
  27.792 -	command</title>
  27.793 -
  27.794 -      <para>Here's an example of <command role="hg-cmd">hg
  27.795 -	  bisect</command> in action.</para>
  27.796 -
  27.797 -      <note>
  27.798 -	<para>  In versions 0.9.5 and earlier of Mercurial, <command
  27.799 -	    role="hg-cmd">hg bisect</command> was not a core command:
  27.800 -	  it was distributed with Mercurial as an extension. This
  27.801 -	  section describes the built-in command, not the old
  27.802 -	  extension.</para>
  27.803 -      </note>
  27.804 -
  27.805 -      <para>Now let's create a repository, so that we can try out the
  27.806 -	<command role="hg-cmd">hg bisect</command> command in
  27.807 -	isolation.</para>
  27.808 -
  27.809 -      &interaction.bisect.init;
  27.810 -
  27.811 -      <para>We'll simulate a project that has a bug in it in a
  27.812 -	simple-minded way: create trivial changes in a loop, and
  27.813 -	nominate one specific change that will have the
  27.814 -	<quote>bug</quote>.  This loop creates 35 changesets, each
  27.815 -	adding a single file to the repository. We'll represent our
  27.816 -	<quote>bug</quote> with a file that contains the text <quote>i
  27.817 -	  have a gub</quote>.</para>
  27.818 -
  27.819 -      &interaction.bisect.commits;
  27.820 -
  27.821 -      <para>The next thing that we'd like to do is figure out how to
  27.822 -	use the <command role="hg-cmd">hg bisect</command> command.
  27.823 -	We can use Mercurial's normal built-in help mechanism for
  27.824 -	this.</para>
  27.825 -
  27.826 -      &interaction.bisect.help;
  27.827 -
  27.828 -      <para>The <command role="hg-cmd">hg bisect</command> command
  27.829 -	works in steps.  Each step proceeds as follows.</para>
  27.830 -      <orderedlist>
  27.831 -	<listitem><para>You run your binary test.</para>
  27.832 -	  <itemizedlist>
  27.833 -	    <listitem><para>If the test succeeded, you tell <command
  27.834 -		  role="hg-cmd">hg bisect</command> by running the
  27.835 -		<command role="hg-cmd">hg bisect good</command>
  27.836 -		command.</para>
  27.837 -	    </listitem>
  27.838 -	    <listitem><para>If it failed, run the <command
  27.839 -		  role="hg-cmd">hg bisect bad</command>
  27.840 -		command.</para></listitem></itemizedlist>
  27.841 -	</listitem>
  27.842 -	<listitem><para>The command uses your information to decide
  27.843 -	    which changeset to test next.</para>
  27.844 -	</listitem>
  27.845 -	<listitem><para>It updates the working directory to that
  27.846 -	    changeset, and the process begins again.</para>
  27.847 -	</listitem></orderedlist>
  27.848 -      <para>The process ends when <command role="hg-cmd">hg
  27.849 -	  bisect</command> identifies a unique changeset that marks
  27.850 -	the point where your test transitioned from
  27.851 -	<quote>succeeding</quote> to <quote>failing</quote>.</para>
  27.852 -
  27.853 -      <para>To start the search, we must run the <command
  27.854 -	  role="hg-cmd">hg bisect --reset</command> command.</para>
  27.855 -
  27.856 -      &interaction.bisect.search.init;
  27.857 -
  27.858 -      <para>In our case, the binary test we use is simple: we check to
  27.859 -	see if any file in the repository contains the string <quote>i
  27.860 -	  have a gub</quote>.  If it does, this changeset contains the
  27.861 -	change that <quote>caused the bug</quote>.  By convention, a
  27.862 -	changeset that has the property we're searching for is
  27.863 -	<quote>bad</quote>, while one that doesn't is
  27.864 -	<quote>good</quote>.</para>
  27.865 -
  27.866 -      <para>Most of the time, the revision to which the working
  27.867 -	directory is synced (usually the tip) already exhibits the
  27.868 -	problem introduced by the buggy change, so we'll mark it as
  27.869 -	<quote>bad</quote>.</para>
  27.870 -
  27.871 -      &interaction.bisect.search.bad-init;
  27.872 -
  27.873 -      <para>Our next task is to nominate a changeset that we know
  27.874 -	<emphasis>doesn't</emphasis> have the bug; the <command
  27.875 -	  role="hg-cmd">hg bisect</command> command will
  27.876 -	<quote>bracket</quote> its search between the first pair of
  27.877 -	good and bad changesets.  In our case, we know that revision
  27.878 -	10 didn't have the bug.  (I'll have more words about choosing
  27.879 -	the first <quote>good</quote> changeset later.)</para>
  27.880 -
  27.881 -      &interaction.bisect.search.good-init;
  27.882 -
  27.883 -      <para>Notice that this command printed some output.</para>
  27.884 -      <itemizedlist>
  27.885 -	<listitem><para>It told us how many changesets it must
  27.886 -	    consider before it can identify the one that introduced
  27.887 -	    the bug, and how many tests that will require.</para>
  27.888 -	</listitem>
  27.889 -	<listitem><para>It updated the working directory to the next
  27.890 -	    changeset to test, and told us which changeset it's
  27.891 -	    testing.</para>
  27.892 -	</listitem></itemizedlist>
  27.893 -
  27.894 -      <para>We now run our test in the working directory.  We use the
  27.895 -	<command>grep</command> command to see if our
  27.896 -	<quote>bad</quote> file is present in the working directory.
  27.897 -	If it is, this revision is bad; if not, this revision is good.
  27.898 -	&interaction.bisect.search.step1;</para>
  27.899 -
  27.900 -      <para>This test looks like a perfect candidate for automation,
  27.901 -	so let's turn it into a shell function.</para>
  27.902 -      &interaction.bisect.search.mytest;
  27.903 -
  27.904 -      <para>We can now run an entire test step with a single command,
  27.905 -	<literal>mytest</literal>.</para>
  27.906 -
  27.907 -      &interaction.bisect.search.step2;
  27.908 -
  27.909 -      <para>A few more invocations of our canned test step command,
  27.910 -	and we're done.</para>
  27.911 -
  27.912 -      &interaction.bisect.search.rest;
  27.913 -
  27.914 -      <para>Even though we had 40 changesets to search through, the
  27.915 -	<command role="hg-cmd">hg bisect</command> command let us find
  27.916 -	the changeset that introduced our <quote>bug</quote> with only
  27.917 -	five tests.  Because the number of tests that the <command
  27.918 -	  role="hg-cmd">hg bisect</command> command performs grows
  27.919 -	logarithmically with the number of changesets to search, the
  27.920 -	advantage that it has over the <quote>brute force</quote>
  27.921 -	search approach increases with every changeset you add.</para>
  27.922 -
  27.923 -    </sect2>
  27.924 -    <sect2>
  27.925 -      <title>Cleaning up after your search</title>
  27.926 -
  27.927 -      <para>When you're finished using the <command role="hg-cmd">hg
  27.928 -	  bisect</command> command in a repository, you can use the
  27.929 -	<command role="hg-cmd">hg bisect reset</command> command to
  27.930 -	drop the information it was using to drive your search.  The
  27.931 -	command doesn't use much space, so it doesn't matter if you
  27.932 -	forget to run this command.  However, <command
  27.933 -	  role="hg-cmd">hg bisect</command> won't let you start a new
  27.934 -	search in that repository until you do a <command
  27.935 -	  role="hg-cmd">hg bisect reset</command>.</para>
  27.936 -
  27.937 -      &interaction.bisect.search.reset;
  27.938 -
  27.939 -    </sect2>
  27.940 -  </sect1>
  27.941 -  <sect1>
  27.942 -    <title>Tips for finding bugs effectively</title>
  27.943 -
  27.944 -    <sect2>
  27.945 -      <title>Give consistent input</title>
  27.946 -
  27.947 -      <para>The <command role="hg-cmd">hg bisect</command> command
  27.948 -	requires that you correctly report the result of every test
  27.949 -	you perform.  If you tell it that a test failed when it really
  27.950 -	succeeded, it <emphasis>might</emphasis> be able to detect the
  27.951 -	inconsistency.  If it can identify an inconsistency in your
  27.952 -	reports, it will tell you that a particular changeset is both
  27.953 -	good and bad. However, it can't do this perfectly; it's about
  27.954 -	as likely to report the wrong changeset as the source of the
  27.955 -	bug.</para>
  27.956 -
  27.957 -    </sect2>
  27.958 -    <sect2>
  27.959 -      <title>Automate as much as possible</title>
  27.960 -
  27.961 -      <para>When I started using the <command role="hg-cmd">hg
  27.962 -	  bisect</command> command, I tried a few times to run my
  27.963 -	tests by hand, on the command line.  This is an approach that
  27.964 -	I, at least, am not suited to.  After a few tries, I found
  27.965 -	that I was making enough mistakes that I was having to restart
  27.966 -	my searches several times before finally getting correct
  27.967 -	results.</para>
  27.968 -
  27.969 -      <para>My initial problems with driving the <command
  27.970 -	  role="hg-cmd">hg bisect</command> command by hand occurred
  27.971 -	even with simple searches on small repositories; if the
  27.972 -	problem you're looking for is more subtle, or the number of
  27.973 -	tests that <command role="hg-cmd">hg bisect</command> must
  27.974 -	perform increases, the likelihood of operator error ruining
  27.975 -	the search is much higher.  Once I started automating my
  27.976 -	tests, I had much better results.</para>
  27.977 -
  27.978 -      <para>The key to automated testing is twofold:</para>
  27.979 -      <itemizedlist>
  27.980 -	<listitem><para>always test for the same symptom, and</para>
  27.981 -	</listitem>
  27.982 -	<listitem><para>always feed consistent input to the <command
  27.983 -	      role="hg-cmd">hg bisect</command> command.</para>
  27.984 -	</listitem></itemizedlist>
  27.985 -      <para>In my tutorial example above, the <command>grep</command>
  27.986 -	command tests for the symptom, and the <literal>if</literal>
  27.987 -	statement takes the result of this check and ensures that we
  27.988 -	always feed the same input to the <command role="hg-cmd">hg
  27.989 -	  bisect</command> command.  The <literal>mytest</literal>
  27.990 -	function marries these together in a reproducible way, so that
  27.991 -	every test is uniform and consistent.</para>
  27.992 -
  27.993 -    </sect2>
  27.994 -    <sect2>
  27.995 -      <title>Check your results</title>
  27.996 -
  27.997 -      <para>Because the output of a <command role="hg-cmd">hg
  27.998 -	  bisect</command> search is only as good as the input you
  27.999 -	give it, don't take the changeset it reports as the absolute
 27.1000 -	truth.  A simple way to cross-check its report is to manually
 27.1001 -	run your test at each of the following changesets:</para>
 27.1002 -      <itemizedlist>
 27.1003 -	<listitem><para>The changeset that it reports as the first bad
 27.1004 -	    revision.  Your test should still report this as
 27.1005 -	    bad.</para>
 27.1006 -	</listitem>
 27.1007 -	<listitem><para>The parent of that changeset (either parent,
 27.1008 -	    if it's a merge). Your test should report this changeset
 27.1009 -	    as good.</para>
 27.1010 -	</listitem>
 27.1011 -	<listitem><para>A child of that changeset.  Your test should
 27.1012 -	    report this changeset as bad.</para>
 27.1013 -	</listitem></itemizedlist>
 27.1014 -
 27.1015 -    </sect2>
 27.1016 -    <sect2>
 27.1017 -      <title>Beware interference between bugs</title>
 27.1018 -
 27.1019 -      <para>It's possible that your search for one bug could be
 27.1020 -	disrupted by the presence of another.  For example, let's say
 27.1021 -	your software crashes at revision 100, and worked correctly at
 27.1022 -	revision 50.  Unknown to you, someone else introduced a
 27.1023 -	different crashing bug at revision 60, and fixed it at
 27.1024 -	revision 80.  This could distort your results in one of
 27.1025 -	several ways.</para>
 27.1026 -
 27.1027 -      <para>It is possible that this other bug completely
 27.1028 -	<quote>masks</quote> yours, which is to say that it occurs
 27.1029 -	before your bug has a chance to manifest itself.  If you can't
 27.1030 -	avoid that other bug (for example, it prevents your project
 27.1031 -	from building), and so can't tell whether your bug is present
 27.1032 -	in a particular changeset, the <command role="hg-cmd">hg
 27.1033 -	  bisect</command> command cannot help you directly.  Instead,
 27.1034 -	you can mark a changeset as untested by running <command
 27.1035 -	  role="hg-cmd">hg bisect --skip</command>.</para>
 27.1036 -
 27.1037 -      <para>A different problem could arise if your test for a bug's
 27.1038 -	presence is not specific enough.  If you check for <quote>my
 27.1039 -	  program crashes</quote>, then both your crashing bug and an
 27.1040 -	unrelated crashing bug that masks it will look like the same
 27.1041 -	thing, and mislead <command role="hg-cmd">hg
 27.1042 -	  bisect</command>.</para>
 27.1043 -
 27.1044 -      <para>Another useful situation in which to use <command
 27.1045 -	  role="hg-cmd">hg bisect --skip</command> is if you can't
 27.1046 -	test a revision because your project was in a broken and hence
 27.1047 -	untestable state at that revision, perhaps because someone
 27.1048 -	checked in a change that prevented the project from
 27.1049 -	building.</para>
 27.1050 -
 27.1051 -    </sect2>
 27.1052 -    <sect2>
 27.1053 -      <title>Bracket your search lazily</title>
 27.1054 -
 27.1055 -      <para>Choosing the first <quote>good</quote> and
 27.1056 -	<quote>bad</quote> changesets that will mark the end points of
 27.1057 -	your search is often easy, but it bears a little discussion
 27.1058 -	nevertheless.  From the perspective of <command
 27.1059 -	  role="hg-cmd">hg bisect</command>, the <quote>newest</quote>
 27.1060 -	changeset is conventionally <quote>bad</quote>, and the older
 27.1061 -	changeset is <quote>good</quote>.</para>
 27.1062 -
 27.1063 -      <para>If you're having trouble remembering when a suitable
 27.1064 -	<quote>good</quote> change was, so that you can tell <command
 27.1065 -	  role="hg-cmd">hg bisect</command>, you could do worse than
 27.1066 -	testing changesets at random.  Just remember to eliminate
 27.1067 -	contenders that can't possibly exhibit the bug (perhaps
 27.1068 -	because the feature with the bug isn't present yet) and those
 27.1069 -	where another problem masks the bug (as I discussed
 27.1070 -	above).</para>
 27.1071 -
 27.1072 -      <para>Even if you end up <quote>early</quote> by thousands of
 27.1073 -	changesets or months of history, you will only add a handful
 27.1074 -	of tests to the total number that <command role="hg-cmd">hg
 27.1075 -	  bisect</command> must perform, thanks to its logarithmic
 27.1076 -	behaviour.</para>
 27.1077 -
 27.1078 -    </sect2>
 27.1079 -  </sect1>
 27.1080 -</chapter>
 27.1081 -
 27.1082 -<!--
 27.1083 -local variables: 
 27.1084 -sgml-parent-document: ("00book.xml" "book" "chapter")
 27.1085 -end:
 27.1086 --->
    28.1 --- a/en/ch10-hook.xml	Fri Mar 20 15:40:06 2009 +0800
    28.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.3 @@ -1,2037 +0,0 @@
    28.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    28.5 -
    28.6 -<chapter id="chap.hook">
    28.7 -  <?dbhtml filename="handling-repository-events-with-hooks.html"?>
    28.8 -  <title>Handling repository events with hooks</title>
    28.9 -
   28.10 -  <para>Mercurial offers a powerful mechanism to let you perform
   28.11 -    automated actions in response to events that occur in a
   28.12 -    repository.  In some cases, you can even control Mercurial's
   28.13 -    response to those events.</para>
   28.14 -
   28.15 -  <para>The name Mercurial uses for one of these actions is a
   28.16 -    <emphasis>hook</emphasis>. Hooks are called
   28.17 -    <quote>triggers</quote> in some revision control systems, but the
   28.18 -    two names refer to the same idea.</para>
   28.19 -
   28.20 -  <sect1>
   28.21 -    <title>An overview of hooks in Mercurial</title>
   28.22 -
   28.23 -    <para>Here is a brief list of the hooks that Mercurial supports.
   28.24 -      We will revisit each of these hooks in more detail later, in
   28.25 -      section <xref linkend="sec.hook.ref"/>.</para>
   28.26 -
   28.27 -    <itemizedlist>
   28.28 -      <listitem><para><literal role="hook">changegroup</literal>: This
   28.29 -	  is run after a group of changesets has been brought into the
   28.30 -	  repository from elsewhere.</para>
   28.31 -      </listitem>
   28.32 -      <listitem><para><literal role="hook">commit</literal>: This is
   28.33 -	  run after a new changeset has been created in the local
   28.34 -	  repository.</para>
   28.35 -      </listitem>
   28.36 -      <listitem><para><literal role="hook">incoming</literal>: This is
   28.37 -	  run once for each new changeset that is brought into the
   28.38 -	  repository from elsewhere.  Notice the difference from
   28.39 -	  <literal role="hook">changegroup</literal>, which is run
   28.40 -	  once per <emphasis>group</emphasis> of changesets brought
   28.41 -	  in.</para>
   28.42 -      </listitem>
   28.43 -      <listitem><para><literal role="hook">outgoing</literal>: This is
   28.44 -	  run after a group of changesets has been transmitted from
   28.45 -	  this repository.</para>
   28.46 -      </listitem>
   28.47 -      <listitem><para><literal role="hook">prechangegroup</literal>:
   28.48 -	  This is run before starting to bring a group of changesets
   28.49 -	  into the repository.
   28.50 -	</para>
   28.51 -      </listitem>
   28.52 -      <listitem><para><literal role="hook">precommit</literal>:
   28.53 -	  Controlling. This is run before starting a commit.
   28.54 -	</para>
   28.55 -      </listitem>
   28.56 -      <listitem><para><literal role="hook">preoutgoing</literal>:
   28.57 -	  Controlling. This is run before starting to transmit a group
   28.58 -	  of changesets from this repository.
   28.59 -	</para>
   28.60 -      </listitem>
   28.61 -      <listitem><para><literal role="hook">pretag</literal>:
   28.62 -	  Controlling. This is run before creating a tag.
   28.63 -	</para>
   28.64 -      </listitem>
   28.65 -      <listitem><para><literal
   28.66 -	    role="hook">pretxnchangegroup</literal>: Controlling. This
   28.67 -	  is run after a group of changesets has been brought into the
   28.68 -	  local repository from another, but before the transaction
   28.69 -	  completes that will make the changes permanent in the
   28.70 -	  repository.
   28.71 -	</para>
   28.72 -      </listitem>
   28.73 -      <listitem><para><literal role="hook">pretxncommit</literal>:
   28.74 -	  Controlling. This is run after a new changeset has been
   28.75 -	  created in the local repository, but before the transaction
   28.76 -	  completes that will make it permanent.
   28.77 -	</para>
   28.78 -      </listitem>
   28.79 -      <listitem><para><literal role="hook">preupdate</literal>:
   28.80 -	  Controlling. This is run before starting an update or merge
   28.81 -	  of the working directory.
   28.82 -	</para>
   28.83 -      </listitem>
   28.84 -      <listitem><para><literal role="hook">tag</literal>: This is run
   28.85 -	  after a tag is created.
   28.86 -	</para>
   28.87 -      </listitem>
   28.88 -      <listitem><para><literal role="hook">update</literal>: This is
   28.89 -	  run after an update or merge of the working directory has
   28.90 -	  finished.
   28.91 -	</para>
   28.92 -      </listitem></itemizedlist>
   28.93 -    <para>Each of the hooks whose description begins with the word
   28.94 -      <quote>Controlling</quote> has the ability to determine whether
   28.95 -      an activity can proceed.  If the hook succeeds, the activity may
   28.96 -      proceed; if it fails, the activity is either not permitted or
   28.97 -      undone, depending on the hook.
   28.98 -    </para>
   28.99 -
  28.100 -  </sect1>
  28.101 -  <sect1>
  28.102 -    <title>Hooks and security</title>
  28.103 -
  28.104 -    <sect2>
  28.105 -      <title>Hooks are run with your privileges</title>
  28.106 -
  28.107 -      <para>When you run a Mercurial command in a repository, and the
  28.108 -	command causes a hook to run, that hook runs on
  28.109 -	<emphasis>your</emphasis> system, under
  28.110 -	<emphasis>your</emphasis> user account, with
  28.111 -	<emphasis>your</emphasis> privilege level.  Since hooks are
  28.112 -	arbitrary pieces of executable code, you should treat them
  28.113 -	with an appropriate level of suspicion.  Do not install a hook
  28.114 -	unless you are confident that you know who created it and what
  28.115 -	it does.
  28.116 -      </para>
  28.117 -
  28.118 -      <para>In some cases, you may be exposed to hooks that you did
  28.119 -	not install yourself.  If you work with Mercurial on an
  28.120 -	unfamiliar system, Mercurial will run hooks defined in that
  28.121 -	system's global <filename role="special">~/.hgrc</filename>
  28.122 -	file.
  28.123 -      </para>
  28.124 -
  28.125 -      <para>If you are working with a repository owned by another
  28.126 -	user, Mercurial can run hooks defined in that user's
  28.127 -	repository, but it will still run them as <quote>you</quote>.
  28.128 -	For example, if you <command role="hg-cmd">hg pull</command>
  28.129 -	from that repository, and its <filename
  28.130 -	  role="special">.hg/hgrc</filename> defines a local <literal
  28.131 -	  role="hook">outgoing</literal> hook, that hook will run
  28.132 -	under your user account, even though you don't own that
  28.133 -	repository.
  28.134 -      </para>
  28.135 -
  28.136 -      <note>
  28.137 -	<para>  This only applies if you are pulling from a repository
  28.138 -	  on a local or network filesystem.  If you're pulling over
  28.139 -	  http or ssh, any <literal role="hook">outgoing</literal>
  28.140 -	  hook will run under whatever account is executing the server
  28.141 -	  process, on the server.
  28.142 -	</para>
  28.143 -      </note>
  28.144 -
  28.145 -      <para>XXX To see what hooks are defined in a repository, use the
  28.146 -	<command role="hg-cmd">hg config hooks</command> command.  If
  28.147 -	you are working in one repository, but talking to another that
  28.148 -	you do not own (e.g. using <command role="hg-cmd">hg
  28.149 -	  pull</command> or <command role="hg-cmd">hg
  28.150 -	  incoming</command>), remember that it is the other
  28.151 -	repository's hooks you should be checking, not your own.
  28.152 -      </para>
  28.153 -
  28.154 -    </sect2>
  28.155 -    <sect2>
  28.156 -      <title>Hooks do not propagate</title>
  28.157 -
  28.158 -      <para>In Mercurial, hooks are not revision controlled, and do
  28.159 -	not propagate when you clone, or pull from, a repository.  The
  28.160 -	reason for this is simple: a hook is a completely arbitrary
  28.161 -	piece of executable code.  It runs under your user identity,
  28.162 -	with your privilege level, on your machine.
  28.163 -      </para>
  28.164 -
  28.165 -      <para>It would be extremely reckless for any distributed
  28.166 -	revision control system to implement revision-controlled
  28.167 -	hooks, as this would offer an easily exploitable way to
  28.168 -	subvert the accounts of users of the revision control system.
  28.169 -      </para>
  28.170 -
  28.171 -      <para>Since Mercurial does not propagate hooks, if you are
  28.172 -	collaborating with other people on a common project, you
  28.173 -	should not assume that they are using the same Mercurial hooks
  28.174 -	as you are, or that theirs are correctly configured.  You
  28.175 -	should document the hooks you expect people to use.
  28.176 -      </para>
  28.177 -
  28.178 -      <para>In a corporate intranet, this is somewhat easier to
  28.179 -	control, as you can for example provide a
  28.180 -	<quote>standard</quote> installation of Mercurial on an NFS
  28.181 -	filesystem, and use a site-wide <filename role="special">~/.hgrc</filename> file to define hooks that all users will
  28.182 -	see.  However, this too has its limits; see below.
  28.183 -      </para>
  28.184 -
  28.185 -    </sect2>
  28.186 -    <sect2>
  28.187 -      <title>Hooks can be overridden</title>
  28.188 -
  28.189 -      <para>Mercurial allows you to override a hook definition by
  28.190 -	redefining the hook.  You can disable it by setting its value
  28.191 -	to the empty string, or change its behaviour as you wish.
  28.192 -      </para>
  28.193 -
  28.194 -      <para>If you deploy a system- or site-wide <filename
  28.195 -	  role="special">~/.hgrc</filename> file that defines some
  28.196 -	hooks, you should thus understand that your users can disable
  28.197 -	or override those hooks.
  28.198 -      </para>
  28.199 -
  28.200 -    </sect2>
  28.201 -    <sect2>
  28.202 -      <title>Ensuring that critical hooks are run</title>
  28.203 -
  28.204 -      <para>Sometimes you may want to enforce a policy that you do not
  28.205 -	want others to be able to work around.  For example, you may
  28.206 -	have a requirement that every changeset must pass a rigorous
  28.207 -	set of tests.  Defining this requirement via a hook in a
  28.208 -	site-wide <filename role="special">~/.hgrc</filename> won't
  28.209 -	work for remote users on laptops, and of course local users
  28.210 -	can subvert it at will by overriding the hook.
  28.211 -      </para>
  28.212 -
  28.213 -      <para>Instead, you can set up your policies for use of Mercurial
  28.214 -	so that people are expected to propagate changes through a
  28.215 -	well-known <quote>canonical</quote> server that you have
  28.216 -	locked down and configured appropriately.
  28.217 -      </para>
  28.218 -
  28.219 -      <para>One way to do this is via a combination of social
  28.220 -	engineering and technology.  Set up a restricted-access
  28.221 -	account; users can push changes over the network to
  28.222 -	repositories managed by this account, but they cannot log into
  28.223 -	the account and run normal shell commands.  In this scenario,
  28.224 -	a user can commit a changeset that contains any old garbage
  28.225 -	they want.
  28.226 -      </para>
  28.227 -
  28.228 -      <para>When someone pushes a changeset to the server that
  28.229 -	everyone pulls from, the server will test the changeset before
  28.230 -	it accepts it as permanent, and reject it if it fails to pass
  28.231 -	the test suite.  If people only pull changes from this
  28.232 -	filtering server, it will serve to ensure that all changes
  28.233 -	that people pull have been automatically vetted.
  28.234 -      </para>
  28.235 -
  28.236 -    </sect2>
  28.237 -  </sect1>
  28.238 -  <sect1>
  28.239 -    <title>Care with <literal>pretxn</literal> hooks in a
  28.240 -      shared-access repository</title>
  28.241 -
  28.242 -    <para>If you want to use hooks to do some automated work in a
  28.243 -      repository that a number of people have shared access to, you
  28.244 -      need to be careful in how you do this.
  28.245 -    </para>
  28.246 -
  28.247 -    <para>Mercurial only locks a repository when it is writing to the
  28.248 -      repository, and only the parts of Mercurial that write to the
  28.249 -      repository pay attention to locks.  Write locks are necessary to
  28.250 -      prevent multiple simultaneous writers from scribbling on each
  28.251 -      other's work, corrupting the repository.
  28.252 -    </para>
  28.253 -
  28.254 -    <para>Because Mercurial is careful with the order in which it
  28.255 -      reads and writes data, it does not need to acquire a lock when
  28.256 -      it wants to read data from the repository.  The parts of
  28.257 -      Mercurial that read from the repository never pay attention to
  28.258 -      locks.  This lockless reading scheme greatly increases
  28.259 -      performance and concurrency.
  28.260 -    </para>
  28.261 -
  28.262 -    <para>With great performance comes a trade-off, though, one which
  28.263 -      has the potential to cause you trouble unless you're aware of
  28.264 -      it.  To describe this requires a little detail about how
  28.265 -      Mercurial adds changesets to a repository and reads those
  28.266 -      changes.
  28.267 -    </para>
  28.268 -
  28.269 -    <para>When Mercurial <emphasis>writes</emphasis> metadata, it
  28.270 -      writes it straight into the destination file.  It writes file
  28.271 -      data first, then manifest data (which contains pointers to the
  28.272 -      new file data), then changelog data (which contains pointers to
  28.273 -      the new manifest data).  Before the first write to each file, it
  28.274 -      stores a record of where the end of the file was in its
  28.275 -      transaction log.  If the transaction must be rolled back,
  28.276 -      Mercurial simply truncates each file back to the size it was
  28.277 -      before the transaction began.
  28.278 -    </para>
  28.279 -
  28.280 -    <para>When Mercurial <emphasis>reads</emphasis> metadata, it reads
  28.281 -      the changelog first, then everything else.  Since a reader will
  28.282 -      only access parts of the manifest or file metadata that it can
  28.283 -      see in the changelog, it can never see partially written data.
  28.284 -    </para>
  28.285 -
  28.286 -    <para>Some controlling hooks (<literal
  28.287 -	role="hook">pretxncommit</literal> and <literal
  28.288 -	role="hook">pretxnchangegroup</literal>) run when a
  28.289 -      transaction is almost complete. All of the metadata has been
  28.290 -      written, but Mercurial can still roll the transaction back and
  28.291 -      cause the newly-written data to disappear.
  28.292 -    </para>
  28.293 -
  28.294 -    <para>If one of these hooks runs for long, it opens a window of
  28.295 -      time during which a reader can see the metadata for changesets
  28.296 -      that are not yet permanent, and should not be thought of as
  28.297 -      <quote>really there</quote>.  The longer the hook runs, the
  28.298 -      longer that window is open.
  28.299 -    </para>
  28.300 -
  28.301 -    <sect2>
  28.302 -      <title>The problem illustrated</title>
  28.303 -
  28.304 -      <para>In principle, a good use for the <literal
  28.305 -	  role="hook">pretxnchangegroup</literal> hook would be to
  28.306 -	automatically build and test incoming changes before they are
  28.307 -	accepted into a central repository.  This could let you
  28.308 -	guarantee that nobody can push changes to this repository that
  28.309 -	<quote>break the build</quote>. But if a client can pull
  28.310 -	changes while they're being tested, the usefulness of the test
  28.311 -	is zero; an unsuspecting someone can pull untested changes,
  28.312 -	potentially breaking their build.
  28.313 -      </para>
  28.314 -
  28.315 -      <para>The safest technological answer to this challenge is to
  28.316 -	set up such a <quote>gatekeeper</quote> repository as
  28.317 -	<emphasis>unidirectional</emphasis>.  Let it take changes
  28.318 -	pushed in from the outside, but do not allow anyone to pull
  28.319 -	changes from it (use the <literal
  28.320 -	  role="hook">preoutgoing</literal> hook to lock it down).
  28.321 -	Configure a <literal role="hook">changegroup</literal> hook so
  28.322 -	that if a build or test succeeds, the hook will push the new
  28.323 -	changes out to another repository that people
  28.324 -	<emphasis>can</emphasis> pull from.
  28.325 -      </para>
  28.326 -
  28.327 -      <para>In practice, putting a centralised bottleneck like this in
  28.328 -	place is not often a good idea, and transaction visibility has
  28.329 -	nothing to do with the problem.  As the size of a
  28.330 -	project&emdash;and the time it takes to build and
  28.331 -	test&emdash;grows, you rapidly run into a wall with this
  28.332 -	<quote>try before you buy</quote> approach, where you have
  28.333 -	more changesets to test than time in which to deal with them.
  28.334 -	The inevitable result is frustration on the part of all
  28.335 -	involved.
  28.336 -      </para>
  28.337 -
  28.338 -      <para>An approach that scales better is to get people to build
  28.339 -	and test before they push, then run automated builds and tests
  28.340 -	centrally <emphasis>after</emphasis> a push, to be sure all is
  28.341 -	well.  The advantage of this approach is that it does not
  28.342 -	impose a limit on the rate at which the repository can accept
  28.343 -	changes.
  28.344 -      </para>
  28.345 -
  28.346 -    </sect2>
  28.347 -  </sect1>
  28.348 -  <sect1 id="sec.hook.simple">
  28.349 -    <title>A short tutorial on using hooks</title>
  28.350 -
  28.351 -    <para>It is easy to write a Mercurial hook.  Let's start with a
  28.352 -      hook that runs when you finish a <command role="hg-cmd">hg
  28.353 -	commit</command>, and simply prints the hash of the changeset
  28.354 -      you just created.  The hook is called <literal
  28.355 -	role="hook">commit</literal>.
  28.356 -    </para>
  28.357 -
  28.358 -    <para>All hooks follow the pattern in this example.</para>
  28.359 -
  28.360 -&interaction.hook.simple.init;
  28.361 -
  28.362 -    <para>You add an entry to the <literal
  28.363 -	role="rc-hooks">hooks</literal> section of your <filename
  28.364 -	role="special">~/.hgrc</filename>.  On the left is the name of
  28.365 -      the event to trigger on; on the right is the action to take.  As
  28.366 -      you can see, you can run an arbitrary shell command in a hook.
  28.367 -      Mercurial passes extra information to the hook using environment
  28.368 -      variables (look for <envar>HG_NODE</envar> in the example).
  28.369 -    </para>
  28.370 -
  28.371 -    <sect2>
  28.372 -      <title>Performing multiple actions per event</title>
  28.373 -
  28.374 -      <para>Quite often, you will want to define more than one hook
  28.375 -	for a particular kind of event, as shown below.</para>
  28.376 -
  28.377 -&interaction.hook.simple.ext;
  28.378 -
  28.379 -      <para>Mercurial lets you do this by adding an
  28.380 -	<emphasis>extension</emphasis> to the end of a hook's name.
  28.381 -	You extend a hook's name by giving the name of the hook,
  28.382 -	followed by a full stop (the
  28.383 -	<quote><literal>.</literal></quote> character), followed by
  28.384 -	some more text of your choosing.  For example, Mercurial will
  28.385 -	run both <literal>commit.foo</literal> and
  28.386 -	<literal>commit.bar</literal> when the
  28.387 -	<literal>commit</literal> event occurs.
  28.388 -      </para>
  28.389 -
  28.390 -      <para>To give a well-defined order of execution when there are
  28.391 -	multiple hooks defined for an event, Mercurial sorts hooks by
  28.392 -	extension, and executes the hook commands in this sorted
  28.393 -	order.  In the above example, it will execute
  28.394 -	<literal>commit.bar</literal> before
  28.395 -	<literal>commit.foo</literal>, and <literal>commit</literal>
  28.396 -	before both.
  28.397 -      </para>
  28.398 -
  28.399 -      <para>It is a good idea to use a somewhat descriptive extension
  28.400 -	when you define a new hook.  This will help you to remember
  28.401 -	what the hook was for.  If the hook fails, you'll get an error
  28.402 -	message that contains the hook name and extension, so using a
  28.403 -	descriptive extension could give you an immediate hint as to
  28.404 -	why the hook failed (see section <xref
  28.405 -	  linkend="sec.hook.perm"/> for an example).
  28.406 -      </para>
  28.407 -
  28.408 -    </sect2>
  28.409 -    <sect2 id="sec.hook.perm">
  28.410 -      <title>Controlling whether an activity can proceed</title>
  28.411 -
  28.412 -      <para>In our earlier examples, we used the <literal
  28.413 -	  role="hook">commit</literal> hook, which is run after a
  28.414 -	commit has completed.  This is one of several Mercurial hooks
  28.415 -	that run after an activity finishes.  Such hooks have no way
  28.416 -	of influencing the activity itself.
  28.417 -      </para>
  28.418 -
  28.419 -      <para>Mercurial defines a number of events that occur before an
  28.420 -	activity starts; or after it starts, but before it finishes.
  28.421 -	Hooks that trigger on these events have the added ability to
  28.422 -	choose whether the activity can continue, or will abort.
  28.423 -      </para>
  28.424 -
  28.425 -      <para>The <literal role="hook">pretxncommit</literal> hook runs
  28.426 -	after a commit has all but completed.  In other words, the
  28.427 -	metadata representing the changeset has been written out to
  28.428 -	disk, but the transaction has not yet been allowed to
  28.429 -	complete.  The <literal role="hook">pretxncommit</literal>
  28.430 -	hook has the ability to decide whether the transaction can
  28.431 -	complete, or must be rolled back.
  28.432 -      </para>
  28.433 -
  28.434 -      <para>If the <literal role="hook">pretxncommit</literal> hook
  28.435 -	exits with a status code of zero, the transaction is allowed
  28.436 -	to complete; the commit finishes; and the <literal
  28.437 -	  role="hook">commit</literal> hook is run.  If the <literal
  28.438 -	  role="hook">pretxncommit</literal> hook exits with a
  28.439 -	non-zero status code, the transaction is rolled back; the
  28.440 -	metadata representing the changeset is erased; and the
  28.441 -	<literal role="hook">commit</literal> hook is not run.
  28.442 -      </para>
  28.443 -
  28.444 -&interaction.hook.simple.pretxncommit;
  28.445 -
  28.446 -      <para>The hook in the example above checks that a commit comment
  28.447 -	contains a bug ID.  If it does, the commit can complete.  If
  28.448 -	not, the commit is rolled back.
  28.449 -      </para>
  28.450 -
  28.451 -    </sect2>
  28.452 -  </sect1>
  28.453 -  <sect1>
  28.454 -    <title>Writing your own hooks</title>
  28.455 -
  28.456 -    <para>When you are writing a hook, you might find it useful to run
  28.457 -      Mercurial either with the <option
  28.458 -	role="hg-opt-global">-v</option> option, or the <envar
  28.459 -	role="rc-item-ui">verbose</envar> config item set to
  28.460 -      <quote>true</quote>.  When you do so, Mercurial will print a
  28.461 -      message before it calls each hook.
  28.462 -    </para>
  28.463 -
  28.464 -    <sect2 id="sec.hook.lang">
  28.465 -      <title>Choosing how your hook should run</title>
  28.466 -
  28.467 -      <para>You can write a hook either as a normal
  28.468 -	program&emdash;typically a shell script&emdash;or as a Python
  28.469 -	function that is executed within the Mercurial process.
  28.470 -      </para>
  28.471 -
  28.472 -      <para>Writing a hook as an external program has the advantage
  28.473 -	that it requires no knowledge of Mercurial's internals.  You
  28.474 -	can call normal Mercurial commands to get any added
  28.475 -	information you need.  The trade-off is that external hooks
  28.476 -	are slower than in-process hooks.
  28.477 -      </para>
  28.478 -
  28.479 -      <para>An in-process Python hook has complete access to the
  28.480 -	Mercurial API, and does not <quote>shell out</quote> to
  28.481 -	another process, so it is inherently faster than an external
  28.482 -	hook.  It is also easier to obtain much of the information
  28.483 -	that a hook requires by using the Mercurial API than by
  28.484 -	running Mercurial commands.
  28.485 -      </para>
  28.486 -
  28.487 -      <para>If you are comfortable with Python, or require high
  28.488 -	performance, writing your hooks in Python may be a good
  28.489 -	choice.  However, when you have a straightforward hook to
  28.490 -	write and you don't need to care about performance (probably
  28.491 -	the majority of hooks), a shell script is perfectly fine.
  28.492 -      </para>
  28.493 -
  28.494 -    </sect2>
  28.495 -    <sect2 id="sec.hook.param">
  28.496 -      <title>Hook parameters</title>
  28.497 -
  28.498 -      <para>Mercurial calls each hook with a set of well-defined
  28.499 -	parameters.  In Python, a parameter is passed as a keyword
  28.500 -	argument to your hook function.  For an external program, a
  28.501 -	parameter is passed as an environment variable.
  28.502 -      </para>
  28.503 -
  28.504 -      <para>Whether your hook is written in Python or as a shell
  28.505 -	script, the hook-specific parameter names and values will be
  28.506 -	the same.  A boolean parameter will be represented as a
  28.507 -	boolean value in Python, but as the number 1 (for
  28.508 -	<quote>true</quote>) or 0 (for <quote>false</quote>) as an
  28.509 -	environment variable for an external hook.  If a hook
  28.510 -	parameter is named <literal>foo</literal>, the keyword
  28.511 -	argument for a Python hook will also be named
  28.512 -	<literal>foo</literal>, while the environment variable for an
  28.513 -	external hook will be named <literal>HG_FOO</literal>.
  28.514 -      </para>
  28.515 -
  28.516 -    </sect2>
  28.517 -    <sect2>
  28.518 -      <title>Hook return values and activity control</title>
  28.519 -
  28.520 -      <para>A hook that executes successfully must exit with a status
  28.521 -	of zero if external, or return boolean <quote>false</quote> if
  28.522 -	in-process.  Failure is indicated with a non-zero exit status
  28.523 -	from an external hook, or an in-process hook returning boolean
  28.524 -	<quote>true</quote>.  If an in-process hook raises an
  28.525 -	exception, the hook is considered to have failed.
  28.526 -      </para>
  28.527 -
  28.528 -      <para>For a hook that controls whether an activity can proceed,
  28.529 -	zero/false means <quote>allow</quote>, while
  28.530 -	non-zero/true/exception means <quote>deny</quote>.
  28.531 -      </para>
  28.532 -
  28.533 -    </sect2>
  28.534 -    <sect2>
  28.535 -      <title>Writing an external hook</title>
  28.536 -
  28.537 -      <para>When you define an external hook in your <filename
  28.538 -	  role="special">~/.hgrc</filename> and the hook is run, its
  28.539 -	value is passed to your shell, which interprets it.  This
  28.540 -	means that you can use normal shell constructs in the body of
  28.541 -	the hook.
  28.542 -      </para>
  28.543 -
  28.544 -      <para>An executable hook is always run with its current
  28.545 -	directory set to a repository's root directory.
  28.546 -      </para>
  28.547 -
  28.548 -      <para>Each hook parameter is passed in as an environment
  28.549 -	variable; the name is upper-cased, and prefixed with the
  28.550 -	string <quote><literal>HG_</literal></quote>.
  28.551 -      </para>
  28.552 -
  28.553 -      <para>With the exception of hook parameters, Mercurial does not
  28.554 -	set or modify any environment variables when running a hook.
  28.555 -	This is useful to remember if you are writing a site-wide hook
  28.556 -	that may be run by a number of different users with differing
  28.557 -	environment variables set. In multi-user situations, you
  28.558 -	should not rely on environment variables being set to the
  28.559 -	values you have in your environment when testing the hook.
  28.560 -      </para>
  28.561 -
  28.562 -    </sect2>
  28.563 -    <sect2>
  28.564 -      <title>Telling Mercurial to use an in-process hook</title>
  28.565 -
  28.566 -      <para>The <filename role="special">~/.hgrc</filename> syntax
  28.567 -	for defining an in-process hook is slightly different than for
  28.568 -	an executable hook.  The value of the hook must start with the
  28.569 -	text <quote><literal>python:</literal></quote>, and continue
  28.570 -	with the fully-qualified name of a callable object to use as
  28.571 -	the hook's value.
  28.572 -      </para>
  28.573 -
  28.574 -      <para>The module in which a hook lives is automatically imported
  28.575 -	when a hook is run.  So long as you have the module name and
  28.576 -	<envar>PYTHONPATH</envar> right, it should <quote>just
  28.577 -	  work</quote>.
  28.578 -      </para>
  28.579 -
  28.580 -      <para>The following <filename role="special">~/.hgrc</filename>
  28.581 -	example snippet illustrates the syntax and meaning of the
  28.582 -	notions we just described.
  28.583 -      </para>
  28.584 -      <programlisting>[hooks]
  28.585 -commit.example = python:mymodule.submodule.myhook</programlisting>
  28.586 -      <para>When Mercurial runs the <literal>commit.example</literal>
  28.587 -	hook, it imports <literal>mymodule.submodule</literal>, looks
  28.588 -	for the callable object named <literal>myhook</literal>, and
  28.589 -	calls it.
  28.590 -      </para>
  28.591 -
  28.592 -    </sect2>
  28.593 -    <sect2>
  28.594 -      <title>Writing an in-process hook</title>
  28.595 -
  28.596 -      <para>The simplest in-process hook does nothing, but illustrates
  28.597 -	the basic shape of the hook API:
  28.598 -      </para>
  28.599 -      <programlisting>def myhook(ui, repo, **kwargs):
  28.600 -    pass</programlisting>
  28.601 -      <para>The first argument to a Python hook is always a <literal
  28.602 -	  role="py-mod-mercurial.ui">ui</literal> object.  The second
  28.603 -	is a repository object; at the moment, it is always an
  28.604 -	instance of <literal
  28.605 -	  role="py-mod-mercurial.localrepo">localrepository</literal>.
  28.606 -	Following these two arguments are other keyword arguments.
  28.607 -	Which ones are passed in depends on the hook being called, but
  28.608 -	a hook can ignore arguments it doesn't care about by dropping
  28.609 -	them into a keyword argument dict, as with
  28.610 -	<literal>**kwargs</literal> above.
  28.611 -      </para>
  28.612 -
  28.613 -    </sect2>
  28.614 -  </sect1>
  28.615 -  <sect1>
  28.616 -    <title>Some hook examples</title>
  28.617 -
  28.618 -    <sect2>
  28.619 -      <title>Writing meaningful commit messages</title>
  28.620 -
  28.621 -      <para>It's hard to imagine a useful commit message being very
  28.622 -	short. The simple <literal role="hook">pretxncommit</literal>
  28.623 -	hook of the example below will prevent you from committing a
  28.624 -	changeset with a message that is less than ten bytes long.
  28.625 -      </para>
  28.626 -
  28.627 -&interaction.hook.msglen.go;
  28.628 -
  28.629 -    </sect2>
  28.630 -    <sect2>
  28.631 -      <title>Checking for trailing whitespace</title>
  28.632 -
  28.633 -      <para>An interesting use of a commit-related hook is to help you
  28.634 -	to write cleaner code.  A simple example of <quote>cleaner
  28.635 -	  code</quote> is the dictum that a change should not add any
  28.636 -	new lines of text that contain <quote>trailing
  28.637 -	  whitespace</quote>.  Trailing whitespace is a series of
  28.638 -	space and tab characters at the end of a line of text.  In
  28.639 -	most cases, trailing whitespace is unnecessary, invisible
  28.640 -	noise, but it is occasionally problematic, and people often
  28.641 -	prefer to get rid of it.
  28.642 -      </para>
  28.643 -
  28.644 -      <para>You can use either the <literal
  28.645 -	  role="hook">precommit</literal> or <literal
  28.646 -	  role="hook">pretxncommit</literal> hook to tell whether you
  28.647 -	have a trailing whitespace problem.  If you use the <literal
  28.648 -	  role="hook">precommit</literal> hook, the hook will not know
  28.649 -	which files you are committing, so it will have to check every
  28.650 -	modified file in the repository for trailing white space.  If
  28.651 -	you want to commit a change to just the file
  28.652 -	<filename>foo</filename>, but the file
  28.653 -	<filename>bar</filename> contains trailing whitespace, doing a
  28.654 -	check in the <literal role="hook">precommit</literal> hook
  28.655 -	will prevent you from committing <filename>foo</filename> due
  28.656 -	to the problem with <filename>bar</filename>.  This doesn't
  28.657 -	seem right.
  28.658 -      </para>
  28.659 -
  28.660 -      <para>Should you choose the <literal
  28.661 -	  role="hook">pretxncommit</literal> hook, the check won't
  28.662 -	occur until just before the transaction for the commit
  28.663 -	completes.  This will allow you to check for problems only the
  28.664 -	exact files that are being committed.  However, if you entered
  28.665 -	the commit message interactively and the hook fails, the
  28.666 -	transaction will roll back; you'll have to re-enter the commit
  28.667 -	message after you fix the trailing whitespace and run <command
  28.668 -	  role="hg-cmd">hg commit</command> again.
  28.669 -      </para>
  28.670 -
  28.671 -&interaction.hook.ws.simple;
  28.672 -
  28.673 -      <para>In this example, we introduce a simple <literal
  28.674 -	  role="hook">pretxncommit</literal> hook that checks for
  28.675 -	trailing whitespace.  This hook is short, but not very
  28.676 -	helpful.  It exits with an error status if a change adds a
  28.677 -	line with trailing whitespace to any file, but does not print
  28.678 -	any information that might help us to identify the offending
  28.679 -	file or line.  It also has the nice property of not paying
  28.680 -	attention to unmodified lines; only lines that introduce new
  28.681 -	trailing whitespace cause problems.
  28.682 -      </para>
  28.683 -
  28.684 -      <para>The above version is much more complex, but also more
  28.685 -	useful.  It parses a unified diff to see if any lines add
  28.686 -	trailing whitespace, and prints the name of the file and the
  28.687 -	line number of each such occurrence.  Even better, if the
  28.688 -	change adds trailing whitespace, this hook saves the commit
  28.689 -	comment and prints the name of the save file before exiting
  28.690 -	and telling Mercurial to roll the transaction back, so you can
  28.691 -	use the <option role="hg-opt-commit">-l filename</option>
  28.692 -	option to <command role="hg-cmd">hg commit</command> to reuse
  28.693 -	the saved commit message once you've corrected the problem.
  28.694 -      </para>
  28.695 -
  28.696 -&interaction.hook.ws.better;
  28.697 -
  28.698 -      <para>As a final aside, note in the example above the use of
  28.699 -	<command>perl</command>'s in-place editing feature to get rid
  28.700 -	of trailing whitespace from a file.  This is concise and
  28.701 -	useful enough that I will reproduce it here.
  28.702 -      </para>
  28.703 -      <programlisting>perl -pi -e 's,\s+$,,' filename</programlisting>
  28.704 -
  28.705 -    </sect2>
  28.706 -  </sect1>
  28.707 -  <sect1>
  28.708 -    <title>Bundled hooks</title>
  28.709 -
  28.710 -    <para>Mercurial ships with several bundled hooks.  You can find
  28.711 -      them in the <filename class="directory">hgext</filename>
  28.712 -      directory of a Mercurial source tree.  If you are using a
  28.713 -      Mercurial binary package, the hooks will be located in the
  28.714 -      <filename class="directory">hgext</filename> directory of
  28.715 -      wherever your package installer put Mercurial.
  28.716 -    </para>
  28.717 -
  28.718 -    <sect2>
  28.719 -      <title><literal role="hg-ext">acl</literal>&emdash;access
  28.720 -	control for parts of a repository</title>
  28.721 -
  28.722 -      <para>The <literal role="hg-ext">acl</literal> extension lets
  28.723 -	you control which remote users are allowed to push changesets
  28.724 -	to a networked server.  You can protect any portion of a
  28.725 -	repository (including the entire repo), so that a specific
  28.726 -	remote user can push changes that do not affect the protected
  28.727 -	portion.
  28.728 -      </para>
  28.729 -
  28.730 -      <para>This extension implements access control based on the
  28.731 -	identity of the user performing a push,
  28.732 -	<emphasis>not</emphasis> on who committed the changesets
  28.733 -	they're pushing.  It makes sense to use this hook only if you
  28.734 -	have a locked-down server environment that authenticates
  28.735 -	remote users, and you want to be sure that only specific users
  28.736 -	are allowed to push changes to that server.
  28.737 -      </para>
  28.738 -
  28.739 -      <sect3>
  28.740 -	<title>Configuring the <literal role="hook">acl</literal>
  28.741 -	  hook</title>
  28.742 -
  28.743 -	<para>In order to manage incoming changesets, the <literal
  28.744 -	    role="hg-ext">acl</literal> hook must be used as a
  28.745 -	  <literal role="hook">pretxnchangegroup</literal> hook.  This
  28.746 -	  lets it see which files are modified by each incoming
  28.747 -	  changeset, and roll back a group of changesets if they
  28.748 -	  modify <quote>forbidden</quote> files.  Example:
  28.749 -	</para>
  28.750 -	<programlisting>[hooks]
  28.751 -pretxnchangegroup.acl = python:hgext.acl.hook</programlisting>
  28.752 -
  28.753 -	<para>The <literal role="hg-ext">acl</literal> extension is
  28.754 -	  configured using three sections.
  28.755 -	</para>
  28.756 -
  28.757 -	<para>The <literal role="rc-acl">acl</literal> section has
  28.758 -	  only one entry, <envar role="rc-item-acl">sources</envar>,
  28.759 -	  which lists the sources of incoming changesets that the hook
  28.760 -	  should pay attention to.  You don't normally need to
  28.761 -	  configure this section.
  28.762 -	</para>
  28.763 -	<itemizedlist>
  28.764 -	  <listitem><para><envar role="rc-item-acl">serve</envar>:
  28.765 -	      Control incoming changesets that are arriving from a
  28.766 -	      remote repository over http or ssh.  This is the default
  28.767 -	      value of <envar role="rc-item-acl">sources</envar>, and
  28.768 -	      usually the only setting you'll need for this
  28.769 -	      configuration item.
  28.770 -	    </para>
  28.771 -	  </listitem>
  28.772 -	  <listitem><para><envar role="rc-item-acl">pull</envar>:
  28.773 -	      Control incoming changesets that are arriving via a pull
  28.774 -	      from a local repository.
  28.775 -	    </para>
  28.776 -	  </listitem>
  28.777 -	  <listitem><para><envar role="rc-item-acl">push</envar>:
  28.778 -	      Control incoming changesets that are arriving via a push
  28.779 -	      from a local repository.
  28.780 -	    </para>
  28.781 -	  </listitem>
  28.782 -	  <listitem><para><envar role="rc-item-acl">bundle</envar>:
  28.783 -	      Control incoming changesets that are arriving from
  28.784 -	      another repository via a bundle.
  28.785 -	    </para>
  28.786 -	  </listitem></itemizedlist>
  28.787 -
  28.788 -	<para>The <literal role="rc-acl.allow">acl.allow</literal>
  28.789 -	  section controls the users that are allowed to add
  28.790 -	  changesets to the repository.  If this section is not
  28.791 -	  present, all users that are not explicitly denied are
  28.792 -	  allowed.  If this section is present, all users that are not
  28.793 -	  explicitly allowed are denied (so an empty section means
  28.794 -	  that all users are denied).
  28.795 -	</para>
  28.796 -
  28.797 -	<para>The <literal role="rc-acl.deny">acl.deny</literal>
  28.798 -	  section determines which users are denied from adding
  28.799 -	  changesets to the repository.  If this section is not
  28.800 -	  present or is empty, no users are denied.
  28.801 -	</para>
  28.802 -
  28.803 -	<para>The syntaxes for the <literal
  28.804 -	    role="rc-acl.allow">acl.allow</literal> and <literal
  28.805 -	    role="rc-acl.deny">acl.deny</literal> sections are
  28.806 -	  identical.  On the left of each entry is a glob pattern that
  28.807 -	  matches files or directories, relative to the root of the
  28.808 -	  repository; on the right, a user name.
  28.809 -	</para>
  28.810 -
  28.811 -	<para>In the following example, the user
  28.812 -	  <literal>docwriter</literal> can only push changes to the
  28.813 -	  <filename class="directory">docs</filename> subtree of the
  28.814 -	  repository, while <literal>intern</literal> can push changes
  28.815 -	  to any file or directory except <filename
  28.816 -	    class="directory">source/sensitive</filename>.
  28.817 -	</para>
  28.818 -	<programlisting>[acl.allow]
  28.819 -docs/** = docwriter
  28.820 -[acl.deny]
  28.821 -source/sensitive/** = intern</programlisting>
  28.822 -
  28.823 -      </sect3>
  28.824 -      <sect3>
  28.825 -	<title>Testing and troubleshooting</title>
  28.826 -
  28.827 -	<para>If you want to test the <literal
  28.828 -	    role="hg-ext">acl</literal> hook, run it with Mercurial's
  28.829 -	  debugging output enabled.  Since you'll probably be running
  28.830 -	  it on a server where it's not convenient (or sometimes
  28.831 -	  possible) to pass in the <option
  28.832 -	    role="hg-opt-global">--debug</option> option, don't forget
  28.833 -	  that you can enable debugging output in your <filename
  28.834 -	    role="special">~/.hgrc</filename>:
  28.835 -	</para>
  28.836 -	<programlisting>[ui]
  28.837 -debug = true</programlisting>
  28.838 -	<para>With this enabled, the <literal
  28.839 -	    role="hg-ext">acl</literal> hook will print enough
  28.840 -	  information to let you figure out why it is allowing or
  28.841 -	  forbidding pushes from specific users.
  28.842 -	</para>
  28.843 -
  28.844 -      </sect3>
  28.845 -    </sect2>
  28.846 -    <sect2>
  28.847 -      <title><literal
  28.848 -	  role="hg-ext">bugzilla</literal>&emdash;integration with
  28.849 -	Bugzilla</title>
  28.850 -
  28.851 -      <para>The <literal role="hg-ext">bugzilla</literal> extension
  28.852 -	adds a comment to a Bugzilla bug whenever it finds a reference
  28.853 -	to that bug ID in a commit comment.  You can install this hook
  28.854 -	on a shared server, so that any time a remote user pushes
  28.855 -	changes to this server, the hook gets run.
  28.856 -      </para>
  28.857 -
  28.858 -      <para>It adds a comment to the bug that looks like this (you can
  28.859 -	configure the contents of the comment&emdash;see below):
  28.860 -      </para>
  28.861 -      <programlisting>Changeset aad8b264143a, made by Joe User
  28.862 -	&lt;joe.user@domain.com&gt; in the frobnitz repository, refers
  28.863 -	to this bug. For complete details, see
  28.864 -	http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a
  28.865 -	Changeset description: Fix bug 10483 by guarding against some
  28.866 -	NULL pointers</programlisting>
  28.867 -      <para>The value of this hook is that it automates the process of
  28.868 -	updating a bug any time a changeset refers to it.  If you
  28.869 -	configure the hook properly, it makes it easy for people to
  28.870 -	browse straight from a Bugzilla bug to a changeset that refers
  28.871 -	to that bug.
  28.872 -      </para>
  28.873 -
  28.874 -      <para>You can use the code in this hook as a starting point for
  28.875 -	some more exotic Bugzilla integration recipes.  Here are a few
  28.876 -	possibilities:
  28.877 -      </para>
  28.878 -      <itemizedlist>
  28.879 -	<listitem><para>Require that every changeset pushed to the
  28.880 -	    server have a valid bug ID in its commit comment.  In this
  28.881 -	    case, you'd want to configure the hook as a <literal
  28.882 -	      role="hook">pretxncommit</literal> hook.  This would
  28.883 -	    allow the hook to reject changes that didn't contain bug
  28.884 -	    IDs.
  28.885 -	  </para>
  28.886 -	</listitem>
  28.887 -	<listitem><para>Allow incoming changesets to automatically
  28.888 -	    modify the <emphasis>state</emphasis> of a bug, as well as
  28.889 -	    simply adding a comment.  For example, the hook could
  28.890 -	    recognise the string <quote>fixed bug 31337</quote> as
  28.891 -	    indicating that it should update the state of bug 31337 to
  28.892 -	    <quote>requires testing</quote>.
  28.893 -	  </para>
  28.894 -	</listitem></itemizedlist>
  28.895 -
  28.896 -      <sect3 id="sec.hook.bugzilla.config">
  28.897 -	<title>Configuring the <literal role="hook">bugzilla</literal>
  28.898 -	  hook</title>
  28.899 -
  28.900 -	<para>You should configure this hook in your server's
  28.901 -	  <filename role="special">~/.hgrc</filename> as an <literal
  28.902 -	    role="hook">incoming</literal> hook, for example as
  28.903 -	  follows:
  28.904 -	</para>
  28.905 -	<programlisting>[hooks]
  28.906 -incoming.bugzilla = python:hgext.bugzilla.hook</programlisting>
  28.907 -
  28.908 -	<para>Because of the specialised nature of this hook, and
  28.909 -	  because Bugzilla was not written with this kind of
  28.910 -	  integration in mind, configuring this hook is a somewhat
  28.911 -	  involved process.
  28.912 -	</para>
  28.913 -
  28.914 -	<para>Before you begin, you must install the MySQL bindings
  28.915 -	  for Python on the host(s) where you'll be running the hook.
  28.916 -	  If this is not available as a binary package for your
  28.917 -	  system, you can download it from
  28.918 -	  <citation>web:mysql-python</citation>.
  28.919 -	</para>
  28.920 -
  28.921 -	<para>Configuration information for this hook lives in the
  28.922 -	  <literal role="rc-bugzilla">bugzilla</literal> section of
  28.923 -	  your <filename role="special">~/.hgrc</filename>.
  28.924 -	</para>
  28.925 -	<itemizedlist>
  28.926 -	  <listitem><para><envar
  28.927 -		role="rc-item-bugzilla">version</envar>: The version
  28.928 -	      of Bugzilla installed on the server.  The database
  28.929 -	      schema that Bugzilla uses changes occasionally, so this
  28.930 -	      hook has to know exactly which schema to use. At the
  28.931 -	      moment, the only version supported is
  28.932 -	      <literal>2.16</literal>.
  28.933 -	    </para>
  28.934 -	  </listitem>
  28.935 -	  <listitem><para><envar role="rc-item-bugzilla">host</envar>:
  28.936 -	      The hostname of the MySQL server that stores your
  28.937 -	      Bugzilla data.  The database must be configured to allow
  28.938 -	      connections from whatever host you are running the
  28.939 -	      <literal role="hook">bugzilla</literal> hook on.
  28.940 -	    </para>
  28.941 -	  </listitem>
  28.942 -	  <listitem><para><envar role="rc-item-bugzilla">user</envar>:
  28.943 -	      The username with which to connect to the MySQL server.
  28.944 -	      The database must be configured to allow this user to
  28.945 -	      connect from whatever host you are running the <literal
  28.946 -		role="hook">bugzilla</literal> hook on.  This user
  28.947 -	      must be able to access and modify Bugzilla tables.  The
  28.948 -	      default value of this item is <literal>bugs</literal>,
  28.949 -	      which is the standard name of the Bugzilla user in a
  28.950 -	      MySQL database.
  28.951 -	    </para>
  28.952 -	  </listitem>
  28.953 -	  <listitem><para><envar
  28.954 -		role="rc-item-bugzilla">password</envar>: The MySQL
  28.955 -	      password for the user you configured above.  This is
  28.956 -	      stored as plain text, so you should make sure that
  28.957 -	      unauthorised users cannot read the <filename
  28.958 -		role="special">~/.hgrc</filename> file where you
  28.959 -	      store this information.
  28.960 -	    </para>
  28.961 -	  </listitem>
  28.962 -	  <listitem><para><envar role="rc-item-bugzilla">db</envar>:
  28.963 -	      The name of the Bugzilla database on the MySQL server.
  28.964 -	      The default value of this item is
  28.965 -	      <literal>bugs</literal>, which is the standard name of
  28.966 -	      the MySQL database where Bugzilla stores its data.
  28.967 -	    </para>
  28.968 -	  </listitem>
  28.969 -	  <listitem><para><envar
  28.970 -		role="rc-item-bugzilla">notify</envar>: If you want
  28.971 -	      Bugzilla to send out a notification email to subscribers
  28.972 -	      after this hook has added a comment to a bug, you will
  28.973 -	      need this hook to run a command whenever it updates the
  28.974 -	      database.  The command to run depends on where you have
  28.975 -	      installed Bugzilla, but it will typically look something
  28.976 -	      like this, if you have Bugzilla installed in <filename
  28.977 -		class="directory">/var/www/html/bugzilla</filename>:
  28.978 -	    </para>
  28.979 -	    <programlisting>cd /var/www/html/bugzilla &amp;&amp;
  28.980 -	      ./processmail %s nobody@nowhere.com</programlisting>
  28.981 -	  </listitem>
  28.982 -	  <listitem><para>  The Bugzilla
  28.983 -	      <literal>processmail</literal> program expects to be
  28.984 -	      given a bug ID (the hook replaces
  28.985 -	      <quote><literal>%s</literal></quote> with the bug ID)
  28.986 -	      and an email address.  It also expects to be able to
  28.987 -	      write to some files in the directory that it runs in.
  28.988 -	      If Bugzilla and this hook are not installed on the same
  28.989 -	      machine, you will need to find a way to run
  28.990 -	      <literal>processmail</literal> on the server where
  28.991 -	      Bugzilla is installed.
  28.992 -	    </para>
  28.993 -	  </listitem></itemizedlist>
  28.994 -
  28.995 -      </sect3>
  28.996 -      <sect3>
  28.997 -	<title>Mapping committer names to Bugzilla user names</title>
  28.998 -
  28.999 -	<para>By default, the <literal
 28.1000 -	    role="hg-ext">bugzilla</literal> hook tries to use the
 28.1001 -	  email address of a changeset's committer as the Bugzilla
 28.1002 -	  user name with which to update a bug.  If this does not suit
 28.1003 -	  your needs, you can map committer email addresses to
 28.1004 -	  Bugzilla user names using a <literal
 28.1005 -	    role="rc-usermap">usermap</literal> section.
 28.1006 -	</para>
 28.1007 -
 28.1008 -	<para>Each item in the <literal
 28.1009 -	    role="rc-usermap">usermap</literal> section contains an
 28.1010 -	  email address on the left, and a Bugzilla user name on the
 28.1011 -	  right.
 28.1012 -	</para>
 28.1013 -	<programlisting>[usermap]
 28.1014 -jane.user@example.com = jane</programlisting>
 28.1015 -	<para>You can either keep the <literal
 28.1016 -	    role="rc-usermap">usermap</literal> data in a normal
 28.1017 -	  <filename role="special">~/.hgrc</filename>, or tell the
 28.1018 -	  <literal role="hg-ext">bugzilla</literal> hook to read the
 28.1019 -	  information from an external <filename>usermap</filename>
 28.1020 -	  file.  In the latter case, you can store
 28.1021 -	  <filename>usermap</filename> data by itself in (for example)
 28.1022 -	  a user-modifiable repository.  This makes it possible to let
 28.1023 -	  your users maintain their own <envar
 28.1024 -	    role="rc-item-bugzilla">usermap</envar> entries.  The main
 28.1025 -	  <filename role="special">~/.hgrc</filename> file might look
 28.1026 -	  like this:
 28.1027 -	</para>
 28.1028 -	<programlisting># regular hgrc file refers to external usermap file
 28.1029 -[bugzilla]
 28.1030 -usermap = /home/hg/repos/userdata/bugzilla-usermap.conf</programlisting>
 28.1031 -	<para>While the <filename>usermap</filename> file that it
 28.1032 -	  refers to might look like this:
 28.1033 -	</para>
 28.1034 -	<programlisting># bugzilla-usermap.conf - inside a hg repository
 28.1035 -[usermap] stephanie@example.com = steph</programlisting>
 28.1036 -
 28.1037 -      </sect3>
 28.1038 -      <sect3>
 28.1039 -	<title>Configuring the text that gets added to a bug</title>
 28.1040 -
 28.1041 -	<para>You can configure the text that this hook adds as a
 28.1042 -	  comment; you specify it in the form of a Mercurial template.
 28.1043 -	  Several <filename role="special">~/.hgrc</filename> entries
 28.1044 -	  (still in the <literal role="rc-bugzilla">bugzilla</literal>
 28.1045 -	  section) control this behaviour.
 28.1046 -	</para>
 28.1047 -	<itemizedlist>
 28.1048 -	  <listitem><para><literal>strip</literal>: The number of
 28.1049 -	      leading path elements to strip from a repository's path
 28.1050 -	      name to construct a partial path for a URL. For example,
 28.1051 -	      if the repositories on your server live under <filename
 28.1052 -		class="directory">/home/hg/repos</filename>, and you
 28.1053 -	      have a repository whose path is <filename
 28.1054 -		class="directory">/home/hg/repos/app/tests</filename>,
 28.1055 -	      then setting <literal>strip</literal> to
 28.1056 -	      <literal>4</literal> will give a partial path of
 28.1057 -	      <filename class="directory">app/tests</filename>.  The
 28.1058 -	      hook will make this partial path available when
 28.1059 -	      expanding a template, as <literal>webroot</literal>.
 28.1060 -	    </para>
 28.1061 -	  </listitem>
 28.1062 -	  <listitem><para><literal>template</literal>: The text of the
 28.1063 -	      template to use.  In addition to the usual
 28.1064 -	      changeset-related variables, this template can use
 28.1065 -	      <literal>hgweb</literal> (the value of the
 28.1066 -	      <literal>hgweb</literal> configuration item above) and
 28.1067 -	      <literal>webroot</literal> (the path constructed using
 28.1068 -	      <literal>strip</literal> above).
 28.1069 -	    </para>
 28.1070 -	  </listitem></itemizedlist>
 28.1071 -
 28.1072 -	<para>In addition, you can add a <envar
 28.1073 -	    role="rc-item-web">baseurl</envar> item to the <literal
 28.1074 -	    role="rc-web">web</literal> section of your <filename
 28.1075 -	    role="special">~/.hgrc</filename>.  The <literal
 28.1076 -	    role="hg-ext">bugzilla</literal> hook will make this
 28.1077 -	  available when expanding a template, as the base string to
 28.1078 -	  use when constructing a URL that will let users browse from
 28.1079 -	  a Bugzilla comment to view a changeset.  Example:
 28.1080 -	</para>
 28.1081 -	<programlisting>[web]
 28.1082 -baseurl = http://hg.domain.com/</programlisting>
 28.1083 -
 28.1084 -	<para>Here is an example set of <literal
 28.1085 -	    role="hg-ext">bugzilla</literal> hook config information.
 28.1086 -	</para>
 28.1087 -
 28.1088 -	<programlisting>&ch10-bugzilla-config.lst;</programlisting>
 28.1089 -
 28.1090 -      </sect3>
 28.1091 -      <sect3>
 28.1092 -	<title>Testing and troubleshooting</title>
 28.1093 -
 28.1094 -	<para>The most common problems with configuring the <literal
 28.1095 -	    role="hg-ext">bugzilla</literal> hook relate to running
 28.1096 -	  Bugzilla's <filename>processmail</filename> script and
 28.1097 -	  mapping committer names to user names.
 28.1098 -	</para>
 28.1099 -
 28.1100 -	<para>Recall from section <xref
 28.1101 -	    linkend="sec.hook.bugzilla.config"/> above that the user
 28.1102 -	  that runs the Mercurial process on the server is also the
 28.1103 -	  one that will run the <filename>processmail</filename>
 28.1104 -	  script.  The <filename>processmail</filename> script
 28.1105 -	  sometimes causes Bugzilla to write to files in its
 28.1106 -	  configuration directory, and Bugzilla's configuration files
 28.1107 -	  are usually owned by the user that your web server runs
 28.1108 -	  under.
 28.1109 -	</para>
 28.1110 -
 28.1111 -	<para>You can cause <filename>processmail</filename> to be run
 28.1112 -	  with the suitable user's identity using the
 28.1113 -	  <command>sudo</command> command.  Here is an example entry
 28.1114 -	  for a <filename>sudoers</filename> file.
 28.1115 -	</para>
 28.1116 -	<programlisting>hg_user = (httpd_user)
 28.1117 -NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s</programlisting>
 28.1118 -	<para>This allows the <literal>hg_user</literal> user to run a
 28.1119 -	  <filename>processmail-wrapper</filename> program under the
 28.1120 -	  identity of <literal>httpd_user</literal>.
 28.1121 -	</para>
 28.1122 -
 28.1123 -	<para>This indirection through a wrapper script is necessary,
 28.1124 -	  because <filename>processmail</filename> expects to be run
 28.1125 -	  with its current directory set to wherever you installed
 28.1126 -	  Bugzilla; you can't specify that kind of constraint in a
 28.1127 -	  <filename>sudoers</filename> file.  The contents of the
 28.1128 -	  wrapper script are simple:
 28.1129 -	</para>
 28.1130 -	<programlisting>#!/bin/sh
 28.1131 -cd `dirname $0` &amp;&amp; ./processmail "$1" nobody@example.com</programlisting>
 28.1132 -	<para>It doesn't seem to matter what email address you pass to
 28.1133 -	  <filename>processmail</filename>.
 28.1134 -	</para>
 28.1135 -
 28.1136 -	<para>If your <literal role="rc-usermap">usermap</literal> is
 28.1137 -	  not set up correctly, users will see an error message from
 28.1138 -	  the <literal role="hg-ext">bugzilla</literal> hook when they
 28.1139 -	  push changes to the server.  The error message will look
 28.1140 -	  like this:
 28.1141 -	</para>
 28.1142 -	<programlisting>cannot find bugzilla user id for john.q.public@example.com</programlisting>
 28.1143 -	<para>What this means is that the committer's address,
 28.1144 -	  <literal>john.q.public@example.com</literal>, is not a valid
 28.1145 -	  Bugzilla user name, nor does it have an entry in your
 28.1146 -	  <literal role="rc-usermap">usermap</literal> that maps it to
 28.1147 -	  a valid Bugzilla user name.
 28.1148 -	</para>
 28.1149 -
 28.1150 -      </sect3>
 28.1151 -    </sect2>
 28.1152 -    <sect2>
 28.1153 -      <title><literal role="hg-ext">notify</literal>&emdash;send email
 28.1154 -	notifications</title>
 28.1155 -
 28.1156 -      <para>Although Mercurial's built-in web server provides RSS
 28.1157 -	feeds of changes in every repository, many people prefer to
 28.1158 -	receive change notifications via email.  The <literal
 28.1159 -	  role="hg-ext">notify</literal> hook lets you send out
 28.1160 -	notifications to a set of email addresses whenever changesets
 28.1161 -	arrive that those subscribers are interested in.
 28.1162 -      </para>
 28.1163 -
 28.1164 -      <para>As with the <literal role="hg-ext">bugzilla</literal>
 28.1165 -	hook, the <literal role="hg-ext">notify</literal> hook is
 28.1166 -	template-driven, so you can customise the contents of the
 28.1167 -	notification messages that it sends.
 28.1168 -      </para>
 28.1169 -
 28.1170 -      <para>By default, the <literal role="hg-ext">notify</literal>
 28.1171 -	hook includes a diff of every changeset that it sends out; you
 28.1172 -	can limit the size of the diff, or turn this feature off
 28.1173 -	entirely.  It is useful for letting subscribers review changes
 28.1174 -	immediately, rather than clicking to follow a URL.
 28.1175 -      </para>
 28.1176 -
 28.1177 -      <sect3>
 28.1178 -	<title>Configuring the <literal role="hg-ext">notify</literal>
 28.1179 -	  hook</title>
 28.1180 -
 28.1181 -	<para>You can set up the <literal
 28.1182 -	    role="hg-ext">notify</literal> hook to send one email
 28.1183 -	  message per incoming changeset, or one per incoming group of
 28.1184 -	  changesets (all those that arrived in a single pull or
 28.1185 -	  push).
 28.1186 -	</para>
 28.1187 -	<programlisting>[hooks]
 28.1188 -# send one email per group of changes
 28.1189 -changegroup.notify = python:hgext.notify.hook
 28.1190 -# send one email per change
 28.1191 -incoming.notify = python:hgext.notify.hook</programlisting>
 28.1192 -
 28.1193 -	<para>Configuration information for this hook lives in the
 28.1194 -	  <literal role="rc-notify">notify</literal> section of a
 28.1195 -	  <filename role="special">~/.hgrc</filename> file.
 28.1196 -	</para>
 28.1197 -	<itemizedlist>
 28.1198 -	  <listitem><para><envar role="rc-item-notify">test</envar>:
 28.1199 -	      By default, this hook does not send out email at all;
 28.1200 -	      instead, it prints the message that it
 28.1201 -	      <emphasis>would</emphasis> send.  Set this item to
 28.1202 -	      <literal>false</literal> to allow email to be sent. The
 28.1203 -	      reason that sending of email is turned off by default is
 28.1204 -	      that it takes several tries to configure this extension
 28.1205 -	      exactly as you would like, and it would be bad form to
 28.1206 -	      spam subscribers with a number of <quote>broken</quote>
 28.1207 -	      notifications while you debug your configuration.
 28.1208 -	    </para>
 28.1209 -	  </listitem>
 28.1210 -	  <listitem><para><envar role="rc-item-notify">config</envar>:
 28.1211 -	      The path to a configuration file that contains
 28.1212 -	      subscription information.  This is kept separate from
 28.1213 -	      the main <filename role="special">~/.hgrc</filename> so
 28.1214 -	      that you can maintain it in a repository of its own.
 28.1215 -	      People can then clone that repository, update their
 28.1216 -	      subscriptions, and push the changes back to your server.
 28.1217 -	    </para>
 28.1218 -	  </listitem>
 28.1219 -	  <listitem><para><envar role="rc-item-notify">strip</envar>:
 28.1220 -	      The number of leading path separator characters to strip
 28.1221 -	      from a repository's path, when deciding whether a
 28.1222 -	      repository has subscribers.  For example, if the
 28.1223 -	      repositories on your server live in <filename
 28.1224 -		class="directory">/home/hg/repos</filename>, and
 28.1225 -	      <literal role="hg-ext">notify</literal> is considering a
 28.1226 -	      repository named <filename
 28.1227 -		class="directory">/home/hg/repos/shared/test</filename>, 
 28.1228 -	      setting <envar role="rc-item-notify">strip</envar> to
 28.1229 -	      <literal>4</literal> will cause <literal
 28.1230 -		role="hg-ext">notify</literal> to trim the path it
 28.1231 -	      considers down to <filename
 28.1232 -		class="directory">shared/test</filename>, and it will
 28.1233 -	      match subscribers against that.
 28.1234 -	    </para>
 28.1235 -	  </listitem>
 28.1236 -	  <listitem><para><envar
 28.1237 -		role="rc-item-notify">template</envar>: The template
 28.1238 -	      text to use when sending messages.  This specifies both
 28.1239 -	      the contents of the message header and its body.
 28.1240 -	    </para>
 28.1241 -	  </listitem>
 28.1242 -	  <listitem><para><envar
 28.1243 -		role="rc-item-notify">maxdiff</envar>: The maximum
 28.1244 -	      number of lines of diff data to append to the end of a
 28.1245 -	      message.  If a diff is longer than this, it is
 28.1246 -	      truncated.  By default, this is set to 300.  Set this to
 28.1247 -	      <literal>0</literal> to omit diffs from notification
 28.1248 -	      emails.
 28.1249 -	    </para>
 28.1250 -	  </listitem>
 28.1251 -	  <listitem><para><envar
 28.1252 -		role="rc-item-notify">sources</envar>: A list of
 28.1253 -	      sources of changesets to consider.  This lets you limit
 28.1254 -	      <literal role="hg-ext">notify</literal> to only sending
 28.1255 -	      out email about changes that remote users pushed into
 28.1256 -	      this repository via a server, for example.  See section
 28.1257 -	      <xref
 28.1258 -		linkend="sec.hook.sources"/> for the sources you can
 28.1259 -	      specify here.
 28.1260 -	    </para>
 28.1261 -	  </listitem></itemizedlist>
 28.1262 -
 28.1263 -	<para>If you set the <envar role="rc-item-web">baseurl</envar>
 28.1264 -	  item in the <literal role="rc-web">web</literal> section,
 28.1265 -	  you can use it in a template; it will be available as
 28.1266 -	  <literal>webroot</literal>.
 28.1267 -	</para>
 28.1268 -
 28.1269 -	<para>Here is an example set of <literal
 28.1270 -	    role="hg-ext">notify</literal> configuration information.
 28.1271 -	</para>
 28.1272 -
 28.1273 -	<programlisting>&ch10-notify-config.lst;</programlisting>
 28.1274 -
 28.1275 -	<para>This will produce a message that looks like the
 28.1276 -	  following:
 28.1277 -	</para>
 28.1278 -
 28.1279 -	<programlisting>&ch10-notify-config-mail.lst;</programlisting>
 28.1280 -
 28.1281 -      </sect3>
 28.1282 -      <sect3>
 28.1283 -	<title>Testing and troubleshooting</title>
 28.1284 -
 28.1285 -	<para>Do not forget that by default, the <literal
 28.1286 -		role="hg-ext">notify</literal> extension <emphasis>will not
 28.1287 -	  send any mail</emphasis> until you explicitly configure it to do so,
 28.1288 -	  by setting <envar role="rc-item-notify">test</envar> to
 28.1289 -	  <literal>false</literal>.  Until you do that, it simply
 28.1290 -	  prints the message it <emphasis>would</emphasis> send.
 28.1291 -	</para>
 28.1292 -
 28.1293 -      </sect3>
 28.1294 -    </sect2>
 28.1295 -  </sect1>
 28.1296 -  <sect1 id="sec.hook.ref">
 28.1297 -    <title>Information for writers of hooks</title>
 28.1298 -
 28.1299 -    <sect2>
 28.1300 -      <title>In-process hook execution</title>
 28.1301 -
 28.1302 -      <para>An in-process hook is called with arguments of the
 28.1303 -	following form:
 28.1304 -      </para>
 28.1305 -      <programlisting>def myhook(ui, repo, **kwargs): pass</programlisting>
 28.1306 -      <para>The <literal>ui</literal> parameter is a <literal
 28.1307 -	  role="py-mod-mercurial.ui">ui</literal> object. The
 28.1308 -	<literal>repo</literal> parameter is a <literal
 28.1309 -	  role="py-mod-mercurial.localrepo">localrepository</literal>
 28.1310 -	object.  The names and values of the
 28.1311 -	<literal>**kwargs</literal> parameters depend on the hook
 28.1312 -	being invoked, with the following common features:
 28.1313 -      </para>
 28.1314 -      <itemizedlist>
 28.1315 -	<listitem><para>If a parameter is named
 28.1316 -	    <literal>node</literal> or <literal>parentN</literal>, it
 28.1317 -	    will contain a hexadecimal changeset ID. The empty string
 28.1318 -	    is used to represent <quote>null changeset ID</quote>
 28.1319 -	    instead of a string of zeroes.
 28.1320 -	  </para>
 28.1321 -	</listitem>
 28.1322 -	<listitem><para>If a parameter is named
 28.1323 -	    <literal>url</literal>, it will contain the URL of a
 28.1324 -	    remote repository, if that can be determined.
 28.1325 -	  </para>
 28.1326 -	</listitem>
 28.1327 -	<listitem><para>Boolean-valued parameters are represented as
 28.1328 -	    Python <literal>bool</literal> objects.
 28.1329 -	  </para>
 28.1330 -	</listitem></itemizedlist>
 28.1331 -
 28.1332 -      <para>An in-process hook is called without a change to the
 28.1333 -	process's working directory (unlike external hooks, which are
 28.1334 -	run in the root of the repository).  It must not change the
 28.1335 -	process's working directory, or it will cause any calls it
 28.1336 -	makes into the Mercurial API to fail.
 28.1337 -      </para>
 28.1338 -
 28.1339 -      <para>If a hook returns a boolean <quote>false</quote> value, it
 28.1340 -	is considered to have succeeded.  If it returns a boolean
 28.1341 -	<quote>true</quote> value or raises an exception, it is
 28.1342 -	considered to have failed.  A useful way to think of the
 28.1343 -	calling convention is <quote>tell me if you fail</quote>.
 28.1344 -      </para>
 28.1345 -
 28.1346 -      <para>Note that changeset IDs are passed into Python hooks as
 28.1347 -	hexadecimal strings, not the binary hashes that Mercurial's
 28.1348 -	APIs normally use.  To convert a hash from hex to binary, use
 28.1349 -	the <literal>bin</literal> function.
 28.1350 -      </para>
 28.1351 -
 28.1352 -    </sect2>
 28.1353 -    <sect2>
 28.1354 -      <title>External hook execution</title>
 28.1355 -
 28.1356 -      <para>An external hook is passed to the shell of the user
 28.1357 -	running Mercurial. Features of that shell, such as variable
 28.1358 -	substitution and command redirection, are available.  The hook
 28.1359 -	is run in the root directory of the repository (unlike
 28.1360 -	in-process hooks, which are run in the same directory that
 28.1361 -	Mercurial was run in).
 28.1362 -      </para>
 28.1363 -
 28.1364 -      <para>Hook parameters are passed to the hook as environment
 28.1365 -	variables.  Each environment variable's name is converted in
 28.1366 -	upper case and prefixed with the string
 28.1367 -	<quote><literal>HG_</literal></quote>.  For example, if the
 28.1368 -	name of a parameter is <quote><literal>node</literal></quote>,
 28.1369 -	the name of the environment variable representing that
 28.1370 -	parameter will be <quote><literal>HG_NODE</literal></quote>.
 28.1371 -      </para>
 28.1372 -
 28.1373 -      <para>A boolean parameter is represented as the string
 28.1374 -	<quote><literal>1</literal></quote> for <quote>true</quote>,
 28.1375 -	<quote><literal>0</literal></quote> for <quote>false</quote>.
 28.1376 -	If an environment variable is named <envar>HG_NODE</envar>,
 28.1377 -	<envar>HG_PARENT1</envar> or <envar>HG_PARENT2</envar>, it
 28.1378 -	contains a changeset ID represented as a hexadecimal string.
 28.1379 -	The empty string is used to represent <quote>null changeset
 28.1380 -	  ID</quote> instead of a string of zeroes.  If an environment
 28.1381 -	variable is named <envar>HG_URL</envar>, it will contain the
 28.1382 -	URL of a remote repository, if that can be determined.
 28.1383 -      </para>
 28.1384 -
 28.1385 -      <para>If a hook exits with a status of zero, it is considered to
 28.1386 -	have succeeded.  If it exits with a non-zero status, it is
 28.1387 -	considered to have failed.
 28.1388 -      </para>
 28.1389 -
 28.1390 -    </sect2>
 28.1391 -    <sect2>
 28.1392 -      <title>Finding out where changesets come from</title>
 28.1393 -
 28.1394 -      <para>A hook that involves the transfer of changesets between a
 28.1395 -	local repository and another may be able to find out
 28.1396 -	information about the <quote>far side</quote>.  Mercurial
 28.1397 -	knows <emphasis>how</emphasis> changes are being transferred,
 28.1398 -	and in many cases <emphasis>where</emphasis> they are being
 28.1399 -	transferred to or from.
 28.1400 -      </para>
 28.1401 -
 28.1402 -      <sect3 id="sec.hook.sources">
 28.1403 -	<title>Sources of changesets</title>
 28.1404 -
 28.1405 -	<para>Mercurial will tell a hook what means are, or were, used
 28.1406 -	  to transfer changesets between repositories.  This is
 28.1407 -	  provided by Mercurial in a Python parameter named
 28.1408 -	  <literal>source</literal>, or an environment variable named
 28.1409 -	  <envar>HG_SOURCE</envar>.
 28.1410 -	</para>
 28.1411 -
 28.1412 -	<itemizedlist>
 28.1413 -	  <listitem><para><literal>serve</literal>: Changesets are
 28.1414 -	      transferred to or from a remote repository over http or
 28.1415 -	      ssh.
 28.1416 -	    </para>
 28.1417 -	  </listitem>
 28.1418 -	  <listitem><para><literal>pull</literal>: Changesets are
 28.1419 -	      being transferred via a pull from one repository into
 28.1420 -	      another.
 28.1421 -	    </para>
 28.1422 -	  </listitem>
 28.1423 -	  <listitem><para><literal>push</literal>: Changesets are
 28.1424 -	      being transferred via a push from one repository into
 28.1425 -	      another.
 28.1426 -	    </para>
 28.1427 -	  </listitem>
 28.1428 -	  <listitem><para><literal>bundle</literal>: Changesets are
 28.1429 -	      being transferred to or from a bundle.
 28.1430 -	    </para>
 28.1431 -	  </listitem></itemizedlist>
 28.1432 -
 28.1433 -      </sect3>
 28.1434 -      <sect3 id="sec.hook.url">
 28.1435 -	<title>Where changes are going&emdash;remote repository
 28.1436 -	  URLs</title>
 28.1437 -
 28.1438 -	<para>When possible, Mercurial will tell a hook the location
 28.1439 -	  of the <quote>far side</quote> of an activity that transfers
 28.1440 -	  changeset data between repositories.  This is provided by
 28.1441 -	  Mercurial in a Python parameter named
 28.1442 -	  <literal>url</literal>, or an environment variable named
 28.1443 -	  <envar>HG_URL</envar>.
 28.1444 -	</para>
 28.1445 -
 28.1446 -	<para>This information is not always known.  If a hook is
 28.1447 -	  invoked in a repository that is being served via http or
 28.1448 -	  ssh, Mercurial cannot tell where the remote repository is,
 28.1449 -	  but it may know where the client is connecting from.  In
 28.1450 -	  such cases, the URL will take one of the following forms:
 28.1451 -	</para>
 28.1452 -	<itemizedlist>
 28.1453 -	  <listitem><para><literal>remote:ssh:1.2.3.4</literal>&emdash;remote 
 28.1454 -	      ssh client, at the IP address
 28.1455 -	      <literal>1.2.3.4</literal>.
 28.1456 -	    </para>
 28.1457 -	  </listitem>
 28.1458 -	  <listitem><para><literal>remote:http:1.2.3.4</literal>&emdash;remote 
 28.1459 -	      http client, at the IP address
 28.1460 -	      <literal>1.2.3.4</literal>.  If the client is using SSL,
 28.1461 -	      this will be of the form
 28.1462 -	      <literal>remote:https:1.2.3.4</literal>.
 28.1463 -	    </para>
 28.1464 -	  </listitem>
 28.1465 -	  <listitem><para>Empty&emdash;no information could be
 28.1466 -	      discovered about the remote client.
 28.1467 -	    </para>
 28.1468 -	  </listitem></itemizedlist>
 28.1469 -
 28.1470 -      </sect3>
 28.1471 -    </sect2>
 28.1472 -  </sect1>
 28.1473 -  <sect1>
 28.1474 -    <title>Hook reference</title>
 28.1475 -
 28.1476 -    <sect2 id="sec.hook.changegroup">
 28.1477 -      <title><literal role="hook">changegroup</literal>&emdash;after
 28.1478 -	remote changesets added</title>
 28.1479 -
 28.1480 -      <para>This hook is run after a group of pre-existing changesets
 28.1481 -	has been added to the repository, for example via a <command
 28.1482 -	  role="hg-cmd">hg pull</command> or <command role="hg-cmd">hg
 28.1483 -	  unbundle</command>.  This hook is run once per operation
 28.1484 -	that added one or more changesets.  This is in contrast to the
 28.1485 -	<literal role="hook">incoming</literal> hook, which is run
 28.1486 -	once per changeset, regardless of whether the changesets
 28.1487 -	arrive in a group.
 28.1488 -      </para>
 28.1489 -
 28.1490 -      <para>Some possible uses for this hook include kicking off an
 28.1491 -	automated build or test of the added changesets, updating a
 28.1492 -	bug database, or notifying subscribers that a repository
 28.1493 -	contains new changes.
 28.1494 -      </para>
 28.1495 -
 28.1496 -      <para>Parameters to this hook:
 28.1497 -      </para>
 28.1498 -      <itemizedlist>
 28.1499 -	<listitem><para><literal>node</literal>: A changeset ID.  The
 28.1500 -	    changeset ID of the first changeset in the group that was
 28.1501 -	    added.  All changesets between this and
 28.1502 -	    <literal role="tag">tip</literal>, inclusive, were added by a single
 28.1503 -	    <command role="hg-cmd">hg pull</command>, <command
 28.1504 -	      role="hg-cmd">hg push</command> or <command
 28.1505 -	      role="hg-cmd">hg unbundle</command>.
 28.1506 -	  </para>
 28.1507 -	</listitem>
 28.1508 -	<listitem><para><literal>source</literal>: A string.  The
 28.1509 -	    source of these changes.  See section <xref
 28.1510 -	      linkend="sec.hook.sources"/> for details.
 28.1511 -	  </para>
 28.1512 -	</listitem>
 28.1513 -	<listitem><para><literal>url</literal>: A URL.  The location
 28.1514 -	    of the remote repository, if known.  See section <xref
 28.1515 -	      linkend="sec.hook.url"/> for more
 28.1516 -	    information.
 28.1517 -	  </para>
 28.1518 -	</listitem></itemizedlist>
 28.1519 -
 28.1520 -      <para>See also: <literal role="hook">incoming</literal> (section
 28.1521 -	<xref linkend="sec.hook.incoming"/>), <literal
 28.1522 -	  role="hook">prechangegroup</literal> (section <xref
 28.1523 -	  linkend="sec.hook.prechangegroup"/>), <literal
 28.1524 -	  role="hook">pretxnchangegroup</literal> (section <xref
 28.1525 -	  linkend="sec.hook.pretxnchangegroup"/>)
 28.1526 -      </para>
 28.1527 -
 28.1528 -    </sect2>
 28.1529 -    <sect2 id="sec.hook.commit">
 28.1530 -      <title><literal role="hook">commit</literal>&emdash;after a new
 28.1531 -	changeset is created</title>
 28.1532 -
 28.1533 -      <para>This hook is run after a new changeset has been created.
 28.1534 -      </para>
 28.1535 -
 28.1536 -      <para>Parameters to this hook:
 28.1537 -      </para>
 28.1538 -      <itemizedlist>
 28.1539 -	<listitem><para><literal>node</literal>: A changeset ID.  The
 28.1540 -	    changeset ID of the newly committed changeset.
 28.1541 -	  </para>
 28.1542 -	</listitem>
 28.1543 -	<listitem><para><literal>parent1</literal>: A changeset ID.
 28.1544 -	    The changeset ID of the first parent of the newly
 28.1545 -	    committed changeset.
 28.1546 -	  </para>
 28.1547 -	</listitem>
 28.1548 -	<listitem><para><literal>parent2</literal>: A changeset ID.
 28.1549 -	    The changeset ID of the second parent of the newly
 28.1550 -	    committed changeset.
 28.1551 -	  </para>
 28.1552 -	</listitem></itemizedlist>
 28.1553 -
 28.1554 -      <para>See also: <literal role="hook">precommit</literal>
 28.1555 -	(section <xref linkend="sec.hook.precommit"/>), <literal
 28.1556 -	  role="hook">pretxncommit</literal> (section <xref
 28.1557 -	  linkend="sec.hook.pretxncommit"/>)
 28.1558 -      </para>
 28.1559 -
 28.1560 -    </sect2>
 28.1561 -    <sect2 id="sec.hook.incoming">
 28.1562 -      <title><literal role="hook">incoming</literal>&emdash;after one
 28.1563 -	remote changeset is added</title>
 28.1564 -
 28.1565 -      <para>This hook is run after a pre-existing changeset has been
 28.1566 -	added to the repository, for example via a <command
 28.1567 -	  role="hg-cmd">hg push</command>.  If a group of changesets
 28.1568 -	was added in a single operation, this hook is called once for
 28.1569 -	each added changeset.
 28.1570 -      </para>
 28.1571 -
 28.1572 -      <para>You can use this hook for the same purposes as the
 28.1573 -	<literal role="hook">changegroup</literal> hook (section <xref
 28.1574 -	  linkend="sec.hook.changegroup"/>); it's simply
 28.1575 -	more convenient sometimes to run a hook once per group of
 28.1576 -	changesets, while other times it's handier once per changeset.
 28.1577 -      </para>
 28.1578 -
 28.1579 -      <para>Parameters to this hook:
 28.1580 -      </para>
 28.1581 -      <itemizedlist>
 28.1582 -	<listitem><para><literal>node</literal>: A changeset ID.  The
 28.1583 -	    ID of the newly added changeset.
 28.1584 -	  </para>
 28.1585 -	</listitem>
 28.1586 -	<listitem><para><literal>source</literal>: A string.  The
 28.1587 -	    source of these changes.  See section <xref
 28.1588 -	      linkend="sec.hook.sources"/> for details.
 28.1589 -	  </para>
 28.1590 -	</listitem>
 28.1591 -	<listitem><para><literal>url</literal>: A URL.  The location
 28.1592 -	    of the remote repository, if known.  See section <xref
 28.1593 -	      linkend="sec.hook.url"/> for more
 28.1594 -	    information.
 28.1595 -	  </para>
 28.1596 -	</listitem></itemizedlist>
 28.1597 -
 28.1598 -      <para>See also: <literal role="hook">changegroup</literal>
 28.1599 -	(section <xref linkend="sec.hook.changegroup"/>) <literal
 28.1600 -	  role="hook">prechangegroup</literal> (section <xref
 28.1601 -	  linkend="sec.hook.prechangegroup"/>), <literal
 28.1602 -	  role="hook">pretxnchangegroup</literal> (section <xref
 28.1603 -	  linkend="sec.hook.pretxnchangegroup"/>)
 28.1604 -      </para>
 28.1605 -
 28.1606 -    </sect2>
 28.1607 -    <sect2 id="sec.hook.outgoing">
 28.1608 -      <title><literal role="hook">outgoing</literal>&emdash;after
 28.1609 -	changesets are propagated</title>
 28.1610 -
 28.1611 -      <para>This hook is run after a group of changesets has been
 28.1612 -	propagated out of this repository, for example by a <command
 28.1613 -	  role="hg-cmd">hg push</command> or <command role="hg-cmd">hg
 28.1614 -	  bundle</command> command.
 28.1615 -      </para>
 28.1616 -
 28.1617 -      <para>One possible use for this hook is to notify administrators
 28.1618 -	that changes have been pulled.
 28.1619 -      </para>
 28.1620 -
 28.1621 -      <para>Parameters to this hook:
 28.1622 -      </para>
 28.1623 -      <itemizedlist>
 28.1624 -	<listitem><para><literal>node</literal>: A changeset ID.  The
 28.1625 -	    changeset ID of the first changeset of the group that was
 28.1626 -	    sent.
 28.1627 -	  </para>
 28.1628 -	</listitem>
 28.1629 -	<listitem><para><literal>source</literal>: A string.  The
 28.1630 -	    source of the of the operation (see section <xref
 28.1631 -	      linkend="sec.hook.sources"/>).  If a remote
 28.1632 -	    client pulled changes from this repository,
 28.1633 -	    <literal>source</literal> will be
 28.1634 -	    <literal>serve</literal>.  If the client that obtained
 28.1635 -	    changes from this repository was local,
 28.1636 -	    <literal>source</literal> will be
 28.1637 -	    <literal>bundle</literal>, <literal>pull</literal>, or
 28.1638 -	    <literal>push</literal>, depending on the operation the
 28.1639 -	    client performed.
 28.1640 -	  </para>
 28.1641 -	</listitem>
 28.1642 -	<listitem><para><literal>url</literal>: A URL.  The location
 28.1643 -	    of the remote repository, if known.  See section <xref
 28.1644 -	      linkend="sec.hook.url"/> for more
 28.1645 -	    information.
 28.1646 -	  </para>
 28.1647 -	</listitem></itemizedlist>
 28.1648 -
 28.1649 -      <para>See also: <literal role="hook">preoutgoing</literal>
 28.1650 -	(section <xref linkend="sec.hook.preoutgoing"/>)
 28.1651 -      </para>
 28.1652 -
 28.1653 -    </sect2>
 28.1654 -    <sect2 id="sec.hook.prechangegroup">
 28.1655 -      <title><literal
 28.1656 -	  role="hook">prechangegroup</literal>&emdash;before starting
 28.1657 -	to add remote changesets</title>
 28.1658 -
 28.1659 -      <para>This controlling hook is run before Mercurial begins to
 28.1660 -	add a group of changesets from another repository.
 28.1661 -      </para>
 28.1662 -
 28.1663 -      <para>This hook does not have any information about the
 28.1664 -	changesets to be added, because it is run before transmission
 28.1665 -	of those changesets is allowed to begin.  If this hook fails,
 28.1666 -	the changesets will not be transmitted.
 28.1667 -      </para>
 28.1668 -
 28.1669 -      <para>One use for this hook is to prevent external changes from
 28.1670 -	being added to a repository.  For example, you could use this
 28.1671 -	to <quote>freeze</quote> a server-hosted branch temporarily or
 28.1672 -	permanently so that users cannot push to it, while still
 28.1673 -	allowing a local administrator to modify the repository.
 28.1674 -      </para>
 28.1675 -
 28.1676 -      <para>Parameters to this hook:
 28.1677 -      </para>
 28.1678 -      <itemizedlist>
 28.1679 -	<listitem><para><literal>source</literal>: A string.  The
 28.1680 -	    source of these changes.  See section <xref
 28.1681 -	      linkend="sec.hook.sources"/> for details.
 28.1682 -	  </para>
 28.1683 -	</listitem>
 28.1684 -	<listitem><para><literal>url</literal>: A URL.  The location
 28.1685 -	    of the remote repository, if known.  See section <xref
 28.1686 -	      linkend="sec.hook.url"/> for more
 28.1687 -	    information.
 28.1688 -	  </para>
 28.1689 -	</listitem></itemizedlist>
 28.1690 -
 28.1691 -      <para>See also: <literal role="hook">changegroup</literal>
 28.1692 -	(section <xref linkend="sec.hook.changegroup"/>), <literal
 28.1693 -	  role="hook">incoming</literal> (section <xref
 28.1694 -	  linkend="sec.hook.incoming"/>), , <literal
 28.1695 -	  role="hook">pretxnchangegroup</literal> (section <xref
 28.1696 -	  linkend="sec.hook.pretxnchangegroup"/>)
 28.1697 -      </para>
 28.1698 -
 28.1699 -    </sect2>
 28.1700 -    <sect2 id="sec.hook.precommit">
 28.1701 -      <title><literal role="hook">precommit</literal>&emdash;before
 28.1702 -	starting to commit a changeset</title>
 28.1703 -
 28.1704 -      <para>This hook is run before Mercurial begins to commit a new
 28.1705 -	changeset. It is run before Mercurial has any of the metadata
 28.1706 -	for the commit, such as the files to be committed, the commit
 28.1707 -	message, or the commit date.
 28.1708 -      </para>
 28.1709 -
 28.1710 -      <para>One use for this hook is to disable the ability to commit
 28.1711 -	new changesets, while still allowing incoming changesets.
 28.1712 -	Another is to run a build or test, and only allow the commit
 28.1713 -	to begin if the build or test succeeds.
 28.1714 -      </para>
 28.1715 -
 28.1716 -      <para>Parameters to this hook:
 28.1717 -      </para>
 28.1718 -      <itemizedlist>
 28.1719 -	<listitem><para><literal>parent1</literal>: A changeset ID.
 28.1720 -	    The changeset ID of the first parent of the working
 28.1721 -	    directory.
 28.1722 -	  </para>
 28.1723 -	</listitem>
 28.1724 -	<listitem><para><literal>parent2</literal>: A changeset ID.
 28.1725 -	    The changeset ID of the second parent of the working
 28.1726 -	    directory.
 28.1727 -	  </para>
 28.1728 -	</listitem></itemizedlist>
 28.1729 -      <para>If the commit proceeds, the parents of the working
 28.1730 -	directory will become the parents of the new changeset.
 28.1731 -      </para>
 28.1732 -
 28.1733 -      <para>See also: <literal role="hook">commit</literal> (section
 28.1734 -	<xref linkend="sec.hook.commit"/>), <literal
 28.1735 -	  role="hook">pretxncommit</literal> (section <xref
 28.1736 -	  linkend="sec.hook.pretxncommit"/>)
 28.1737 -      </para>
 28.1738 -
 28.1739 -    </sect2>
 28.1740 -    <sect2 id="sec.hook.preoutgoing">
 28.1741 -      <title><literal role="hook">preoutgoing</literal>&emdash;before
 28.1742 -	starting to propagate changesets</title>
 28.1743 -
 28.1744 -      <para>This hook is invoked before Mercurial knows the identities
 28.1745 -	of the changesets to be transmitted.
 28.1746 -      </para>
 28.1747 -
 28.1748 -      <para>One use for this hook is to prevent changes from being
 28.1749 -	transmitted to another repository.
 28.1750 -      </para>
 28.1751 -
 28.1752 -      <para>Parameters to this hook:
 28.1753 -      </para>
 28.1754 -      <itemizedlist>
 28.1755 -	<listitem><para><literal>source</literal>: A string.  The
 28.1756 -	    source of the operation that is attempting to obtain
 28.1757 -	    changes from this repository (see section <xref
 28.1758 -	      linkend="sec.hook.sources"/>).  See the documentation
 28.1759 -	    for the <literal>source</literal> parameter to the
 28.1760 -	    <literal role="hook">outgoing</literal> hook, in section
 28.1761 -	    <xref linkend="sec.hook.outgoing"/>, for possible values
 28.1762 -	    of
 28.1763 -	    this parameter.
 28.1764 -	  </para>
 28.1765 -	</listitem>
 28.1766 -	<listitem><para><literal>url</literal>: A URL.  The location
 28.1767 -	    of the remote repository, if known.  See section <xref
 28.1768 -	      linkend="sec.hook.url"/> for more
 28.1769 -	    information.
 28.1770 -	  </para>
 28.1771 -	</listitem></itemizedlist>
 28.1772 -
 28.1773 -      <para>See also: <literal role="hook">outgoing</literal> (section
 28.1774 -	<xref linkend="sec.hook.outgoing"/>)
 28.1775 -      </para>
 28.1776 -
 28.1777 -    </sect2>
 28.1778 -    <sect2 id="sec.hook.pretag">
 28.1779 -      <title><literal role="hook">pretag</literal>&emdash;before
 28.1780 -	tagging a changeset</title>
 28.1781 -
 28.1782 -      <para>This controlling hook is run before a tag is created.  If
 28.1783 -	the hook succeeds, creation of the tag proceeds.  If the hook
 28.1784 -	fails, the tag is not created.
 28.1785 -      </para>
 28.1786 -
 28.1787 -      <para>Parameters to this hook:
 28.1788 -      </para>
 28.1789 -      <itemizedlist>
 28.1790 -	<listitem><para><literal>local</literal>: A boolean.  Whether
 28.1791 -	    the tag is local to this repository instance (i.e. stored
 28.1792 -	    in <filename role="special">.hg/localtags</filename>) or
 28.1793 -	    managed by Mercurial (stored in <filename
 28.1794 -	      role="special">.hgtags</filename>).
 28.1795 -	  </para>
 28.1796 -	</listitem>
 28.1797 -	<listitem><para><literal>node</literal>: A changeset ID.  The
 28.1798 -	    ID of the changeset to be tagged.
 28.1799 -	  </para>
 28.1800 -	</listitem>
 28.1801 -	<listitem><para><literal>tag</literal>: A string.  The name of
 28.1802 -	    the tag to be created.
 28.1803 -	  </para>
 28.1804 -	</listitem></itemizedlist>
 28.1805 -
 28.1806 -      <para>If the tag to be created is revision-controlled, the
 28.1807 -	<literal role="hook">precommit</literal> and <literal
 28.1808 -	  role="hook">pretxncommit</literal> hooks (sections <xref
 28.1809 -	  linkend="sec.hook.commit"/> and <xref
 28.1810 -	  linkend="sec.hook.pretxncommit"/>) will also be run.
 28.1811 -      </para>
 28.1812 -
 28.1813 -      <para>See also: <literal role="hook">tag</literal> (section
 28.1814 -	<xref linkend="sec.hook.tag"/>)
 28.1815 -      </para>
 28.1816 -    </sect2>
 28.1817 -    <sect2 id="sec.hook.pretxnchangegroup">
 28.1818 -      <title><literal
 28.1819 -	  role="hook">pretxnchangegroup</literal>&emdash;before
 28.1820 -	completing addition of remote changesets</title>
 28.1821 -
 28.1822 -      <para>This controlling hook is run before a
 28.1823 -	transaction&emdash;that manages the addition of a group of new
 28.1824 -	changesets from outside the repository&emdash;completes.  If
 28.1825 -	the hook succeeds, the transaction completes, and all of the
 28.1826 -	changesets become permanent within this repository.  If the
 28.1827 -	hook fails, the transaction is rolled back, and the data for
 28.1828 -	the changesets is erased.
 28.1829 -      </para>
 28.1830 -
 28.1831 -      <para>This hook can access the metadata associated with the
 28.1832 -	almost-added changesets, but it should not do anything
 28.1833 -	permanent with this data. It must also not modify the working
 28.1834 -	directory.
 28.1835 -      </para>
 28.1836 -
 28.1837 -      <para>While this hook is running, if other Mercurial processes
 28.1838 -	access this repository, they will be able to see the
 28.1839 -	almost-added changesets as if they are permanent.  This may
 28.1840 -	lead to race conditions if you do not take steps to avoid
 28.1841 -	them.
 28.1842 -      </para>
 28.1843 -
 28.1844 -      <para>This hook can be used to automatically vet a group of
 28.1845 -	changesets.  If the hook fails, all of the changesets are
 28.1846 -	<quote>rejected</quote> when the transaction rolls back.
 28.1847 -      </para>
 28.1848 -
 28.1849 -      <para>Parameters to this hook:
 28.1850 -      </para>
 28.1851 -      <itemizedlist>
 28.1852 -	<listitem><para><literal>node</literal>: A changeset ID.  The
 28.1853 -	    changeset ID of the first changeset in the group that was
 28.1854 -	    added.  All changesets between this and
 28.1855 -	    <literal role="tag">tip</literal>,
 28.1856 -	    inclusive, were added by a single <command
 28.1857 -	      role="hg-cmd">hg pull</command>, <command
 28.1858 -	      role="hg-cmd">hg push</command> or <command
 28.1859 -	      role="hg-cmd">hg unbundle</command>.
 28.1860 -	  </para>
 28.1861 -	</listitem>
 28.1862 -	<listitem><para><literal>source</literal>: A string.  The
 28.1863 -	    source of these changes.  See section <xref
 28.1864 -	      linkend="sec.hook.sources"/> for details.
 28.1865 -	  </para>
 28.1866 -	</listitem>
 28.1867 -	<listitem><para><literal>url</literal>: A URL.  The location
 28.1868 -	    of the remote repository, if known.  See section <xref
 28.1869 -	      linkend="sec.hook.url"/> for more
 28.1870 -	    information.
 28.1871 -	  </para>
 28.1872 -	</listitem></itemizedlist>
 28.1873 -
 28.1874 -      <para>See also: <literal role="hook">changegroup</literal>
 28.1875 -	(section <xref linkend="sec.hook.changegroup"/>), <literal
 28.1876 -	  role="hook">incoming</literal> (section <xref
 28.1877 -	  linkend="sec.hook.incoming"/>), <literal
 28.1878 -	  role="hook">prechangegroup</literal> (section <xref
 28.1879 -	  linkend="sec.hook.prechangegroup"/>)
 28.1880 -      </para>
 28.1881 -
 28.1882 -    </sect2>
 28.1883 -    <sect2 id="sec.hook.pretxncommit">
 28.1884 -      <title><literal role="hook">pretxncommit</literal>&emdash;before
 28.1885 -	completing commit of new changeset</title>
 28.1886 -
 28.1887 -      <para>This controlling hook is run before a
 28.1888 -	transaction&emdash;that manages a new commit&emdash;completes.
 28.1889 -	If the hook succeeds, the transaction completes and the
 28.1890 -	changeset becomes permanent within this repository.  If the
 28.1891 -	hook fails, the transaction is rolled back, and the commit
 28.1892 -	data is erased.
 28.1893 -      </para>
 28.1894 -
 28.1895 -      <para>This hook can access the metadata associated with the
 28.1896 -	almost-new changeset, but it should not do anything permanent
 28.1897 -	with this data.  It must also not modify the working
 28.1898 -	directory.
 28.1899 -      </para>
 28.1900 -
 28.1901 -      <para>While this hook is running, if other Mercurial processes
 28.1902 -	access this repository, they will be able to see the
 28.1903 -	almost-new changeset as if it is permanent.  This may lead to
 28.1904 -	race conditions if you do not take steps to avoid them.
 28.1905 -      </para>
 28.1906 -
 28.1907 -      <para>Parameters to this hook:
 28.1908 -      </para>
 28.1909 -      <itemizedlist>
 28.1910 -	<listitem><para><literal>node</literal>: A changeset ID.  The
 28.1911 -	    changeset ID of the newly committed changeset.
 28.1912 -	  </para>
 28.1913 -	</listitem>
 28.1914 -	<listitem><para><literal>parent1</literal>: A changeset ID.
 28.1915 -	    The changeset ID of the first parent of the newly
 28.1916 -	    committed changeset.
 28.1917 -	  </para>
 28.1918 -	</listitem>
 28.1919 -	<listitem><para><literal>parent2</literal>: A changeset ID.
 28.1920 -	    The changeset ID of the second parent of the newly
 28.1921 -	    committed changeset.
 28.1922 -	  </para>
 28.1923 -	</listitem></itemizedlist>
 28.1924 -
 28.1925 -      <para>See also: <literal role="hook">precommit</literal>
 28.1926 -	(section <xref linkend="sec.hook.precommit"/>)
 28.1927 -      </para>
 28.1928 -
 28.1929 -    </sect2>
 28.1930 -    <sect2 id="sec.hook.preupdate">
 28.1931 -      <title><literal role="hook">preupdate</literal>&emdash;before
 28.1932 -	updating or merging working directory</title>
 28.1933 -
 28.1934 -      <para>This controlling hook is run before an update or merge of
 28.1935 -	the working directory begins.  It is run only if Mercurial's
 28.1936 -	normal pre-update checks determine that the update or merge
 28.1937 -	can proceed.  If the hook succeeds, the update or merge may
 28.1938 -	proceed; if it fails, the update or merge does not start.
 28.1939 -      </para>
 28.1940 -
 28.1941 -      <para>Parameters to this hook:
 28.1942 -      </para>
 28.1943 -      <itemizedlist>
 28.1944 -	<listitem><para><literal>parent1</literal>: A changeset ID.
 28.1945 -	    The ID of the parent that the working directory is to be
 28.1946 -	    updated to.  If the working directory is being merged, it
 28.1947 -	    will not change this parent.
 28.1948 -	  </para>
 28.1949 -	</listitem>
 28.1950 -	<listitem><para><literal>parent2</literal>: A changeset ID.
 28.1951 -	    Only set if the working directory is being merged.  The ID
 28.1952 -	    of the revision that the working directory is being merged
 28.1953 -	    with.
 28.1954 -	  </para>
 28.1955 -	</listitem></itemizedlist>
 28.1956 -
 28.1957 -      <para>See also: <literal role="hook">update</literal> (section
 28.1958 -	<xref linkend="sec.hook.update"/>)
 28.1959 -      </para>
 28.1960 -
 28.1961 -    </sect2>
 28.1962 -    <sect2 id="sec.hook.tag">
 28.1963 -      <title><literal role="hook">tag</literal>&emdash;after tagging a
 28.1964 -	changeset</title>
 28.1965 -
 28.1966 -      <para>This hook is run after a tag has been created.
 28.1967 -      </para>
 28.1968 -
 28.1969 -      <para>Parameters to this hook:
 28.1970 -      </para>
 28.1971 -      <itemizedlist>
 28.1972 -	<listitem><para><literal>local</literal>: A boolean.  Whether
 28.1973 -	    the new tag is local to this repository instance (i.e.
 28.1974 -	    stored in <filename
 28.1975 -	      role="special">.hg/localtags</filename>) or managed by
 28.1976 -	    Mercurial (stored in <filename
 28.1977 -	      role="special">.hgtags</filename>).
 28.1978 -	  </para>
 28.1979 -	</listitem>
 28.1980 -	<listitem><para><literal>node</literal>: A changeset ID.  The
 28.1981 -	    ID of the changeset that was tagged.
 28.1982 -	  </para>
 28.1983 -	</listitem>
 28.1984 -	<listitem><para><literal>tag</literal>: A string.  The name of
 28.1985 -	    the tag that was created.
 28.1986 -	  </para>
 28.1987 -	</listitem></itemizedlist>
 28.1988 -
 28.1989 -      <para>If the created tag is revision-controlled, the <literal
 28.1990 -	  role="hook">commit</literal> hook (section <xref
 28.1991 -	  linkend="sec.hook.commit"/>) is run before this hook.
 28.1992 -      </para>
 28.1993 -
 28.1994 -      <para>See also: <literal role="hook">pretag</literal> (section
 28.1995 -	<xref linkend="sec.hook.pretag"/>)
 28.1996 -      </para>
 28.1997 -
 28.1998 -    </sect2>
 28.1999 -    <sect2 id="sec.hook.update">
 28.2000 -      <title><literal role="hook">update</literal>&emdash;after
 28.2001 -	updating or merging working directory</title>
 28.2002 -
 28.2003 -      <para>This hook is run after an update or merge of the working
 28.2004 -	directory completes.  Since a merge can fail (if the external
 28.2005 -	<command>hgmerge</command> command fails to resolve conflicts
 28.2006 -	in a file), this hook communicates whether the update or merge
 28.2007 -	completed cleanly.
 28.2008 -      </para>
 28.2009 -
 28.2010 -      <itemizedlist>
 28.2011 -	<listitem><para><literal>error</literal>: A boolean.
 28.2012 -	    Indicates whether the update or merge completed
 28.2013 -	    successfully.
 28.2014 -	  </para>
 28.2015 -	</listitem>
 28.2016 -	<listitem><para><literal>parent1</literal>: A changeset ID.
 28.2017 -	    The ID of the parent that the working directory was
 28.2018 -	    updated to.  If the working directory was merged, it will
 28.2019 -	    not have changed this parent.
 28.2020 -	  </para>
 28.2021 -	</listitem>
 28.2022 -	<listitem><para><literal>parent2</literal>: A changeset ID.
 28.2023 -	    Only set if the working directory was merged.  The ID of
 28.2024 -	    the revision that the working directory was merged with.
 28.2025 -	  </para>
 28.2026 -	</listitem></itemizedlist>
 28.2027 -
 28.2028 -      <para>See also: <literal role="hook">preupdate</literal>
 28.2029 -	(section <xref linkend="sec.hook.preupdate"/>)
 28.2030 -      </para>
 28.2031 -
 28.2032 -    </sect2>
 28.2033 -  </sect1>
 28.2034 -</chapter>
 28.2035 -
 28.2036 -<!--
 28.2037 -local variables: 
 28.2038 -sgml-parent-document: ("00book.xml" "book" "chapter")
 28.2039 -end:
 28.2040 --->
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/en/ch10-template.xml	Fri Mar 20 16:43:35 2009 +0800
    29.3 @@ -0,0 +1,675 @@
    29.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    29.5 +
    29.6 +<chapter id="chap.template">
    29.7 +  <?dbhtml filename="customizing-the-output-of-mercurial.html"?>
    29.8 +  <title>Customising the output of Mercurial</title>
    29.9 +
   29.10 +  <para id="x_578">Mercurial provides a powerful mechanism to let you control how
   29.11 +    it displays information.  The mechanism is based on templates.
   29.12 +    You can use templates to generate specific output for a single
   29.13 +    command, or to customise the entire appearance of the built-in web
   29.14 +    interface.</para>
   29.15 +
   29.16 +  <sect1 id="sec.style">
   29.17 +    <title>Using precanned output styles</title>
   29.18 +
   29.19 +    <para id="x_579">Packaged with Mercurial are some output styles that you can
   29.20 +      use immediately.  A style is simply a precanned template that
   29.21 +      someone wrote and installed somewhere that Mercurial can
   29.22 +      find.</para>
   29.23 +
   29.24 +    <para id="x_57a">Before we take a look at Mercurial's bundled styles, let's
   29.25 +      review its normal output.</para>
   29.26 +
   29.27 +    &interaction.template.simple.normal;
   29.28 +
   29.29 +    <para id="x_57b">This is somewhat informative, but it takes up a lot of
   29.30 +      space&emdash;five lines of output per changeset.  The
   29.31 +      <literal>compact</literal> style reduces this to three lines,
   29.32 +      presented in a sparse manner.</para>
   29.33 +
   29.34 +    &interaction.template.simple.compact;
   29.35 +
   29.36 +    <para id="x_57c">The <literal>changelog</literal> style hints at the
   29.37 +      expressive power of Mercurial's templating engine.  This style
   29.38 +      attempts to follow the GNU Project's changelog
   29.39 +      guidelines<citation>web:changelog</citation>.</para>
   29.40 +
   29.41 +    &interaction.template.simple.changelog;
   29.42 +
   29.43 +    <para id="x_57d">You will not be shocked to learn that Mercurial's default
   29.44 +      output style is named <literal>default</literal>.</para>
   29.45 +
   29.46 +    <sect2>
   29.47 +      <title>Setting a default style</title>
   29.48 +
   29.49 +      <para id="x_57e">You can modify the output style that Mercurial will use
   29.50 +	for every command by editing your <filename
   29.51 +	  role="special">~/.hgrc</filename> file, naming the style
   29.52 +	you would prefer to use.</para>
   29.53 +
   29.54 +      <programlisting>[ui]
   29.55 +style = compact</programlisting>
   29.56 +
   29.57 +      <para id="x_57f">If you write a style of your own, you can use it by either
   29.58 +	providing the path to your style file, or copying your style
   29.59 +	file into a location where Mercurial can find it (typically
   29.60 +	the <literal>templates</literal> subdirectory of your
   29.61 +	Mercurial install directory).</para>
   29.62 +
   29.63 +    </sect2>
   29.64 +  </sect1>
   29.65 +  <sect1>
   29.66 +    <title>Commands that support styles and templates</title>
   29.67 +
   29.68 +    <para id="x_580">All of Mercurial's
   29.69 +      <quote><literal>log</literal>-like</quote> commands let you use
   29.70 +      styles and templates: <command role="hg-cmd">hg
   29.71 +	incoming</command>, <command role="hg-cmd">hg log</command>,
   29.72 +      <command role="hg-cmd">hg outgoing</command>, and <command
   29.73 +	role="hg-cmd">hg tip</command>.</para>
   29.74 +
   29.75 +    <para id="x_581">As I write this manual, these are so far the only commands
   29.76 +      that support styles and templates.  Since these are the most
   29.77 +      important commands that need customisable output, there has been
   29.78 +      little pressure from the Mercurial user community to add style
   29.79 +      and template support to other commands.</para>
   29.80 +
   29.81 +  </sect1>
   29.82 +  <sect1>
   29.83 +    <title>The basics of templating</title>
   29.84 +
   29.85 +    <para id="x_582">At its simplest, a Mercurial template is a piece of text.
   29.86 +      Some of the text never changes, while other parts are
   29.87 +      <emphasis>expanded</emphasis>, or replaced with new text, when
   29.88 +      necessary.</para>
   29.89 +
   29.90 +    <para id="x_583">Before we continue, let's look again at a simple example of
   29.91 +      Mercurial's normal output.</para>
   29.92 +
   29.93 +    &interaction.template.simple.normal;
   29.94 +
   29.95 +    <para id="x_584">Now, let's run the same command, but using a template to
   29.96 +      change its output.</para>
   29.97 +
   29.98 +    &interaction.template.simple.simplest;
   29.99 +
  29.100 +    <para id="x_585">The example above illustrates the simplest possible
  29.101 +      template; it's just a piece of static text, printed once for
  29.102 +      each changeset.  The <option
  29.103 +	role="hg-opt-log">--template</option> option to the <command
  29.104 +	role="hg-cmd">hg log</command> command tells Mercurial to use
  29.105 +      the given text as the template when printing each
  29.106 +      changeset.</para>
  29.107 +
  29.108 +    <para id="x_586">Notice that the template string above ends with the text
  29.109 +      <quote><literal>\n</literal></quote>.  This is an
  29.110 +      <emphasis>escape sequence</emphasis>, telling Mercurial to print
  29.111 +      a newline at the end of each template item.  If you omit this
  29.112 +      newline, Mercurial will run each piece of output together.  See
  29.113 +      section <xref linkend="sec.template.escape"/> for more details
  29.114 +      of escape sequences.</para>
  29.115 +
  29.116 +    <para id="x_587">A template that prints a fixed string of text all the time
  29.117 +      isn't very useful; let's try something a bit more
  29.118 +      complex.</para>
  29.119 +
  29.120 +    &interaction.template.simple.simplesub;
  29.121 +
  29.122 +    <para id="x_588">As you can see, the string
  29.123 +      <quote><literal>{desc}</literal></quote> in the template has
  29.124 +      been replaced in the output with the description of each
  29.125 +      changeset.  Every time Mercurial finds text enclosed in curly
  29.126 +      braces (<quote><literal>{</literal></quote> and
  29.127 +      <quote><literal>}</literal></quote>), it will try to replace the braces
  29.128 +      and text with the expansion of whatever is inside.  To print a
  29.129 +      literal curly brace, you must escape it, as described in section
  29.130 +      <xref
  29.131 +	linkend="sec.template.escape"/>.</para>
  29.132 +
  29.133 +  </sect1>
  29.134 +  <sect1 id="sec.template.keyword">
  29.135 +    <title>Common template keywords</title>
  29.136 +
  29.137 +    <para id="x_589">You can start writing simple templates immediately using the
  29.138 +      keywords below.</para>
  29.139 +
  29.140 +    <itemizedlist>
  29.141 +      <listitem><para id="x_58a"><literal
  29.142 +	    role="template-keyword">author</literal>: String.  The
  29.143 +	  unmodified author of the changeset.</para>
  29.144 +      </listitem>
  29.145 +      <listitem><para id="x_58b"><literal
  29.146 +	    role="template-keyword">branches</literal>: String.  The
  29.147 +	  name of the branch on which the changeset was committed.
  29.148 +	  Will be empty if the branch name was
  29.149 +	  <literal>default</literal>.</para>
  29.150 +      </listitem>
  29.151 +      <listitem><para id="x_58c"><literal role="template-keyword">date</literal>:
  29.152 +	  Date information.  The date when the changeset was
  29.153 +	  committed.  This is <emphasis>not</emphasis> human-readable;
  29.154 +	  you must pass it through a filter that will render it
  29.155 +	  appropriately.  See section <xref
  29.156 +	    linkend="sec.template.filter"/> for more information
  29.157 +	  on filters. The date is expressed as a pair of numbers.  The
  29.158 +	  first number is a Unix UTC timestamp (seconds since January
  29.159 +	  1, 1970); the second is the offset of the committer's
  29.160 +	  timezone from UTC, in seconds.</para>
  29.161 +      </listitem>
  29.162 +      <listitem><para id="x_58d"><literal role="template-keyword">desc</literal>:
  29.163 +	  String.  The text of the changeset description.</para>
  29.164 +      </listitem>
  29.165 +      <listitem><para id="x_58e"><literal
  29.166 +	    role="template-keyword">files</literal>: List of strings.
  29.167 +	  All files modified, added, or removed by this
  29.168 +	  changeset.</para>
  29.169 +      </listitem>
  29.170 +      <listitem><para id="x_58f"><literal
  29.171 +	    role="template-keyword">file_adds</literal>: List of
  29.172 +	  strings.  Files added by this changeset.</para>
  29.173 +      </listitem>
  29.174 +      <listitem><para id="x_590"><literal
  29.175 +	    role="template-keyword">file_dels</literal>: List of
  29.176 +	  strings.  Files removed by this changeset.</para>
  29.177 +      </listitem>
  29.178 +      <listitem><para id="x_591"><literal role="template-keyword">node</literal>:
  29.179 +	  String.  The changeset identification hash, as a
  29.180 +	  40-character hexadecimal string.</para>
  29.181 +      </listitem>
  29.182 +      <listitem><para id="x_592"><literal
  29.183 +	    role="template-keyword">parents</literal>: List of
  29.184 +	  strings.  The parents of the changeset.</para>
  29.185 +      </listitem>
  29.186 +      <listitem><para id="x_593"><literal role="template-keyword">rev</literal>:
  29.187 +	  Integer.  The repository-local changeset revision
  29.188 +	  number.</para>
  29.189 +      </listitem>
  29.190 +      <listitem><para id="x_594"><literal role="template-keyword">tags</literal>:
  29.191 +	  List of strings.  Any tags associated with the
  29.192 +	  changeset.</para>
  29.193 +      </listitem></itemizedlist>
  29.194 +
  29.195 +    <para id="x_595">A few simple experiments will show us what to expect when we
  29.196 +      use these keywords; you can see the results below.</para>
  29.197 +
  29.198 +&interaction.template.simple.keywords;
  29.199 +
  29.200 +    <para id="x_596">As we noted above, the date keyword does not produce
  29.201 +      human-readable output, so we must treat it specially.  This
  29.202 +      involves using a <emphasis>filter</emphasis>, about which more
  29.203 +      in section <xref
  29.204 +	linkend="sec.template.filter"/>.</para>
  29.205 +
  29.206 +    &interaction.template.simple.datekeyword;
  29.207 +
  29.208 +  </sect1>
  29.209 +  <sect1 id="sec.template.escape">
  29.210 +    <title>Escape sequences</title>
  29.211 +
  29.212 +    <para id="x_597">Mercurial's templating engine recognises the most commonly
  29.213 +      used escape sequences in strings.  When it sees a backslash
  29.214 +      (<quote><literal>\</literal></quote>) character, it looks at the
  29.215 +      following character and substitutes the two characters with a
  29.216 +      single replacement, as described below.</para>
  29.217 +
  29.218 +    <itemizedlist>
  29.219 +      <listitem><para id="x_598"><literal>\</literal>:
  29.220 +	  Backslash, <quote><literal>\</literal></quote>, ASCII
  29.221 +	  134.</para>
  29.222 +      </listitem>
  29.223 +      <listitem><para id="x_599"><literal>\n</literal>: Newline,
  29.224 +	  ASCII 12.</para>
  29.225 +      </listitem>
  29.226 +      <listitem><para id="x_59a"><literal>\r</literal>: Carriage
  29.227 +	  return, ASCII 15.</para>
  29.228 +      </listitem>
  29.229 +      <listitem><para id="x_59b"><literal>\t</literal>: Tab, ASCII
  29.230 +	  11.</para>
  29.231 +      </listitem>
  29.232 +      <listitem><para id="x_59c"><literal>\v</literal>: Vertical
  29.233 +	  tab, ASCII 13.</para>
  29.234 +      </listitem>
  29.235 +      <listitem><para id="x_59d"><literal>{</literal>: Open curly
  29.236 +	  brace, <quote><literal>{</literal></quote>, ASCII
  29.237 +	  173.</para>
  29.238 +      </listitem>
  29.239 +      <listitem><para id="x_59e"><literal>}</literal>: Close curly
  29.240 +	  brace, <quote><literal>}</literal></quote>, ASCII
  29.241 +	  175.</para>
  29.242 +      </listitem></itemizedlist>
  29.243 +
  29.244 +    <para id="x_59f">As indicated above, if you want the expansion of a template
  29.245 +      to contain a literal <quote><literal>\</literal></quote>,
  29.246 +      <quote><literal>{</literal></quote>, or
  29.247 +      <quote><literal>{</literal></quote> character, you must escape
  29.248 +      it.</para>
  29.249 +
  29.250 +  </sect1>
  29.251 +  <sect1 id="sec.template.filter">
  29.252 +    <title>Filtering keywords to change their results</title>
  29.253 +
  29.254 +    <para id="x_5a0">Some of the results of template expansion are not
  29.255 +      immediately easy to use.  Mercurial lets you specify an optional
  29.256 +      chain of <emphasis>filters</emphasis> to modify the result of
  29.257 +      expanding a keyword.  You have already seen a common filter,
  29.258 +      <literal role="template-kw-filt-date">isodate</literal>, in
  29.259 +      action above, to make a date readable.</para>
  29.260 +
  29.261 +    <para id="x_5a1">Below is a list of the most commonly used filters that
  29.262 +      Mercurial supports.  While some filters can be applied to any
  29.263 +      text, others can only be used in specific circumstances.  The
  29.264 +      name of each filter is followed first by an indication of where
  29.265 +      it can be used, then a description of its effect.</para>
  29.266 +
  29.267 +    <itemizedlist>
  29.268 +      <listitem><para id="x_5a2"><literal
  29.269 +	    role="template-filter">addbreaks</literal>: Any text. Add
  29.270 +	  an XHTML <quote><literal>&lt;br/&gt;</literal></quote> tag
  29.271 +	  before the end of every line except the last.  For example,
  29.272 +	  <quote><literal>foo\nbar</literal></quote> becomes
  29.273 +	  <quote><literal>foo&lt;br/&gt;\nbar</literal></quote>.</para>
  29.274 +      </listitem>
  29.275 +      <listitem><para id="x_5a3"><literal
  29.276 +	    role="template-kw-filt-date">age</literal>: <literal
  29.277 +	    role="template-keyword">date</literal> keyword.  Render
  29.278 +	  the age of the date, relative to the current time.  Yields a
  29.279 +	  string like <quote><literal>10
  29.280 +	      minutes</literal></quote>.</para>
  29.281 +      </listitem>
  29.282 +      <listitem><para id="x_5a4"><literal
  29.283 +	    role="template-filter">basename</literal>: Any text, but
  29.284 +	  most useful for the <literal
  29.285 +	    role="template-keyword">files</literal> keyword and its
  29.286 +	  relatives.  Treat the text as a path, and return the
  29.287 +	  basename. For example,
  29.288 +	  <quote><literal>foo/bar/baz</literal></quote> becomes
  29.289 +	  <quote><literal>baz</literal></quote>.</para>
  29.290 +      </listitem>
  29.291 +      <listitem><para id="x_5a5"><literal
  29.292 +	    role="template-kw-filt-date">date</literal>: <literal
  29.293 +	    role="template-keyword">date</literal> keyword.  Render a
  29.294 +	  date in a similar format to the Unix <literal
  29.295 +	    role="template-keyword">date</literal> command, but with
  29.296 +	  timezone included.  Yields a string like <quote><literal>Mon
  29.297 +	      Sep 04 15:13:13 2006 -0700</literal></quote>.</para>
  29.298 +      </listitem>
  29.299 +      <listitem><para id="x_5a6"><literal
  29.300 +	    role="template-kw-filt-author">domain</literal>: Any text,
  29.301 +	  but most useful for the <literal
  29.302 +	    role="template-keyword">author</literal> keyword.  Finds
  29.303 +	  the first string that looks like an email address, and
  29.304 +	  extract just the domain component.  For example,
  29.305 +	  <quote><literal>Bryan O'Sullivan
  29.306 +	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
  29.307 +	  <quote><literal>serpentine.com</literal></quote>.</para>
  29.308 +      </listitem>
  29.309 +      <listitem><para id="x_5a7"><literal
  29.310 +	    role="template-kw-filt-author">email</literal>: Any text,
  29.311 +	  but most useful for the <literal
  29.312 +	    role="template-keyword">author</literal> keyword.  Extract
  29.313 +	  the first string that looks like an email address.  For
  29.314 +	  example, <quote><literal>Bryan O'Sullivan
  29.315 +	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
  29.316 +	  <quote><literal>bos@serpentine.com</literal></quote>.</para>
  29.317 +      </listitem>
  29.318 +      <listitem><para id="x_5a8"><literal
  29.319 +	    role="template-filter">escape</literal>: Any text.
  29.320 +	  Replace the special XML/XHTML characters
  29.321 +	  <quote><literal>&amp;</literal></quote>,
  29.322 +	  <quote><literal>&lt;</literal></quote> and
  29.323 +	  <quote><literal>&gt;</literal></quote> with XML
  29.324 +	  entities.</para>
  29.325 +      </listitem>
  29.326 +      <listitem><para id="x_5a9"><literal
  29.327 +	    role="template-filter">fill68</literal>: Any text.  Wrap
  29.328 +	  the text to fit in 68 columns.  This is useful before you
  29.329 +	  pass text through the <literal
  29.330 +	    role="template-filter">tabindent</literal> filter, and
  29.331 +	  still want it to fit in an 80-column fixed-font
  29.332 +	  window.</para>
  29.333 +      </listitem>
  29.334 +      <listitem><para id="x_5aa"><literal
  29.335 +	    role="template-filter">fill76</literal>: Any text.  Wrap
  29.336 +	  the text to fit in 76 columns.</para>
  29.337 +      </listitem>
  29.338 +      <listitem><para id="x_5ab"><literal
  29.339 +	    role="template-filter">firstline</literal>: Any text.
  29.340 +	  Yield the first line of text, without any trailing
  29.341 +	  newlines.</para>
  29.342 +      </listitem>
  29.343 +      <listitem><para id="x_5ac"><literal
  29.344 +	    role="template-kw-filt-date">hgdate</literal>: <literal
  29.345 +	    role="template-keyword">date</literal> keyword.  Render
  29.346 +	  the date as a pair of readable numbers.  Yields a string
  29.347 +	  like <quote><literal>1157407993
  29.348 +	      25200</literal></quote>.</para>
  29.349 +      </listitem>
  29.350 +      <listitem><para id="x_5ad"><literal
  29.351 +	    role="template-kw-filt-date">isodate</literal>: <literal
  29.352 +	    role="template-keyword">date</literal> keyword.  Render
  29.353 +	  the date as a text string in ISO 8601 format.  Yields a
  29.354 +	  string like <quote><literal>2006-09-04 15:13:13
  29.355 +	      -0700</literal></quote>.</para>
  29.356 +      </listitem>
  29.357 +      <listitem><para id="x_5ae"><literal
  29.358 +	    role="template-filter">obfuscate</literal>: Any text, but
  29.359 +	  most useful for the <literal
  29.360 +	    role="template-keyword">author</literal> keyword.  Yield
  29.361 +	  the input text rendered as a sequence of XML entities.  This
  29.362 +	  helps to defeat some particularly stupid screen-scraping
  29.363 +	  email harvesting spambots.</para>
  29.364 +      </listitem>
  29.365 +      <listitem><para id="x_5af"><literal
  29.366 +	    role="template-kw-filt-author">person</literal>: Any text,
  29.367 +	  but most useful for the <literal
  29.368 +	    role="template-keyword">author</literal> keyword.  Yield
  29.369 +	  the text before an email address. For example,
  29.370 +	  <quote><literal>Bryan O'Sullivan
  29.371 +	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
  29.372 +	  <quote><literal>Bryan O'Sullivan</literal></quote>.</para>
  29.373 +      </listitem>
  29.374 +      <listitem><para id="x_5b0"><literal
  29.375 +	    role="template-kw-filt-date">rfc822date</literal>:
  29.376 +	  <literal role="template-keyword">date</literal> keyword.
  29.377 +	  Render a date using the same format used in email headers.
  29.378 +	  Yields a string like <quote><literal>Mon, 04 Sep 2006
  29.379 +	      15:13:13 -0700</literal></quote>.</para>
  29.380 +      </listitem>
  29.381 +      <listitem><para id="x_5b1"><literal
  29.382 +	    role="template-kw-filt-node">short</literal>: Changeset
  29.383 +	  hash.  Yield the short form of a changeset hash, i.e. a
  29.384 +	  12-character hexadecimal string.</para>
  29.385 +      </listitem>
  29.386 +      <listitem><para id="x_5b2"><literal
  29.387 +	    role="template-kw-filt-date">shortdate</literal>: <literal
  29.388 +	    role="template-keyword">date</literal> keyword.  Render
  29.389 +	  the year, month, and day of the date.  Yields a string like
  29.390 +	  <quote><literal>2006-09-04</literal></quote>.</para>
  29.391 +      </listitem>
  29.392 +      <listitem><para id="x_5b3"><literal role="template-filter">strip</literal>:
  29.393 +	  Any text.  Strip all leading and trailing whitespace from
  29.394 +	  the string.</para>
  29.395 +      </listitem>
  29.396 +      <listitem><para id="x_5b4"><literal
  29.397 +	    role="template-filter">tabindent</literal>: Any text.
  29.398 +	  Yield the text, with every line except the first starting
  29.399 +	  with a tab character.</para>
  29.400 +      </listitem>
  29.401 +      <listitem><para id="x_5b5"><literal
  29.402 +	    role="template-filter">urlescape</literal>: Any text.
  29.403 +	  Escape all characters that are considered
  29.404 +	  <quote>special</quote> by URL parsers.  For example,
  29.405 +	  <literal>foo bar</literal> becomes
  29.406 +	  <literal>foo%20bar</literal>.</para>
  29.407 +      </listitem>
  29.408 +      <listitem><para id="x_5b6"><literal
  29.409 +	    role="template-kw-filt-author">user</literal>: Any text,
  29.410 +	  but most useful for the <literal
  29.411 +	    role="template-keyword">author</literal> keyword.  Return
  29.412 +	  the <quote>user</quote> portion of an email address.  For
  29.413 +	  example, <quote><literal>Bryan O'Sullivan
  29.414 +	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
  29.415 +	  <quote><literal>bos</literal></quote>.</para>
  29.416 +      </listitem></itemizedlist>
  29.417 +
  29.418 +&interaction.template.simple.manyfilters;
  29.419 +
  29.420 +    <note>
  29.421 +      <para id="x_5b7">  If you try to apply a filter to a piece of data that it
  29.422 +	cannot process, Mercurial will fail and print a Python
  29.423 +	exception.  For example, trying to run the output of the
  29.424 +	<literal role="template-keyword">desc</literal> keyword into
  29.425 +	the <literal role="template-kw-filt-date">isodate</literal>
  29.426 +	filter is not a good idea.</para>
  29.427 +    </note>
  29.428 +
  29.429 +    <sect2>
  29.430 +      <title>Combining filters</title>
  29.431 +
  29.432 +      <para id="x_5b8">It is easy to combine filters to yield output in the form
  29.433 +	you would like.  The following chain of filters tidies up a
  29.434 +	description, then makes sure that it fits cleanly into 68
  29.435 +	columns, then indents it by a further 8 characters (at least
  29.436 +	on Unix-like systems, where a tab is conventionally 8
  29.437 +	characters wide).</para>
  29.438 +
  29.439 +      &interaction.template.simple.combine;
  29.440 +
  29.441 +      <para id="x_5b9">Note the use of <quote><literal>\t</literal></quote> (a
  29.442 +	tab character) in the template to force the first line to be
  29.443 +	indented; this is necessary since <literal
  29.444 +	  role="template-keyword">tabindent</literal> indents all
  29.445 +	lines <emphasis>except</emphasis> the first.</para>
  29.446 +
  29.447 +      <para id="x_5ba">Keep in mind that the order of filters in a chain is
  29.448 +	significant.  The first filter is applied to the result of the
  29.449 +	keyword; the second to the result of the first filter; and so
  29.450 +	on.  For example, using <literal>fill68|tabindent</literal>
  29.451 +	gives very different results from
  29.452 +	<literal>tabindent|fill68</literal>.</para>
  29.453 +
  29.454 +
  29.455 +    </sect2>
  29.456 +  </sect1>
  29.457 +  <sect1>
  29.458 +    <title>From templates to styles</title>
  29.459 +
  29.460 +    <para id="x_5bb">A command line template provides a quick and simple way to
  29.461 +      format some output.  Templates can become verbose, though, and
  29.462 +      it's useful to be able to give a template a name.  A style file
  29.463 +      is a template with a name, stored in a file.</para>
  29.464 +
  29.465 +    <para id="x_5bc">More than that, using a style file unlocks the power of
  29.466 +      Mercurial's templating engine in ways that are not possible
  29.467 +      using the command line <option
  29.468 +	role="hg-opt-log">--template</option> option.</para>
  29.469 +
  29.470 +    <sect2>
  29.471 +      <title>The simplest of style files</title>
  29.472 +
  29.473 +      <para id="x_5bd">Our simple style file contains just one line:</para>
  29.474 +
  29.475 +      &interaction.template.simple.rev;
  29.476 +
  29.477 +      <para id="x_5be">This tells Mercurial, <quote>if you're printing a
  29.478 +	  changeset, use the text on the right as the
  29.479 +	  template</quote>.</para>
  29.480 +
  29.481 +    </sect2>
  29.482 +    <sect2>
  29.483 +      <title>Style file syntax</title>
  29.484 +
  29.485 +      <para id="x_5bf">The syntax rules for a style file are simple.</para>
  29.486 +
  29.487 +      <itemizedlist>
  29.488 +	<listitem><para id="x_5c0">The file is processed one line at a
  29.489 +	    time.</para>
  29.490 +	</listitem>
  29.491 +	<listitem><para id="x_5c1">Leading and trailing white space are
  29.492 +	    ignored.</para>
  29.493 +	</listitem>
  29.494 +	<listitem><para id="x_5c2">Empty lines are skipped.</para>
  29.495 +	</listitem>
  29.496 +	<listitem><para id="x_5c3">If a line starts with either of the characters
  29.497 +	    <quote><literal>#</literal></quote> or
  29.498 +	    <quote><literal>;</literal></quote>, the entire line is
  29.499 +	    treated as a comment, and skipped as if empty.</para>
  29.500 +	</listitem>
  29.501 +	<listitem><para id="x_5c4">A line starts with a keyword.  This must start
  29.502 +	    with an alphabetic character or underscore, and can
  29.503 +	    subsequently contain any alphanumeric character or
  29.504 +	    underscore.  (In regexp notation, a keyword must match
  29.505 +	    <literal>[A-Za-z_][A-Za-z0-9_]*</literal>.)</para>
  29.506 +	</listitem>
  29.507 +	<listitem><para id="x_5c5">The next element must be an
  29.508 +	    <quote><literal>=</literal></quote> character, which can
  29.509 +	    be preceded or followed by an arbitrary amount of white
  29.510 +	    space.</para>
  29.511 +	</listitem>
  29.512 +	<listitem><para id="x_5c6">If the rest of the line starts and ends with
  29.513 +	    matching quote characters (either single or double quote),
  29.514 +	    it is treated as a template body.</para>
  29.515 +	</listitem>
  29.516 +	<listitem><para id="x_5c7">If the rest of the line <emphasis>does
  29.517 +	      not</emphasis> start with a quote character, it is
  29.518 +	    treated as the name of a file; the contents of this file
  29.519 +	    will be read and used as a template body.</para>
  29.520 +	</listitem></itemizedlist>
  29.521 +
  29.522 +    </sect2>
  29.523 +  </sect1>
  29.524 +  <sect1>
  29.525 +    <title>Style files by example</title>
  29.526 +
  29.527 +    <para id="x_5c8">To illustrate how to write a style file, we will construct a
  29.528 +      few by example.  Rather than provide a complete style file and
  29.529 +      walk through it, we'll mirror the usual process of developing a
  29.530 +      style file by starting with something very simple, and walking
  29.531 +      through a series of successively more complete examples.</para>
  29.532 +
  29.533 +    <sect2>
  29.534 +      <title>Identifying mistakes in style files</title>
  29.535 +
  29.536 +      <para id="x_5c9">If Mercurial encounters a problem in a style file you are
  29.537 +	working on, it prints a terse error message that, once you
  29.538 +	figure out what it means, is actually quite useful.</para>
  29.539 +
  29.540 +&interaction.template.svnstyle.syntax.input;
  29.541 +
  29.542 +      <para id="x_5ca">Notice that <filename>broken.style</filename> attempts to
  29.543 +	define a <literal>changeset</literal> keyword, but forgets to
  29.544 +	give any content for it. When instructed to use this style
  29.545 +	file, Mercurial promptly complains.</para>
  29.546 +
  29.547 +      &interaction.template.svnstyle.syntax.error;
  29.548 +
  29.549 +      <para id="x_5cb">This error message looks intimidating, but it is not too
  29.550 +	hard to follow.</para>
  29.551 +
  29.552 +      <itemizedlist>
  29.553 +	<listitem><para id="x_5cc">The first component is simply Mercurial's way
  29.554 +	    of saying <quote>I am giving up</quote>.</para>
  29.555 +	  <programlisting>___abort___: broken.style:1: parse error</programlisting>
  29.556 +	</listitem>
  29.557 +	<listitem><para id="x_5cd">Next comes the name of the style file that
  29.558 +	    contains the error.</para>
  29.559 +	  <programlisting>abort: ___broken.style___:1: parse error</programlisting>
  29.560 +	</listitem>
  29.561 +	<listitem><para id="x_5ce">Following the file name is the line number
  29.562 +	    where the error was encountered.</para>
  29.563 +	  <programlisting>abort: broken.style:___1___: parse error</programlisting>
  29.564 +	</listitem>
  29.565 +	<listitem><para id="x_5cf">Finally, a description of what went
  29.566 +	    wrong.</para>
  29.567 +	  <programlisting>abort: broken.style:1: ___parse error___</programlisting>
  29.568 +	</listitem>
  29.569 +	<listitem><para id="x_5d0">The description of the problem is not always
  29.570 +	    clear (as in this case), but even when it is cryptic, it
  29.571 +	    is almost always trivial to visually inspect the offending
  29.572 +	    line in the style file and see what is wrong.</para>
  29.573 +	</listitem></itemizedlist>
  29.574 +
  29.575 +    </sect2>
  29.576 +    <sect2>
  29.577 +      <title>Uniquely identifying a repository</title>
  29.578 +
  29.579 +      <para id="x_5d1">If you would like to be able to identify a Mercurial
  29.580 +	repository <quote>fairly uniquely</quote> using a short string
  29.581 +	as an identifier, you can use the first revision in the
  29.582 +	repository.</para>
  29.583 +
  29.584 +      &interaction.template.svnstyle.id;
  29.585 +
  29.586 +      <para id="x_5d2">This is not guaranteed to be unique, but it is
  29.587 +	nevertheless useful in many cases.</para>
  29.588 +      <itemizedlist>
  29.589 +	<listitem><para id="x_5d3">It will not work in a completely empty
  29.590 +	    repository, because such a repository does not have a
  29.591 +	    revision zero.</para>
  29.592 +	</listitem>
  29.593 +	<listitem><para id="x_5d4">Neither will it work in the (extremely rare)
  29.594 +	    case where a repository is a merge of two or more formerly
  29.595 +	    independent repositories, and you still have those
  29.596 +	    repositories around.</para>
  29.597 +	</listitem></itemizedlist>
  29.598 +      <para id="x_5d5">Here are some uses to which you could put this
  29.599 +	identifier:</para>
  29.600 +      <itemizedlist>
  29.601 +	<listitem><para id="x_5d6">As a key into a table for a database that
  29.602 +	    manages repositories on a server.</para>
  29.603 +	</listitem>
  29.604 +	<listitem><para id="x_5d7">As half of a {<emphasis>repository
  29.605 +	      ID</emphasis>, <emphasis>revision ID</emphasis>} tuple.
  29.606 +	    Save this information away when you run an automated build
  29.607 +	    or other activity, so that you can <quote>replay</quote>
  29.608 +	    the build later if necessary.</para>
  29.609 +	</listitem></itemizedlist>
  29.610 +
  29.611 +    </sect2>
  29.612 +    <sect2>
  29.613 +      <title>Mimicking Subversion's output</title>
  29.614 +
  29.615 +      <para id="x_5d8">Let's try to emulate the default output format used by
  29.616 +	another revision control tool, Subversion.</para>
  29.617 +
  29.618 +      &interaction.template.svnstyle.short;
  29.619 +
  29.620 +      <para id="x_5d9">Since Subversion's output style is fairly simple, it is
  29.621 +	easy to copy-and-paste a hunk of its output into a file, and
  29.622 +	replace the text produced above by Subversion with the
  29.623 +	template values we'd like to see expanded.</para>
  29.624 +
  29.625 +      &interaction.template.svnstyle.template;
  29.626 +
  29.627 +      <para id="x_5da">There are a few small ways in which this template deviates
  29.628 +	from the output produced by Subversion.</para>
  29.629 +      <itemizedlist>
  29.630 +	<listitem><para id="x_5db">Subversion prints a <quote>readable</quote>
  29.631 +	    date (the <quote><literal>Wed, 27 Sep 2006</literal></quote> in the
  29.632 +	    example output above) in parentheses.  Mercurial's
  29.633 +	    templating engine does not provide a way to display a date
  29.634 +	    in this format without also printing the time and time
  29.635 +	    zone.</para>
  29.636 +	</listitem>
  29.637 +	<listitem><para id="x_5dc">We emulate Subversion's printing of
  29.638 +	    <quote>separator</quote> lines full of
  29.639 +	    <quote><literal>-</literal></quote> characters by ending
  29.640 +	    the template with such a line. We use the templating
  29.641 +	    engine's <literal role="template-keyword">header</literal>
  29.642 +	    keyword to print a separator line as the first line of
  29.643 +	    output (see below), thus achieving similar output to
  29.644 +	    Subversion.</para>
  29.645 +	</listitem>
  29.646 +	<listitem><para id="x_5dd">Subversion's output includes a count in the
  29.647 +	    header of the number of lines in the commit message.  We
  29.648 +	    cannot replicate this in Mercurial; the templating engine
  29.649 +	    does not currently provide a filter that counts the number
  29.650 +	    of lines the template generates.</para>
  29.651 +	</listitem></itemizedlist>
  29.652 +      <para id="x_5de">It took me no more than a minute or two of work to replace
  29.653 +	literal text from an example of Subversion's output with some
  29.654 +	keywords and filters to give the template above.  The style
  29.655 +	file simply refers to the template.</para>
  29.656 +
  29.657 +      &interaction.template.svnstyle.style;
  29.658 +
  29.659 +      <para id="x_5df">We could have included the text of the template file
  29.660 +	directly in the style file by enclosing it in quotes and
  29.661 +	replacing the newlines with
  29.662 +	<quote><literal>\n</literal></quote> sequences, but it would
  29.663 +	have made the style file too difficult to read.  Readability
  29.664 +	is a good guide when you're trying to decide whether some text
  29.665 +	belongs in a style file, or in a template file that the style
  29.666 +	file points to.  If the style file will look too big or
  29.667 +	cluttered if you insert a literal piece of text, drop it into
  29.668 +	a template instead.</para>
  29.669 +
  29.670 +    </sect2>
  29.671 +  </sect1>
  29.672 +</chapter>
  29.673 +
  29.674 +<!--
  29.675 +local variables: 
  29.676 +sgml-parent-document: ("00book.xml" "book" "chapter")
  29.677 +end:
  29.678 +-->
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/en/ch11-mq.xml	Fri Mar 20 16:43:35 2009 +0800
    30.3 @@ -0,0 +1,1323 @@
    30.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    30.5 +
    30.6 +<chapter id="chap.mq">
    30.7 +  <?dbhtml filename="managing-change-with-mercurial-queues.html"?>
    30.8 +  <title>Managing change with Mercurial Queues</title>
    30.9 +
   30.10 +  <sect1 id="sec.mq.patch-mgmt">
   30.11 +    <title>The patch management problem</title>
   30.12 +
   30.13 +    <para>Here is a common scenario: you need to install a software
   30.14 +      package from source, but you find a bug that you must fix in the
   30.15 +      source before you can start using the package.  You make your
   30.16 +      changes, forget about the package for a while, and a few months
   30.17 +      later you need to upgrade to a newer version of the package.  If
   30.18 +      the newer version of the package still has the bug, you must
   30.19 +      extract your fix from the older source tree and apply it against
   30.20 +      the newer version.  This is a tedious task, and it's easy to
   30.21 +      make mistakes.</para>
   30.22 +
   30.23 +    <para>This is a simple case of the <quote>patch management</quote>
   30.24 +      problem.  You have an <quote>upstream</quote> source tree that
   30.25 +      you can't change; you need to make some local changes on top of
   30.26 +      the upstream tree; and you'd like to be able to keep those
   30.27 +      changes separate, so that you can apply them to newer versions
   30.28 +      of the upstream source.</para>
   30.29 +
   30.30 +    <para>The patch management problem arises in many situations.
   30.31 +      Probably the most visible is that a user of an open source
   30.32 +      software project will contribute a bug fix or new feature to the
   30.33 +      project's maintainers in the form of a patch.</para>
   30.34 +
   30.35 +    <para>Distributors of operating systems that include open source
   30.36 +      software often need to make changes to the packages they
   30.37 +      distribute so that they will build properly in their
   30.38 +      environments.</para>
   30.39 +
   30.40 +    <para>When you have few changes to maintain, it is easy to manage
   30.41 +      a single patch using the standard <command>diff</command> and
   30.42 +      <command>patch</command> programs (see section <xref
   30.43 +	linkend="sec.mq.patch"/> for a discussion of these
   30.44 +      tools). Once the number of changes grows, it starts to make
   30.45 +      sense to maintain patches as discrete <quote>chunks of
   30.46 +	work,</quote> so that for example a single patch will contain
   30.47 +      only one bug fix (the patch might modify several files, but it's
   30.48 +      doing <quote>only one thing</quote>), and you may have a number
   30.49 +      of such patches for different bugs you need fixed and local
   30.50 +      changes you require.  In this situation, if you submit a bug fix
   30.51 +      patch to the upstream maintainers of a package and they include
   30.52 +      your fix in a subsequent release, you can simply drop that
   30.53 +      single patch when you're updating to the newer release.</para>
   30.54 +
   30.55 +    <para>Maintaining a single patch against an upstream tree is a
   30.56 +      little tedious and error-prone, but not difficult.  However, the
   30.57 +      complexity of the problem grows rapidly as the number of patches
   30.58 +      you have to maintain increases.  With more than a tiny number of
   30.59 +      patches in hand, understanding which ones you have applied and
   30.60 +      maintaining them moves from messy to overwhelming.</para>
   30.61 +
   30.62 +    <para>Fortunately, Mercurial includes a powerful extension,
   30.63 +      Mercurial Queues (or simply <quote>MQ</quote>), that massively
   30.64 +      simplifies the patch management problem.</para>
   30.65 +
   30.66 +  </sect1>
   30.67 +  <sect1 id="sec.mq.history">
   30.68 +    <title>The prehistory of Mercurial Queues</title>
   30.69 +
   30.70 +    <para>During the late 1990s, several Linux kernel developers
   30.71 +      started to maintain <quote>patch series</quote> that modified
   30.72 +      the behaviour of the Linux kernel.  Some of these series were
   30.73 +      focused on stability, some on feature coverage, and others were
   30.74 +      more speculative.</para>
   30.75 +
   30.76 +    <para>The sizes of these patch series grew rapidly.  In 2002,
   30.77 +      Andrew Morton published some shell scripts he had been using to
   30.78 +      automate the task of managing his patch queues.  Andrew was
   30.79 +      successfully using these scripts to manage hundreds (sometimes
   30.80 +      thousands) of patches on top of the Linux kernel.</para>
   30.81 +
   30.82 +    <sect2 id="sec.mq.quilt">
   30.83 +      <title>A patchwork quilt</title>
   30.84 +
   30.85 +      <para>In early 2003, Andreas Gruenbacher and Martin Quinson
   30.86 +	borrowed the approach of Andrew's scripts and published a tool
   30.87 +	called <quote>patchwork quilt</quote>
   30.88 +	<citation>web:quilt</citation>, or simply <quote>quilt</quote>
   30.89 +	(see <citation>gruenbacher:2005</citation> for a paper
   30.90 +	describing it).  Because quilt substantially automated patch
   30.91 +	management, it rapidly gained a large following among open
   30.92 +	source software developers.</para>
   30.93 +
   30.94 +      <para>Quilt manages a <emphasis>stack of patches</emphasis> on
   30.95 +	top of a directory tree. To begin, you tell quilt to manage a
   30.96 +	directory tree, and tell it which files you want to manage; it
   30.97 +	stores away the names and contents of those files.  To fix a
   30.98 +	bug, you create a new patch (using a single command), edit the
   30.99 +	files you need to fix, then <quote>refresh</quote> the
  30.100 +	patch.</para>
  30.101 +
  30.102 +      <para>The refresh step causes quilt to scan the directory tree;
  30.103 +	it updates the patch with all of the changes you have made.
  30.104 +	You can create another patch on top of the first, which will
  30.105 +	track the changes required to modify the tree from <quote>tree
  30.106 +	  with one patch applied</quote> to <quote>tree with two
  30.107 +	  patches applied</quote>.</para>
  30.108 +
  30.109 +      <para>You can <emphasis>change</emphasis> which patches are
  30.110 +	applied to the tree.  If you <quote>pop</quote> a patch, the
  30.111 +	changes made by that patch will vanish from the directory
  30.112 +	tree.  Quilt remembers which patches you have popped, though,
  30.113 +	so you can <quote>push</quote> a popped patch again, and the
  30.114 +	directory tree will be restored to contain the modifications
  30.115 +	in the patch.  Most importantly, you can run the
  30.116 +	<quote>refresh</quote> command at any time, and the topmost
  30.117 +	applied patch will be updated.  This means that you can, at
  30.118 +	any time, change both which patches are applied and what
  30.119 +	modifications those patches make.</para>
  30.120 +
  30.121 +      <para>Quilt knows nothing about revision control tools, so it
  30.122 +	works equally well on top of an unpacked tarball or a
  30.123 +	Subversion working copy.</para>
  30.124 +
  30.125 +    </sect2>
  30.126 +    <sect2 id="sec.mq.quilt-mq">
  30.127 +      <title>From patchwork quilt to Mercurial Queues</title>
  30.128 +
  30.129 +      <para>In mid-2005, Chris Mason took the features of quilt and
  30.130 +	wrote an extension that he called Mercurial Queues, which
  30.131 +	added quilt-like behaviour to Mercurial.</para>
  30.132 +
  30.133 +      <para>The key difference between quilt and MQ is that quilt
  30.134 +	knows nothing about revision control systems, while MQ is
  30.135 +	<emphasis>integrated</emphasis> into Mercurial.  Each patch
  30.136 +	that you push is represented as a Mercurial changeset.  Pop a
  30.137 +	patch, and the changeset goes away.</para>
  30.138 +
  30.139 +      <para>Because quilt does not care about revision control tools,
  30.140 +	it is still a tremendously useful piece of software to know
  30.141 +	about for situations where you cannot use Mercurial and
  30.142 +	MQ.</para>
  30.143 +
  30.144 +    </sect2>
  30.145 +  </sect1>
  30.146 +  <sect1>
  30.147 +    <title>The huge advantage of MQ</title>
  30.148 +
  30.149 +    <para>I cannot overstate the value that MQ offers through the
  30.150 +      unification of patches and revision control.</para>
  30.151 +
  30.152 +    <para>A major reason that patches have persisted in the free
  30.153 +      software and open source world&emdash;in spite of the
  30.154 +      availability of increasingly capable revision control tools over
  30.155 +      the years&emdash;is the <emphasis>agility</emphasis> they
  30.156 +      offer.</para>
  30.157 +
  30.158 +    <para>Traditional revision control tools make a permanent,
  30.159 +      irreversible record of everything that you do.  While this has
  30.160 +      great value, it's also somewhat stifling.  If you want to
  30.161 +      perform a wild-eyed experiment, you have to be careful in how
  30.162 +      you go about it, or you risk leaving unneeded&emdash;or worse,
  30.163 +      misleading or destabilising&emdash;traces of your missteps and
  30.164 +      errors in the permanent revision record.</para>
  30.165 +
  30.166 +    <para>By contrast, MQ's marriage of distributed revision control
  30.167 +      with patches makes it much easier to isolate your work.  Your
  30.168 +      patches live on top of normal revision history, and you can make
  30.169 +      them disappear or reappear at will.  If you don't like a patch,
  30.170 +      you can drop it.  If a patch isn't quite as you want it to be,
  30.171 +      simply fix it&emdash;as many times as you need to, until you
  30.172 +      have refined it into the form you desire.</para>
  30.173 +
  30.174 +    <para>As an example, the integration of patches with revision
  30.175 +      control makes understanding patches and debugging their
  30.176 +      effects&emdash;and their interplay with the code they're based
  30.177 +      on&emdash;<emphasis>enormously</emphasis> easier. Since every
  30.178 +      applied patch has an associated changeset, you can give <command
  30.179 +	role="hg-cmd">hg log</command> a file name to see which
  30.180 +      changesets and patches affected the file.  You can use the
  30.181 +      <command role="hg-cmd">hg bisect</command> command to
  30.182 +      binary-search through all changesets and applied patches to see
  30.183 +      where a bug got introduced or fixed.  You can use the <command
  30.184 +	role="hg-cmd">hg annotate</command> command to see which
  30.185 +      changeset or patch modified a particular line of a source file.
  30.186 +      And so on.</para>
  30.187 +
  30.188 +  </sect1>
  30.189 +  <sect1 id="sec.mq.patch">
  30.190 +    <title>Understanding patches</title>
  30.191 +
  30.192 +    <para>Because MQ doesn't hide its patch-oriented nature, it is
  30.193 +      helpful to understand what patches are, and a little about the
  30.194 +      tools that work with them.</para>
  30.195 +
  30.196 +    <para>The traditional Unix <command>diff</command> command
  30.197 +      compares two files, and prints a list of differences between
  30.198 +      them. The <command>patch</command> command understands these
  30.199 +      differences as <emphasis>modifications</emphasis> to make to a
  30.200 +      file.  Take a look below for a simple example of these commands
  30.201 +      in action.</para>
  30.202 +
  30.203 +&interaction.mq.dodiff.diff;
  30.204 +
  30.205 +    <para>The type of file that <command>diff</command> generates (and
  30.206 +      <command>patch</command> takes as input) is called a
  30.207 +      <quote>patch</quote> or a <quote>diff</quote>; there is no
  30.208 +      difference between a patch and a diff.  (We'll use the term
  30.209 +      <quote>patch</quote>, since it's more commonly used.)</para>
  30.210 +
  30.211 +    <para>A patch file can start with arbitrary text; the
  30.212 +      <command>patch</command> command ignores this text, but MQ uses
  30.213 +      it as the commit message when creating changesets.  To find the
  30.214 +      beginning of the patch content, <command>patch</command>
  30.215 +      searches for the first line that starts with the string
  30.216 +      <quote><literal>diff -</literal></quote>.</para>
  30.217 +
  30.218 +    <para>MQ works with <emphasis>unified</emphasis> diffs
  30.219 +      (<command>patch</command> can accept several other diff formats,
  30.220 +      but MQ doesn't).  A unified diff contains two kinds of header.
  30.221 +      The <emphasis>file header</emphasis> describes the file being
  30.222 +      modified; it contains the name of the file to modify.  When
  30.223 +      <command>patch</command> sees a new file header, it looks for a
  30.224 +      file with that name to start modifying.</para>
  30.225 +
  30.226 +    <para>After the file header comes a series of
  30.227 +      <emphasis>hunks</emphasis>.  Each hunk starts with a header;
  30.228 +      this identifies the range of line numbers within the file that
  30.229 +      the hunk should modify.  Following the header, a hunk starts and
  30.230 +      ends with a few (usually three) lines of text from the
  30.231 +      unmodified file; these are called the
  30.232 +      <emphasis>context</emphasis> for the hunk.  If there's only a
  30.233 +      small amount of context between successive hunks,
  30.234 +      <command>diff</command> doesn't print a new hunk header; it just
  30.235 +      runs the hunks together, with a few lines of context between
  30.236 +      modifications.</para>
  30.237 +
  30.238 +    <para>Each line of context begins with a space character.  Within
  30.239 +      the hunk, a line that begins with
  30.240 +      <quote><literal>-</literal></quote> means <quote>remove this
  30.241 +	line,</quote> while a line that begins with
  30.242 +      <quote><literal>+</literal></quote> means <quote>insert this
  30.243 +	line.</quote>  For example, a line that is modified is
  30.244 +      represented by one deletion and one insertion.</para>
  30.245 +
  30.246 +    <para>We will return to some of the more subtle aspects of patches
  30.247 +      later (in section <xref linkend="sec.mq.adv-patch"/>), but you
  30.248 +      should have
  30.249 +      enough information now to use MQ.</para>
  30.250 +
  30.251 +  </sect1>
  30.252 +  <sect1 id="sec.mq.start">
  30.253 +    <title>Getting started with Mercurial Queues</title>
  30.254 +
  30.255 +    <para>Because MQ is implemented as an extension, you must
  30.256 +      explicitly enable before you can use it.  (You don't need to
  30.257 +      download anything; MQ ships with the standard Mercurial
  30.258 +      distribution.)  To enable MQ, edit your <filename
  30.259 +	role="home">~/.hgrc</filename> file, and add the lines
  30.260 +      below.</para>
  30.261 +
  30.262 +    <programlisting>[extensions]
  30.263 +hgext.mq =</programlisting>
  30.264 +
  30.265 +    <para>Once the extension is enabled, it will make a number of new
  30.266 +      commands available.  To verify that the extension is working,
  30.267 +      you can use <command role="hg-cmd">hg help</command> to see if
  30.268 +      the <command role="hg-ext-mq">qinit</command> command is now
  30.269 +      available.</para>
  30.270 +
  30.271 +&interaction.mq.qinit-help.help;
  30.272 +
  30.273 +    <para>You can use MQ with <emphasis>any</emphasis> Mercurial
  30.274 +      repository, and its commands only operate within that
  30.275 +      repository.  To get started, simply prepare the repository using
  30.276 +      the <command role="hg-ext-mq">qinit</command> command.</para>
  30.277 +
  30.278 +&interaction.mq.tutorial.qinit;
  30.279 +
  30.280 +    <para>This command creates an empty directory called <filename
  30.281 +	role="special" class="directory">.hg/patches</filename>, where
  30.282 +      MQ will keep its metadata.  As with many Mercurial commands, the
  30.283 +      <command role="hg-ext-mq">qinit</command> command prints nothing
  30.284 +      if it succeeds.</para>
  30.285 +
  30.286 +    <sect2>
  30.287 +      <title>Creating a new patch</title>
  30.288 +
  30.289 +      <para>To begin work on a new patch, use the <command
  30.290 +	  role="hg-ext-mq">qnew</command> command.  This command takes
  30.291 +	one argument, the name of the patch to create.</para>
  30.292 +
  30.293 +      <para>MQ will use this as the name of an actual file in the
  30.294 +	<filename role="special"
  30.295 +	  class="directory">.hg/patches</filename> directory, as you
  30.296 +	can see below.</para>
  30.297 +
  30.298 +&interaction.mq.tutorial.qnew;
  30.299 +
  30.300 +      <para>Also newly present in the <filename role="special"
  30.301 +	  class="directory">.hg/patches</filename> directory are two
  30.302 +	other files, <filename role="special">series</filename> and
  30.303 +	<filename role="special">status</filename>.  The <filename
  30.304 +	  role="special">series</filename> file lists all of the
  30.305 +	patches that MQ knows about for this repository, with one
  30.306 +	patch per line.  Mercurial uses the <filename
  30.307 +	  role="special">status</filename> file for internal
  30.308 +	book-keeping; it tracks all of the patches that MQ has
  30.309 +	<emphasis>applied</emphasis> in this repository.</para>
  30.310 +
  30.311 +      <note>
  30.312 +	<para>  You may sometimes want to edit the <filename
  30.313 +	    role="special">series</filename> file by hand; for
  30.314 +	  example, to change the sequence in which some patches are
  30.315 +	  applied.  However, manually editing the <filename
  30.316 +	    role="special">status</filename> file is almost always a
  30.317 +	  bad idea, as it's easy to corrupt MQ's idea of what is
  30.318 +	  happening.</para>
  30.319 +      </note>
  30.320 +
  30.321 +      <para>Once you have created your new patch, you can edit files
  30.322 +	in the working directory as you usually would.  All of the
  30.323 +	normal Mercurial commands, such as <command role="hg-cmd">hg
  30.324 +	  diff</command> and <command role="hg-cmd">hg
  30.325 +	  annotate</command>, work exactly as they did before.</para>
  30.326 +
  30.327 +    </sect2>
  30.328 +    <sect2>
  30.329 +      <title>Refreshing a patch</title>
  30.330 +
  30.331 +      <para>When you reach a point where you want to save your work,
  30.332 +	use the <command role="hg-ext-mq">qrefresh</command> command
  30.333 +	to update the patch you are working on.</para>
  30.334 +
  30.335 +&interaction.mq.tutorial.qrefresh;
  30.336 +
  30.337 +      <para>This command folds the changes you have made in the
  30.338 +	working directory into your patch, and updates its
  30.339 +	corresponding changeset to contain those changes.</para>
  30.340 +
  30.341 +      <para>You can run <command role="hg-ext-mq">qrefresh</command>
  30.342 +	as often as you like, so it's a good way to
  30.343 +	<quote>checkpoint</quote> your work.  Refresh your patch at an
  30.344 +	opportune time; try an experiment; and if the experiment
  30.345 +	doesn't work out, <command role="hg-cmd">hg revert</command>
  30.346 +	your modifications back to the last time you refreshed.</para>
  30.347 +
  30.348 +&interaction.mq.tutorial.qrefresh2;
  30.349 +
  30.350 +    </sect2>
  30.351 +    <sect2>
  30.352 +      <title>Stacking and tracking patches</title>
  30.353 +
  30.354 +      <para>Once you have finished working on a patch, or need to work
  30.355 +	on another, you can use the <command
  30.356 +	  role="hg-ext-mq">qnew</command> command again to create a
  30.357 +	new patch. Mercurial will apply this patch on top of your
  30.358 +	existing patch.</para>
  30.359 +
  30.360 +&interaction.mq.tutorial.qnew2;
  30.361 +      <para>Notice that the patch contains the changes in our prior
  30.362 +	patch as part of its context (you can see this more clearly in
  30.363 +	the output of <command role="hg-cmd">hg
  30.364 +	  annotate</command>).</para>
  30.365 +
  30.366 +      <para>So far, with the exception of <command
  30.367 +	  role="hg-ext-mq">qnew</command> and <command
  30.368 +	  role="hg-ext-mq">qrefresh</command>, we've been careful to
  30.369 +	only use regular Mercurial commands.  However, MQ provides
  30.370 +	many commands that are easier to use when you are thinking
  30.371 +	about patches, as illustrated below.</para>
  30.372 +
  30.373 +&interaction.mq.tutorial.qseries;
  30.374 +
  30.375 +      <itemizedlist>
  30.376 +	<listitem><para>The <command
  30.377 +	      role="hg-ext-mq">qseries</command> command lists every
  30.378 +	    patch that MQ knows about in this repository, from oldest
  30.379 +	    to newest (most recently
  30.380 +	    <emphasis>created</emphasis>).</para>
  30.381 +	</listitem>
  30.382 +	<listitem><para>The <command
  30.383 +	      role="hg-ext-mq">qapplied</command> command lists every
  30.384 +	    patch that MQ has <emphasis>applied</emphasis> in this
  30.385 +	    repository, again from oldest to newest (most recently
  30.386 +	    applied).</para>
  30.387 +	</listitem></itemizedlist>
  30.388 +
  30.389 +    </sect2>
  30.390 +    <sect2>
  30.391 +      <title>Manipulating the patch stack</title>
  30.392 +
  30.393 +      <para>The previous discussion implied that there must be a
  30.394 +	difference between <quote>known</quote> and
  30.395 +	<quote>applied</quote> patches, and there is.  MQ can manage a
  30.396 +	patch without it being applied in the repository.</para>
  30.397 +
  30.398 +      <para>An <emphasis>applied</emphasis> patch has a corresponding
  30.399 +	changeset in the repository, and the effects of the patch and
  30.400 +	changeset are visible in the working directory.  You can undo
  30.401 +	the application of a patch using the <command
  30.402 +	  role="hg-ext-mq">qpop</command> command.  MQ still
  30.403 +	<emphasis>knows about</emphasis>, or manages, a popped patch,
  30.404 +	but the patch no longer has a corresponding changeset in the
  30.405 +	repository, and the working directory does not contain the
  30.406 +	changes made by the patch.  Figure <xref
  30.407 +	  endterm="fig.mq.stack.caption" linkend="fig.mq.stack"/> illustrates
  30.408 +	the difference between applied and tracked patches.</para>
  30.409 +
  30.410 +      <informalfigure id="fig.mq.stack">
  30.411 +        <mediaobject>
  30.412 +          <imageobject><imagedata fileref="images/mq-stack.png"/></imageobject>
  30.413 +          <textobject><phrase>XXX add text</phrase></textobject>
  30.414 +          <caption><para id="fig.mq.stack.caption">Applied and unapplied patches
  30.415 +            in the MQ patch stack</para></caption>
  30.416 +          </mediaobject>
  30.417 +      </informalfigure>
  30.418 +
  30.419 +      <para>You can reapply an unapplied, or popped, patch using the
  30.420 +	<command role="hg-ext-mq">qpush</command> command.  This
  30.421 +	creates a new changeset to correspond to the patch, and the
  30.422 +	patch's changes once again become present in the working
  30.423 +	directory.  See below for examples of <command
  30.424 +	  role="hg-ext-mq">qpop</command> and <command
  30.425 +	  role="hg-ext-mq">qpush</command> in action.</para>
  30.426 +&interaction.mq.tutorial.qpop;
  30.427 +
  30.428 +      <para>Notice that once we have popped a patch or two patches,
  30.429 +	the output of <command role="hg-ext-mq">qseries</command>
  30.430 +	remains the same, while that of <command
  30.431 +	  role="hg-ext-mq">qapplied</command> has changed.</para>
  30.432 +
  30.433 +
  30.434 +    </sect2>
  30.435 +    <sect2>
  30.436 +      <title>Pushing and popping many patches</title>
  30.437 +
  30.438 +      <para>While <command role="hg-ext-mq">qpush</command> and
  30.439 +	<command role="hg-ext-mq">qpop</command> each operate on a
  30.440 +	single patch at a time by default, you can push and pop many
  30.441 +	patches in one go.  The <option
  30.442 +	  role="hg-ext-mq-cmd-qpush-opt">hg -a</option> option to
  30.443 +	<command role="hg-ext-mq">qpush</command> causes it to push
  30.444 +	all unapplied patches, while the <option
  30.445 +	  role="hg-ext-mq-cmd-qpop-opt">-a</option> option to <command
  30.446 +	  role="hg-ext-mq">qpop</command> causes it to pop all applied
  30.447 +	patches.  (For some more ways to push and pop many patches,
  30.448 +	see section <xref linkend="sec.mq.perf"/>
  30.449 +	below.)</para>
  30.450 +
  30.451 +&interaction.mq.tutorial.qpush-a;
  30.452 +
  30.453 +    </sect2>
  30.454 +    <sect2>
  30.455 +      <title>Safety checks, and overriding them</title>
  30.456 +
  30.457 +      <para>Several MQ commands check the working directory before
  30.458 +	they do anything, and fail if they find any modifications.
  30.459 +	They do this to ensure that you won't lose any changes that
  30.460 +	you have made, but not yet incorporated into a patch.  The
  30.461 +	example below illustrates this; the <command
  30.462 +	  role="hg-ext-mq">qnew</command> command will not create a
  30.463 +	new patch if there are outstanding changes, caused in this
  30.464 +	case by the <command role="hg-cmd">hg add</command> of
  30.465 +	<filename>file3</filename>.</para>
  30.466 +
  30.467 +&interaction.mq.tutorial.add;
  30.468 +
  30.469 +      <para>Commands that check the working directory all take an
  30.470 +	<quote>I know what I'm doing</quote> option, which is always
  30.471 +	named <option>-f</option>.  The exact meaning of
  30.472 +	<option>-f</option> depends on the command.  For example,
  30.473 +	<command role="hg-cmd">hg qnew <option
  30.474 +	    role="hg-ext-mq-cmd-qnew-opt">hg -f</option></command>
  30.475 +	will incorporate any outstanding changes into the new patch it
  30.476 +	creates, but <command role="hg-cmd">hg qpop <option
  30.477 +	    role="hg-ext-mq-cmd-qpop-opt">hg -f</option></command>
  30.478 +	will revert modifications to any files affected by the patch
  30.479 +	that it is popping.  Be sure to read the documentation for a
  30.480 +	command's <option>-f</option> option before you use it!</para>
  30.481 +
  30.482 +    </sect2>
  30.483 +    <sect2>
  30.484 +      <title>Working on several patches at once</title>
  30.485 +
  30.486 +      <para>The <command role="hg-ext-mq">qrefresh</command> command
  30.487 +	always refreshes the <emphasis>topmost</emphasis> applied
  30.488 +	patch.  This means that you can suspend work on one patch (by
  30.489 +	refreshing it), pop or push to make a different patch the top,
  30.490 +	and work on <emphasis>that</emphasis> patch for a
  30.491 +	while.</para>
  30.492 +
  30.493 +      <para>Here's an example that illustrates how you can use this
  30.494 +	ability. Let's say you're developing a new feature as two
  30.495 +	patches.  The first is a change to the core of your software,
  30.496 +	and the second&emdash;layered on top of the
  30.497 +	first&emdash;changes the user interface to use the code you
  30.498 +	just added to the core.  If you notice a bug in the core while
  30.499 +	you're working on the UI patch, it's easy to fix the core.
  30.500 +	Simply <command role="hg-ext-mq">qrefresh</command> the UI
  30.501 +	patch to save your in-progress changes, and <command
  30.502 +	  role="hg-ext-mq">qpop</command> down to the core patch.  Fix
  30.503 +	the core bug, <command role="hg-ext-mq">qrefresh</command> the
  30.504 +	core patch, and <command role="hg-ext-mq">qpush</command> back
  30.505 +	to the UI patch to continue where you left off.</para>
  30.506 +
  30.507 +    </sect2>
  30.508 +  </sect1>
  30.509 +  <sect1 id="sec.mq.adv-patch">
  30.510 +    <title>More about patches</title>
  30.511 +
  30.512 +    <para>MQ uses the GNU <command>patch</command> command to apply
  30.513 +      patches, so it's helpful to know a few more detailed aspects of
  30.514 +      how <command>patch</command> works, and about patches
  30.515 +      themselves.</para>
  30.516 +
  30.517 +    <sect2>
  30.518 +      <title>The strip count</title>
  30.519 +
  30.520 +      <para>If you look at the file headers in a patch, you will
  30.521 +	notice that the pathnames usually have an extra component on
  30.522 +	the front that isn't present in the actual path name.  This is
  30.523 +	a holdover from the way that people used to generate patches
  30.524 +	(people still do this, but it's somewhat rare with modern
  30.525 +	revision control tools).</para>
  30.526 +
  30.527 +      <para>Alice would unpack a tarball, edit her files, then decide
  30.528 +	that she wanted to create a patch.  So she'd rename her
  30.529 +	working directory, unpack the tarball again (hence the need
  30.530 +	for the rename), and use the <option
  30.531 +	  role="cmd-opt-diff">-r</option> and <option
  30.532 +	  role="cmd-opt-diff">-N</option> options to
  30.533 +	<command>diff</command> to recursively generate a patch
  30.534 +	between the unmodified directory and the modified one.  The
  30.535 +	result would be that the name of the unmodified directory
  30.536 +	would be at the front of the left-hand path in every file
  30.537 +	header, and the name of the modified directory would be at the
  30.538 +	front of the right-hand path.</para>
  30.539 +
  30.540 +      <para>Since someone receiving a patch from the Alices of the net
  30.541 +	would be unlikely to have unmodified and modified directories
  30.542 +	with exactly the same names, the <command>patch</command>
  30.543 +	command has a <option role="cmd-opt-patch">-p</option> option
  30.544 +	that indicates the number of leading path name components to
  30.545 +	strip when trying to apply a patch.  This number is called the
  30.546 +	<emphasis>strip count</emphasis>.</para>
  30.547 +
  30.548 +      <para>An option of <quote><literal>-p1</literal></quote> means
  30.549 +	<quote>use a strip count of one</quote>.  If
  30.550 +	<command>patch</command> sees a file name
  30.551 +	<filename>foo/bar/baz</filename> in a file header, it will
  30.552 +	strip <filename>foo</filename> and try to patch a file named
  30.553 +	<filename>bar/baz</filename>.  (Strictly speaking, the strip
  30.554 +	count refers to the number of <emphasis>path
  30.555 +	  separators</emphasis> (and the components that go with them
  30.556 +	) to strip.  A strip count of one will turn
  30.557 +	<filename>foo/bar</filename> into <filename>bar</filename>,
  30.558 +	but <filename>/foo/bar</filename> (notice the extra leading
  30.559 +	slash) into <filename>foo/bar</filename>.)</para>
  30.560 +
  30.561 +      <para>The <quote>standard</quote> strip count for patches is
  30.562 +	one; almost all patches contain one leading path name
  30.563 +	component that needs to be stripped. Mercurial's <command
  30.564 +	  role="hg-cmd">hg diff</command> command generates path names
  30.565 +	in this form, and the <command role="hg-cmd">hg
  30.566 +	  import</command> command and MQ expect patches to have a
  30.567 +	strip count of one.</para>
  30.568 +
  30.569 +      <para>If you receive a patch from someone that you want to add
  30.570 +	to your patch queue, and the patch needs a strip count other
  30.571 +	than one, you cannot just <command
  30.572 +	  role="hg-ext-mq">qimport</command> the patch, because
  30.573 +	<command role="hg-ext-mq">qimport</command> does not yet have
  30.574 +	a <literal>-p</literal> option (see <ulink role="hg-bug"
  30.575 +	  url="http://www.selenic.com/mercurial/bts/issue311">issue
  30.576 +	  311</ulink>).  Your best bet is to <command
  30.577 +	  role="hg-ext-mq">qnew</command> a patch of your own, then
  30.578 +	use <command>patch -pN</command> to apply their patch,
  30.579 +	followed by <command role="hg-cmd">hg addremove</command> to
  30.580 +	pick up any files added or removed by the patch, followed by
  30.581 +	<command role="hg-ext-mq">hg qrefresh</command>. This
  30.582 +	complexity may become unnecessary; see <ulink role="hg-bug"
  30.583 +	  url="http://www.selenic.com/mercurial/bts/issue311">issue
  30.584 +	  311</ulink> for details.
  30.585 +      </para>
  30.586 +    </sect2>
  30.587 +    <sect2>
  30.588 +      <title>Strategies for applying a patch</title>
  30.589 +
  30.590 +      <para>When <command>patch</command> applies a hunk, it tries a
  30.591 +	handful of successively less accurate strategies to try to
  30.592 +	make the hunk apply. This falling-back technique often makes
  30.593 +	it possible to take a patch that was generated against an old
  30.594 +	version of a file, and apply it against a newer version of
  30.595 +	that file.</para>
  30.596 +
  30.597 +      <para>First, <command>patch</command> tries an exact match,
  30.598 +	where the line numbers, the context, and the text to be
  30.599 +	modified must apply exactly.  If it cannot make an exact
  30.600 +	match, it tries to find an exact match for the context,
  30.601 +	without honouring the line numbering information.  If this
  30.602 +	succeeds, it prints a line of output saying that the hunk was
  30.603 +	applied, but at some <emphasis>offset</emphasis> from the
  30.604 +	original line number.</para>
  30.605 +
  30.606 +      <para>If a context-only match fails, <command>patch</command>
  30.607 +	removes the first and last lines of the context, and tries a
  30.608 +	<emphasis>reduced</emphasis> context-only match.  If the hunk
  30.609 +	with reduced context succeeds, it prints a message saying that
  30.610 +	it applied the hunk with a <emphasis>fuzz factor</emphasis>
  30.611 +	(the number after the fuzz factor indicates how many lines of
  30.612 +	context <command>patch</command> had to trim before the patch
  30.613 +	applied).</para>
  30.614 +
  30.615 +      <para>When neither of these techniques works,
  30.616 +	<command>patch</command> prints a message saying that the hunk
  30.617 +	in question was rejected.  It saves rejected hunks (also
  30.618 +	simply called <quote>rejects</quote>) to a file with the same
  30.619 +	name, and an added <filename role="special">.rej</filename>
  30.620 +	extension.  It also saves an unmodified copy of the file with
  30.621 +	a <filename role="special">.orig</filename> extension; the
  30.622 +	copy of the file without any extensions will contain any
  30.623 +	changes made by hunks that <emphasis>did</emphasis> apply
  30.624 +	cleanly.  If you have a patch that modifies
  30.625 +	<filename>foo</filename> with six hunks, and one of them fails
  30.626 +	to apply, you will have: an unmodified
  30.627 +	<filename>foo.orig</filename>, a <filename>foo.rej</filename>
  30.628 +	containing one hunk, and <filename>foo</filename>, containing
  30.629 +	the changes made by the five successful hunks.</para>
  30.630 +
  30.631 +    </sect2>
  30.632 +    <sect2>
  30.633 +      <title>Some quirks of patch representation</title>
  30.634 +
  30.635 +      <para>There are a few useful things to know about how
  30.636 +	<command>patch</command> works with files.</para>
  30.637 +      <itemizedlist>
  30.638 +	<listitem><para>This should already be obvious, but
  30.639 +	    <command>patch</command> cannot handle binary
  30.640 +	    files.</para>
  30.641 +	</listitem>
  30.642 +	<listitem><para>Neither does it care about the executable bit;
  30.643 +	    it creates new files as readable, but not
  30.644 +	    executable.</para>
  30.645 +	</listitem>
  30.646 +	<listitem><para><command>patch</command> treats the removal of
  30.647 +	    a file as a diff between the file to be removed and the
  30.648 +	    empty file.  So your idea of <quote>I deleted this
  30.649 +	      file</quote> looks like <quote>every line of this file
  30.650 +	      was deleted</quote> in a patch.</para>
  30.651 +	</listitem>
  30.652 +	<listitem><para>It treats the addition of a file as a diff
  30.653 +	    between the empty file and the file to be added.  So in a
  30.654 +	    patch, your idea of <quote>I added this file</quote> looks
  30.655 +	    like <quote>every line of this file was
  30.656 +	      added</quote>.</para>
  30.657 +	</listitem>
  30.658 +	<listitem><para>It treats a renamed file as the removal of the
  30.659 +	    old name, and the addition of the new name.  This means
  30.660 +	    that renamed files have a big footprint in patches.  (Note
  30.661 +	    also that Mercurial does not currently try to infer when
  30.662 +	    files have been renamed or copied in a patch.)</para>
  30.663 +	</listitem>
  30.664 +	<listitem><para><command>patch</command> cannot represent
  30.665 +	    empty files, so you cannot use a patch to represent the
  30.666 +	    notion <quote>I added this empty file to the
  30.667 +	      tree</quote>.</para>
  30.668 +	</listitem></itemizedlist>
  30.669 +    </sect2>
  30.670 +    <sect2>
  30.671 +      <title>Beware the fuzz</title>
  30.672 +
  30.673 +      <para>While applying a hunk at an offset, or with a fuzz factor,
  30.674 +	will often be completely successful, these inexact techniques
  30.675 +	naturally leave open the possibility of corrupting the patched
  30.676 +	file.  The most common cases typically involve applying a
  30.677 +	patch twice, or at an incorrect location in the file.  If
  30.678 +	<command>patch</command> or <command
  30.679 +	  role="hg-ext-mq">qpush</command> ever mentions an offset or
  30.680 +	fuzz factor, you should make sure that the modified files are
  30.681 +	correct afterwards.</para>
  30.682 +
  30.683 +      <para>It's often a good idea to refresh a patch that has applied
  30.684 +	with an offset or fuzz factor; refreshing the patch generates
  30.685 +	new context information that will make it apply cleanly.  I
  30.686 +	say <quote>often,</quote> not <quote>always,</quote> because
  30.687 +	sometimes refreshing a patch will make it fail to apply
  30.688 +	against a different revision of the underlying files.  In some
  30.689 +	cases, such as when you're maintaining a patch that must sit
  30.690 +	on top of multiple versions of a source tree, it's acceptable
  30.691 +	to have a patch apply with some fuzz, provided you've verified
  30.692 +	the results of the patching process in such cases.</para>
  30.693 +
  30.694 +    </sect2>
  30.695 +    <sect2>
  30.696 +      <title>Handling rejection</title>
  30.697 +
  30.698 +      <para>If <command role="hg-ext-mq">qpush</command> fails to
  30.699 +	apply a patch, it will print an error message and exit.  If it
  30.700 +	has left <filename role="special">.rej</filename> files
  30.701 +	behind, it is usually best to fix up the rejected hunks before
  30.702 +	you push more patches or do any further work.</para>
  30.703 +
  30.704 +      <para>If your patch <emphasis>used to</emphasis> apply cleanly,
  30.705 +	and no longer does because you've changed the underlying code
  30.706 +	that your patches are based on, Mercurial Queues can help; see
  30.707 +	section <xref
  30.708 +	  linkend="sec.mq.merge"/> for details.</para>
  30.709 +
  30.710 +      <para>Unfortunately, there aren't any great techniques for
  30.711 +	dealing with rejected hunks.  Most often, you'll need to view
  30.712 +	the <filename role="special">.rej</filename> file and edit the
  30.713 +	target file, applying the rejected hunks by hand.</para>
  30.714 +
  30.715 +      <para>If you're feeling adventurous, Neil Brown, a Linux kernel
  30.716 +	hacker, wrote a tool called <command>wiggle</command>
  30.717 +	<citation>web:wiggle</citation>, which is more vigorous than
  30.718 +	<command>patch</command> in its attempts to make a patch
  30.719 +	apply.</para>
  30.720 +
  30.721 +      <para>Another Linux kernel hacker, Chris Mason (the author of
  30.722 +	Mercurial Queues), wrote a similar tool called
  30.723 +	<command>mpatch</command> <citation>web:mpatch</citation>,
  30.724 +	which takes a simple approach to automating the application of
  30.725 +	hunks rejected by <command>patch</command>.  The
  30.726 +	<command>mpatch</command> command can help with four common
  30.727 +	reasons that a hunk may be rejected:</para>
  30.728 +
  30.729 +      <itemizedlist>
  30.730 +	<listitem><para>The context in the middle of a hunk has
  30.731 +	    changed.</para>
  30.732 +	</listitem>
  30.733 +	<listitem><para>A hunk is missing some context at the
  30.734 +	    beginning or end.</para>
  30.735 +	</listitem>
  30.736 +	<listitem><para>A large hunk might apply better&emdash;either
  30.737 +	    entirely or in part&emdash;if it was broken up into
  30.738 +	    smaller hunks.</para>
  30.739 +	</listitem>
  30.740 +	<listitem><para>A hunk removes lines with slightly different
  30.741 +	    content than those currently present in the file.</para>
  30.742 +	</listitem></itemizedlist>
  30.743 +
  30.744 +      <para>If you use <command>wiggle</command> or
  30.745 +	<command>mpatch</command>, you should be doubly careful to
  30.746 +	check your results when you're done.  In fact,
  30.747 +	<command>mpatch</command> enforces this method of
  30.748 +	double-checking the tool's output, by automatically dropping
  30.749 +	you into a merge program when it has done its job, so that you
  30.750 +	can verify its work and finish off any remaining
  30.751 +	merges.</para>
  30.752 +
  30.753 +    </sect2>
  30.754 +  </sect1>
  30.755 +  <sect1 id="sec.mq.perf">
  30.756 +    <title>Getting the best performance out of MQ</title>
  30.757 +
  30.758 +    <para>MQ is very efficient at handling a large number of patches.
  30.759 +      I ran some performance experiments in mid-2006 for a talk that I
  30.760 +      gave at the 2006 EuroPython conference
  30.761 +      <citation>web:europython</citation>.  I used as my data set the
  30.762 +      Linux 2.6.17-mm1 patch series, which consists of 1,738 patches.
  30.763 +      I applied these on top of a Linux kernel repository containing
  30.764 +      all 27,472 revisions between Linux 2.6.12-rc2 and Linux
  30.765 +      2.6.17.</para>
  30.766 +
  30.767 +    <para>On my old, slow laptop, I was able to <command
  30.768 +	role="hg-cmd">hg qpush <option
  30.769 +	  role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> all
  30.770 +      1,738 patches in 3.5 minutes, and <command role="hg-cmd">hg qpop
  30.771 +	<option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command>
  30.772 +      them all in 30 seconds.  (On a newer laptop, the time to push
  30.773 +      all patches dropped to two minutes.)  I could <command
  30.774 +	role="hg-ext-mq">qrefresh</command> one of the biggest patches
  30.775 +      (which made 22,779 lines of changes to 287 files) in 6.6
  30.776 +      seconds.</para>
  30.777 +
  30.778 +    <para>Clearly, MQ is well suited to working in large trees, but
  30.779 +      there are a few tricks you can use to get the best performance
  30.780 +      of it.</para>
  30.781 +
  30.782 +    <para>First of all, try to <quote>batch</quote> operations
  30.783 +      together.  Every time you run <command
  30.784 +	role="hg-ext-mq">qpush</command> or <command
  30.785 +	role="hg-ext-mq">qpop</command>, these commands scan the
  30.786 +      working directory once to make sure you haven't made some
  30.787 +      changes and then forgotten to run <command
  30.788 +	role="hg-ext-mq">qrefresh</command>.  On a small tree, the
  30.789 +      time that this scan takes is unnoticeable.  However, on a
  30.790 +      medium-sized tree (containing tens of thousands of files), it
  30.791 +      can take a second or more.</para>
  30.792 +
  30.793 +    <para>The <command role="hg-ext-mq">qpush</command> and <command
  30.794 +	role="hg-ext-mq">qpop</command> commands allow you to push and
  30.795 +      pop multiple patches at a time.  You can identify the
  30.796 +      <quote>destination patch</quote> that you want to end up at.
  30.797 +      When you <command role="hg-ext-mq">qpush</command> with a
  30.798 +      destination specified, it will push patches until that patch is
  30.799 +      at the top of the applied stack.  When you <command
  30.800 +	role="hg-ext-mq">qpop</command> to a destination, MQ will pop
  30.801 +      patches until the destination patch is at the top.</para>
  30.802 +
  30.803 +    <para>You can identify a destination patch using either the name
  30.804 +      of the patch, or by number.  If you use numeric addressing,
  30.805 +      patches are counted from zero; this means that the first patch
  30.806 +      is zero, the second is one, and so on.</para>
  30.807 +
  30.808 +  </sect1>
  30.809 +  <sect1 id="sec.mq.merge">
  30.810 +    <title>Updating your patches when the underlying code
  30.811 +      changes</title>
  30.812 +
  30.813 +    <para>It's common to have a stack of patches on top of an
  30.814 +      underlying repository that you don't modify directly.  If you're
  30.815 +      working on changes to third-party code, or on a feature that is
  30.816 +      taking longer to develop than the rate of change of the code
  30.817 +      beneath, you will often need to sync up with the underlying
  30.818 +      code, and fix up any hunks in your patches that no longer apply.
  30.819 +      This is called <emphasis>rebasing</emphasis> your patch
  30.820 +      series.</para>
  30.821 +
  30.822 +    <para>The simplest way to do this is to <command role="hg-cmd">hg
  30.823 +	qpop <option role="hg-ext-mq-cmd-qpop-opt">hg
  30.824 +	  -a</option></command> your patches, then <command
  30.825 +	role="hg-cmd">hg pull</command> changes into the underlying
  30.826 +      repository, and finally <command role="hg-cmd">hg qpush <option
  30.827 +	  role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> your
  30.828 +      patches again.  MQ will stop pushing any time it runs across a
  30.829 +      patch that fails to apply during conflicts, allowing you to fix
  30.830 +      your conflicts, <command role="hg-ext-mq">qrefresh</command> the
  30.831 +      affected patch, and continue pushing until you have fixed your
  30.832 +      entire stack.</para>
  30.833 +
  30.834 +    <para>This approach is easy to use and works well if you don't
  30.835 +      expect changes to the underlying code to affect how well your
  30.836 +      patches apply. If your patch stack touches code that is modified
  30.837 +      frequently or invasively in the underlying repository, however,
  30.838 +      fixing up rejected hunks by hand quickly becomes
  30.839 +      tiresome.</para>
  30.840 +
  30.841 +    <para>It's possible to partially automate the rebasing process.
  30.842 +      If your patches apply cleanly against some revision of the
  30.843 +      underlying repo, MQ can use this information to help you to
  30.844 +      resolve conflicts between your patches and a different
  30.845 +      revision.</para>
  30.846 +
  30.847 +    <para>The process is a little involved.</para>
  30.848 +    <orderedlist>
  30.849 +      <listitem><para>To begin, <command role="hg-cmd">hg qpush
  30.850 +	    -a</command> all of your patches on top of the revision
  30.851 +	  where you know that they apply cleanly.</para>
  30.852 +      </listitem>
  30.853 +      <listitem><para>Save a backup copy of your patch directory using
  30.854 +	  <command role="hg-cmd">hg qsave <option
  30.855 +	      role="hg-ext-mq-cmd-qsave-opt">hg -e</option> <option
  30.856 +	      role="hg-ext-mq-cmd-qsave-opt">hg -c</option></command>.
  30.857 +	  This prints the name of the directory that it has saved the
  30.858 +	  patches in.  It will save the patches to a directory called
  30.859 +	  <filename role="special"
  30.860 +	    class="directory">.hg/patches.N</filename>, where
  30.861 +	  <literal>N</literal> is a small integer.  It also commits a
  30.862 +	  <quote>save changeset</quote> on top of your applied
  30.863 +	  patches; this is for internal book-keeping, and records the
  30.864 +	  states of the <filename role="special">series</filename> and
  30.865 +	  <filename role="special">status</filename> files.</para>
  30.866 +      </listitem>
  30.867 +      <listitem><para>Use <command role="hg-cmd">hg pull</command> to
  30.868 +	  bring new changes into the underlying repository.  (Don't
  30.869 +	  run <command role="hg-cmd">hg pull -u</command>; see below
  30.870 +	  for why.)</para>
  30.871 +      </listitem>
  30.872 +      <listitem><para>Update to the new tip revision, using <command
  30.873 +	    role="hg-cmd">hg update <option
  30.874 +	      role="hg-opt-update">-C</option></command> to override
  30.875 +	  the patches you have pushed.</para>
  30.876 +      </listitem>
  30.877 +      <listitem><para>Merge all patches using <command>hg qpush -m
  30.878 +	    -a</command>.  The <option
  30.879 +	    role="hg-ext-mq-cmd-qpush-opt">-m</option> option to
  30.880 +	  <command role="hg-ext-mq">qpush</command> tells MQ to
  30.881 +	  perform a three-way merge if the patch fails to
  30.882 +	  apply.</para>
  30.883 +      </listitem></orderedlist>
  30.884 +
  30.885 +    <para>During the <command role="hg-cmd">hg qpush <option
  30.886 +	  role="hg-ext-mq-cmd-qpush-opt">hg -m</option></command>,
  30.887 +      each patch in the <filename role="special">series</filename>
  30.888 +      file is applied normally.  If a patch applies with fuzz or
  30.889 +      rejects, MQ looks at the queue you <command
  30.890 +	role="hg-ext-mq">qsave</command>d, and performs a three-way
  30.891 +      merge with the corresponding changeset.  This merge uses
  30.892 +      Mercurial's normal merge machinery, so it may pop up a GUI merge
  30.893 +      tool to help you to resolve problems.</para>
  30.894 +
  30.895 +    <para>When you finish resolving the effects of a patch, MQ
  30.896 +      refreshes your patch based on the result of the merge.</para>
  30.897 +
  30.898 +    <para>At the end of this process, your repository will have one
  30.899 +      extra head from the old patch queue, and a copy of the old patch
  30.900 +      queue will be in <filename role="special"
  30.901 +	class="directory">.hg/patches.N</filename>. You can remove the
  30.902 +      extra head using <command role="hg-cmd">hg qpop -a -n
  30.903 +	patches.N</command> or <command role="hg-cmd">hg
  30.904 +	strip</command>.  You can delete <filename role="special"
  30.905 +	class="directory">.hg/patches.N</filename> once you are sure
  30.906 +      that you no longer need it as a backup.</para>
  30.907 +
  30.908 +  </sect1>
  30.909 +  <sect1>
  30.910 +    <title>Identifying patches</title>
  30.911 +
  30.912 +    <para>MQ commands that work with patches let you refer to a patch
  30.913 +      either by using its name or by a number.  By name is obvious
  30.914 +      enough; pass the name <filename>foo.patch</filename> to <command
  30.915 +	role="hg-ext-mq">qpush</command>, for example, and it will
  30.916 +      push patches until <filename>foo.patch</filename> is
  30.917 +      applied.</para>
  30.918 +
  30.919 +    <para>As a shortcut, you can refer to a patch using both a name
  30.920 +      and a numeric offset; <literal>foo.patch-2</literal> means
  30.921 +      <quote>two patches before <literal>foo.patch</literal></quote>,
  30.922 +      while <literal>bar.patch+4</literal> means <quote>four patches
  30.923 +	after <literal>bar.patch</literal></quote>.</para>
  30.924 +
  30.925 +    <para>Referring to a patch by index isn't much different.  The
  30.926 +      first patch printed in the output of <command
  30.927 +	role="hg-ext-mq">qseries</command> is patch zero (yes, it's
  30.928 +      one of those start-at-zero counting systems); the second is
  30.929 +      patch one; and so on.</para>
  30.930 +
  30.931 +    <para>MQ also makes it easy to work with patches when you are
  30.932 +      using normal Mercurial commands.  Every command that accepts a
  30.933 +      changeset ID will also accept the name of an applied patch.  MQ
  30.934 +      augments the tags normally in the repository with an eponymous
  30.935 +      one for each applied patch.  In addition, the special tags
  30.936 +      <literal role="tag">qbase</literal> and
  30.937 +      <literal role="tag">qtip</literal> identify
  30.938 +      the <quote>bottom-most</quote> and topmost applied patches,
  30.939 +      respectively.</para>
  30.940 +
  30.941 +    <para>These additions to Mercurial's normal tagging capabilities
  30.942 +      make dealing with patches even more of a breeze.</para>
  30.943 +    <itemizedlist>
  30.944 +      <listitem><para>Want to patchbomb a mailing list with your
  30.945 +	  latest series of changes?</para>
  30.946 +	<programlisting>hg email qbase:qtip</programlisting>
  30.947 +	<para>  (Don't know what <quote>patchbombing</quote> is?  See
  30.948 +	  section <xref linkend="sec.hgext.patchbomb"/>.)</para>
  30.949 +      </listitem>
  30.950 +      <listitem><para>Need to see all of the patches since
  30.951 +	  <literal>foo.patch</literal> that have touched files in a
  30.952 +	  subdirectory of your tree?</para>
  30.953 +	<programlisting>hg log -r foo.patch:qtip subdir</programlisting>
  30.954 +      </listitem>
  30.955 +    </itemizedlist>
  30.956 +
  30.957 +    <para>Because MQ makes the names of patches available to the rest
  30.958 +      of Mercurial through its normal internal tag machinery, you
  30.959 +      don't need to type in the entire name of a patch when you want
  30.960 +      to identify it by name.</para>
  30.961 +
  30.962 +    <para>Another nice consequence of representing patch names as tags
  30.963 +      is that when you run the <command role="hg-cmd">hg log</command>
  30.964 +      command, it will display a patch's name as a tag, simply as part
  30.965 +      of its normal output.  This makes it easy to visually
  30.966 +      distinguish applied patches from underlying
  30.967 +      <quote>normal</quote> revisions.  The following example shows a
  30.968 +      few normal Mercurial commands in use with applied
  30.969 +      patches.</para>
  30.970 +
  30.971 +&interaction.mq.id.output;
  30.972 +
  30.973 +  </sect1>
  30.974 +  <sect1>
  30.975 +    <title>Useful things to know about</title>
  30.976 +
  30.977 +    <para>There are a number of aspects of MQ usage that don't fit
  30.978 +      tidily into sections of their own, but that are good to know.
  30.979 +      Here they are, in one place.</para>
  30.980 +
  30.981 +    <itemizedlist>
  30.982 +      <listitem><para>Normally, when you <command
  30.983 +	    role="hg-ext-mq">qpop</command> a patch and <command
  30.984 +	    role="hg-ext-mq">qpush</command> it again, the changeset
  30.985 +	  that represents the patch after the pop/push will have a
  30.986 +	  <emphasis>different identity</emphasis> than the changeset
  30.987 +	  that represented the hash beforehand.  See section <xref
  30.988 +	    linkend="sec.mqref.cmd.qpush"/> for
  30.989 +	  information as to why this is.</para>
  30.990 +      </listitem>
  30.991 +      <listitem><para>It's not a good idea to <command
  30.992 +	    role="hg-cmd">hg merge</command> changes from another
  30.993 +	  branch with a patch changeset, at least if you want to
  30.994 +	  maintain the <quote>patchiness</quote> of that changeset and
  30.995 +	  changesets below it on the patch stack.  If you try to do
  30.996 +	  this, it will appear to succeed, but MQ will become
  30.997 +	  confused.</para>
  30.998 +      </listitem></itemizedlist>
  30.999 +
 30.1000 +  </sect1>
 30.1001 +  <sect1 id="sec.mq.repo">
 30.1002 +    <title>Managing patches in a repository</title>
 30.1003 +
 30.1004 +    <para>Because MQ's <filename role="special"
 30.1005 +	class="directory">.hg/patches</filename> directory resides
 30.1006 +      outside a Mercurial repository's working directory, the
 30.1007 +      <quote>underlying</quote> Mercurial repository knows nothing
 30.1008 +      about the management or presence of patches.</para>
 30.1009 +
 30.1010 +    <para>This presents the interesting possibility of managing the
 30.1011 +      contents of the patch directory as a Mercurial repository in its
 30.1012 +      own right.  This can be a useful way to work.  For example, you
 30.1013 +      can work on a patch for a while, <command
 30.1014 +	role="hg-ext-mq">qrefresh</command> it, then <command
 30.1015 +	role="hg-cmd">hg commit</command> the current state of the
 30.1016 +      patch.  This lets you <quote>roll back</quote> to that version
 30.1017 +      of the patch later on.</para>
 30.1018 +
 30.1019 +    <para>You can then share different versions of the same patch
 30.1020 +      stack among multiple underlying repositories.  I use this when I
 30.1021 +      am developing a Linux kernel feature.  I have a pristine copy of
 30.1022 +      my kernel sources for each of several CPU architectures, and a
 30.1023 +      cloned repository under each that contains the patches I am
 30.1024 +      working on.  When I want to test a change on a different
 30.1025 +      architecture, I push my current patches to the patch repository
 30.1026 +      associated with that kernel tree, pop and push all of my
 30.1027 +      patches, and build and test that kernel.</para>
 30.1028 +
 30.1029 +    <para>Managing patches in a repository makes it possible for
 30.1030 +      multiple developers to work on the same patch series without
 30.1031 +      colliding with each other, all on top of an underlying source
 30.1032 +      base that they may or may not control.</para>
 30.1033 +
 30.1034 +    <sect2>
 30.1035 +      <title>MQ support for patch repositories</title>
 30.1036 +
 30.1037 +      <para>MQ helps you to work with the <filename role="special"
 30.1038 +	  class="directory">.hg/patches</filename> directory as a
 30.1039 +	repository; when you prepare a repository for working with
 30.1040 +	patches using <command role="hg-ext-mq">qinit</command>, you
 30.1041 +	can pass the <option role="hg-ext-mq-cmd-qinit-opt">hg
 30.1042 +	  -c</option> option to create the <filename role="special"
 30.1043 +	  class="directory">.hg/patches</filename> directory as a
 30.1044 +	Mercurial repository.</para>
 30.1045 +
 30.1046 +      <note>
 30.1047 +	<para>  If you forget to use the <option
 30.1048 +	    role="hg-ext-mq-cmd-qinit-opt">hg -c</option> option, you
 30.1049 +	  can simply go into the <filename role="special"
 30.1050 +	    class="directory">.hg/patches</filename> directory at any
 30.1051 +	  time and run <command role="hg-cmd">hg init</command>.
 30.1052 +	  Don't forget to add an entry for the <filename
 30.1053 +	    role="special">status</filename> file to the <filename
 30.1054 +	    role="special">.hgignore</filename> file, though</para>
 30.1055 +
 30.1056 +	<para>  (<command role="hg-cmd">hg qinit <option
 30.1057 +	      role="hg-ext-mq-cmd-qinit-opt">hg -c</option></command>
 30.1058 +	  does this for you automatically); you
 30.1059 +	  <emphasis>really</emphasis> don't want to manage the
 30.1060 +	  <filename role="special">status</filename> file.</para>
 30.1061 +      </note>
 30.1062 +
 30.1063 +      <para>As a convenience, if MQ notices that the <filename
 30.1064 +	  class="directory">.hg/patches</filename> directory is a
 30.1065 +	repository, it will automatically <command role="hg-cmd">hg
 30.1066 +	  add</command> every patch that you create and import.</para>
 30.1067 +
 30.1068 +      <para>MQ provides a shortcut command, <command
 30.1069 +	  role="hg-ext-mq">qcommit</command>, that runs <command
 30.1070 +	  role="hg-cmd">hg commit</command> in the <filename
 30.1071 +	  role="special" class="directory">.hg/patches</filename>
 30.1072 +	directory.  This saves some bothersome typing.</para>
 30.1073 +
 30.1074 +      <para>Finally, as a convenience to manage the patch directory,
 30.1075 +	you can define the alias <command>mq</command> on Unix
 30.1076 +	systems. For example, on Linux systems using the
 30.1077 +	<command>bash</command> shell, you can include the following
 30.1078 +	snippet in your <filename
 30.1079 +	  role="home">~/.bashrc</filename>.</para>
 30.1080 +
 30.1081 +      <programlisting>alias mq=`hg -R $(hg root)/.hg/patches'</programlisting>
 30.1082 +
 30.1083 +      <para>You can then issue commands of the form <command>mq
 30.1084 +	  pull</command> from the main repository.</para>
 30.1085 +
 30.1086 +    </sect2>
 30.1087 +    <sect2>
 30.1088 +      <title>A few things to watch out for</title>
 30.1089 +
 30.1090 +      <para>MQ's support for working with a repository full of patches
 30.1091 +	is limited in a few small respects.</para>
 30.1092 +
 30.1093 +      <para>MQ cannot automatically detect changes that you make to
 30.1094 +	the patch directory.  If you <command role="hg-cmd">hg
 30.1095 +	  pull</command>, manually edit, or <command role="hg-cmd">hg
 30.1096 +	  update</command> changes to patches or the <filename
 30.1097 +	  role="special">series</filename> file, you will have to
 30.1098 +	<command role="hg-cmd">hg qpop <option
 30.1099 +	    role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> and
 30.1100 +	then <command role="hg-cmd">hg qpush <option
 30.1101 +	    role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> in
 30.1102 +	the underlying repository to see those changes show up there.
 30.1103 +	If you forget to do this, you can confuse MQ's idea of which
 30.1104 +	patches are applied.</para>
 30.1105 +
 30.1106 +    </sect2>
 30.1107 +  </sect1>
 30.1108 +  <sect1 id="sec.mq.tools">
 30.1109 +    <title>Third party tools for working with patches</title>
 30.1110 +
 30.1111 +    <para>Once you've been working with patches for a while, you'll
 30.1112 +      find yourself hungry for tools that will help you to understand
 30.1113 +      and manipulate the patches you're dealing with.</para>
 30.1114 +
 30.1115 +    <para>The <command>diffstat</command> command
 30.1116 +      <citation>web:diffstat</citation> generates a histogram of the
 30.1117 +      modifications made to each file in a patch.  It provides a good
 30.1118 +      way to <quote>get a sense of</quote> a patch&emdash;which files
 30.1119 +      it affects, and how much change it introduces to each file and
 30.1120 +      as a whole.  (I find that it's a good idea to use
 30.1121 +      <command>diffstat</command>'s <option
 30.1122 +	role="cmd-opt-diffstat">-p</option> option as a matter of
 30.1123 +      course, as otherwise it will try to do clever things with
 30.1124 +      prefixes of file names that inevitably confuse at least
 30.1125 +      me.)</para>
 30.1126 +
 30.1127 +&interaction.mq.tools.tools;
 30.1128 +
 30.1129 +    <para>The <literal role="package">patchutils</literal> package
 30.1130 +      <citation>web:patchutils</citation> is invaluable. It provides a
 30.1131 +      set of small utilities that follow the <quote>Unix
 30.1132 +	philosophy;</quote> each does one useful thing with a patch.
 30.1133 +      The <literal role="package">patchutils</literal> command I use
 30.1134 +      most is <command>filterdiff</command>, which extracts subsets
 30.1135 +      from a patch file.  For example, given a patch that modifies
 30.1136 +      hundreds of files across dozens of directories, a single
 30.1137 +      invocation of <command>filterdiff</command> can generate a
 30.1138 +      smaller patch that only touches files whose names match a
 30.1139 +      particular glob pattern.  See section <xref
 30.1140 +	linkend="mq-collab.tips.interdiff"/> for another
 30.1141 +      example.</para>
 30.1142 +
 30.1143 +  </sect1>
 30.1144 +  <sect1>
 30.1145 +    <title>Good ways to work with patches</title>
 30.1146 +
 30.1147 +    <para>Whether you are working on a patch series to submit to a
 30.1148 +      free software or open source project, or a series that you
 30.1149 +      intend to treat as a sequence of regular changesets when you're
 30.1150 +      done, you can use some simple techniques to keep your work well
 30.1151 +      organised.</para>
 30.1152 +
 30.1153 +    <para>Give your patches descriptive names.  A good name for a
 30.1154 +      patch might be <filename>rework-device-alloc.patch</filename>,
 30.1155 +      because it will immediately give you a hint what the purpose of
 30.1156 +      the patch is.  Long names shouldn't be a problem; you won't be
 30.1157 +      typing the names often, but you <emphasis>will</emphasis> be
 30.1158 +      running commands like <command
 30.1159 +	role="hg-ext-mq">qapplied</command> and <command
 30.1160 +	role="hg-ext-mq">qtop</command> over and over. Good naming
 30.1161 +      becomes especially important when you have a number of patches
 30.1162 +      to work with, or if you are juggling a number of different tasks
 30.1163 +      and your patches only get a fraction of your attention.</para>
 30.1164 +
 30.1165 +    <para>Be aware of what patch you're working on.  Use the <command
 30.1166 +	role="hg-ext-mq">qtop</command> command and skim over the text
 30.1167 +      of your patches frequently&emdash;for example, using <command
 30.1168 +	role="hg-cmd">hg tip <option
 30.1169 +	  role="hg-opt-tip">-p</option></command>)&emdash;to be sure
 30.1170 +      of where you stand.  I have several times worked on and <command
 30.1171 +	role="hg-ext-mq">qrefresh</command>ed a patch other than the
 30.1172 +      one I intended, and it's often tricky to migrate changes into
 30.1173 +      the right patch after making them in the wrong one.</para>
 30.1174 +
 30.1175 +    <para>For this reason, it is very much worth investing a little
 30.1176 +      time to learn how to use some of the third-party tools I
 30.1177 +      described in section <xref linkend="sec.mq.tools"/>,
 30.1178 +      particularly
 30.1179 +      <command>diffstat</command> and <command>filterdiff</command>.
 30.1180 +      The former will give you a quick idea of what changes your patch
 30.1181 +      is making, while the latter makes it easy to splice hunks
 30.1182 +      selectively out of one patch and into another.</para>
 30.1183 +
 30.1184 +  </sect1>
 30.1185 +  <sect1>
 30.1186 +    <title>MQ cookbook</title>
 30.1187 +
 30.1188 +    <sect2>
 30.1189 +      <title>Manage <quote>trivial</quote> patches</title>
 30.1190 +
 30.1191 +      <para>Because the overhead of dropping files into a new
 30.1192 +	Mercurial repository is so low, it makes a lot of sense to
 30.1193 +	manage patches this way even if you simply want to make a few
 30.1194 +	changes to a source tarball that you downloaded.</para>
 30.1195 +
 30.1196 +      <para>Begin by downloading and unpacking the source tarball, and
 30.1197 +	turning it into a Mercurial repository.</para>
 30.1198 +
 30.1199 +      &interaction.mq.tarball.download;
 30.1200 +
 30.1201 +      <para>Continue by creating a patch stack and making your
 30.1202 +	changes.</para>
 30.1203 +
 30.1204 +      &interaction.mq.tarball.qinit;
 30.1205 +
 30.1206 +      <para>Let's say a few weeks or months pass, and your package
 30.1207 +	author releases a new version.  First, bring their changes
 30.1208 +	into the repository.</para>
 30.1209 +
 30.1210 +      &interaction.mq.tarball.newsource;
 30.1211 +
 30.1212 +      <para>The pipeline starting with <command role="hg-cmd">hg
 30.1213 +	  locate</command> above deletes all files in the working
 30.1214 +	directory, so that <command role="hg-cmd">hg
 30.1215 +	  commit</command>'s <option
 30.1216 +	  role="hg-opt-commit">--addremove</option> option can
 30.1217 +	actually tell which files have really been removed in the
 30.1218 +	newer version of the source.</para>
 30.1219 +
 30.1220 +      <para>Finally, you can apply your patches on top of the new
 30.1221 +	tree.</para>
 30.1222 +
 30.1223 +      &interaction.mq.tarball.repush;
 30.1224 +
 30.1225 +    </sect2>
 30.1226 +    <sect2 id="sec.mq.combine">
 30.1227 +      <title>Combining entire patches</title>
 30.1228 +
 30.1229 +      <para>MQ provides a command, <command
 30.1230 +	  role="hg-ext-mq">qfold</command> that lets you combine
 30.1231 +	entire patches.  This <quote>folds</quote> the patches you
 30.1232 +	name, in the order you name them, into the topmost applied
 30.1233 +	patch, and concatenates their descriptions onto the end of its
 30.1234 +	description.  The patches that you fold must be unapplied
 30.1235 +	before you fold them.</para>
 30.1236 +
 30.1237 +      <para>The order in which you fold patches matters.  If your
 30.1238 +	topmost applied patch is <literal>foo</literal>, and you
 30.1239 +	<command role="hg-ext-mq">qfold</command>
 30.1240 +	<literal>bar</literal> and <literal>quux</literal> into it,
 30.1241 +	you will end up with a patch that has the same effect as if
 30.1242 +	you applied first <literal>foo</literal>, then
 30.1243 +	<literal>bar</literal>, followed by
 30.1244 +	<literal>quux</literal>.</para>
 30.1245 +
 30.1246 +    </sect2>
 30.1247 +    <sect2>
 30.1248 +      <title>Merging part of one patch into another</title>
 30.1249 +
 30.1250 +      <para>Merging <emphasis>part</emphasis> of one patch into
 30.1251 +	another is more difficult than combining entire
 30.1252 +	patches.</para>
 30.1253 +
 30.1254 +      <para>If you want to move changes to entire files, you can use
 30.1255 +	<command>filterdiff</command>'s <option
 30.1256 +	  role="cmd-opt-filterdiff">-i</option> and <option
 30.1257 +	  role="cmd-opt-filterdiff">-x</option> options to choose the
 30.1258 +	modifications to snip out of one patch, concatenating its
 30.1259 +	output onto the end of the patch you want to merge into.  You
 30.1260 +	usually won't need to modify the patch you've merged the
 30.1261 +	changes from.  Instead, MQ will report some rejected hunks
 30.1262 +	when you <command role="hg-ext-mq">qpush</command> it (from
 30.1263 +	the hunks you moved into the other patch), and you can simply
 30.1264 +	<command role="hg-ext-mq">qrefresh</command> the patch to drop
 30.1265 +	the duplicate hunks.</para>
 30.1266 +
 30.1267 +      <para>If you have a patch that has multiple hunks modifying a
 30.1268 +	file, and you only want to move a few of those hunks, the job
 30.1269 +	becomes more messy, but you can still partly automate it.  Use
 30.1270 +	<command>lsdiff -nvv</command> to print some metadata about
 30.1271 +	the patch.</para>
 30.1272 +
 30.1273 +      &interaction.mq.tools.lsdiff;
 30.1274 +
 30.1275 +      <para>This command prints three different kinds of
 30.1276 +	number:</para>
 30.1277 +      <itemizedlist>
 30.1278 +	<listitem><para>(in the first column) a <emphasis>file
 30.1279 +	      number</emphasis> to identify each file modified in the
 30.1280 +	    patch;</para>
 30.1281 +	</listitem>
 30.1282 +	<listitem><para>(on the next line, indented) the line number
 30.1283 +	    within a modified file where a hunk starts; and</para>
 30.1284 +	</listitem>
 30.1285 +	<listitem><para>(on the same line) a <emphasis>hunk
 30.1286 +	      number</emphasis> to identify that hunk.</para>
 30.1287 +	</listitem></itemizedlist>
 30.1288 +
 30.1289 +      <para>You'll have to use some visual inspection, and reading of
 30.1290 +	the patch, to identify the file and hunk numbers you'll want,
 30.1291 +	but you can then pass them to to
 30.1292 +	<command>filterdiff</command>'s <option
 30.1293 +	  role="cmd-opt-filterdiff">--files</option> and <option
 30.1294 +	  role="cmd-opt-filterdiff">--hunks</option> options, to
 30.1295 +	select exactly the file and hunk you want to extract.</para>
 30.1296 +
 30.1297 +      <para>Once you have this hunk, you can concatenate it onto the
 30.1298 +	end of your destination patch and continue with the remainder
 30.1299 +	of section <xref linkend="sec.mq.combine"/>.</para>
 30.1300 +
 30.1301 +    </sect2>
 30.1302 +  </sect1>
 30.1303 +  <sect1>
 30.1304 +    <title>Differences between quilt and MQ</title>
 30.1305 +
 30.1306 +    <para>If you are already familiar with quilt, MQ provides a
 30.1307 +      similar command set.  There are a few differences in the way
 30.1308 +      that it works.</para>
 30.1309 +
 30.1310 +    <para>You will already have noticed that most quilt commands have
 30.1311 +      MQ counterparts that simply begin with a
 30.1312 +      <quote><literal>q</literal></quote>.  The exceptions are quilt's
 30.1313 +      <literal>add</literal> and <literal>remove</literal> commands,
 30.1314 +      the counterparts for which are the normal Mercurial <command
 30.1315 +	role="hg-cmd">hg add</command> and <command role="hg-cmd">hg
 30.1316 +	remove</command> commands.  There is no MQ equivalent of the
 30.1317 +      quilt <literal>edit</literal> command.</para>
 30.1318 +
 30.1319 +  </sect1>
 30.1320 +</chapter>
 30.1321 +
 30.1322 +<!--
 30.1323 +local variables: 
 30.1324 +sgml-parent-document: ("00book.xml" "book" "chapter")
 30.1325 +end:
 30.1326 +-->
    31.1 --- a/en/ch11-template.xml	Fri Mar 20 15:40:06 2009 +0800
    31.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.3 @@ -1,675 +0,0 @@
    31.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    31.5 -
    31.6 -<chapter id="chap.template">
    31.7 -  <?dbhtml filename="customizing-the-output-of-mercurial.html"?>
    31.8 -  <title>Customising the output of Mercurial</title>
    31.9 -
   31.10 -  <para>Mercurial provides a powerful mechanism to let you control how
   31.11 -    it displays information.  The mechanism is based on templates.
   31.12 -    You can use templates to generate specific output for a single
   31.13 -    command, or to customise the entire appearance of the built-in web
   31.14 -    interface.</para>
   31.15 -
   31.16 -  <sect1 id="sec.style">
   31.17 -    <title>Using precanned output styles</title>
   31.18 -
   31.19 -    <para>Packaged with Mercurial are some output styles that you can
   31.20 -      use immediately.  A style is simply a precanned template that
   31.21 -      someone wrote and installed somewhere that Mercurial can
   31.22 -      find.</para>
   31.23 -
   31.24 -    <para>Before we take a look at Mercurial's bundled styles, let's
   31.25 -      review its normal output.</para>
   31.26 -
   31.27 -    &interaction.template.simple.normal;
   31.28 -
   31.29 -    <para>This is somewhat informative, but it takes up a lot of
   31.30 -      space&emdash;five lines of output per changeset.  The
   31.31 -      <literal>compact</literal> style reduces this to three lines,
   31.32 -      presented in a sparse manner.</para>
   31.33 -
   31.34 -    &interaction.template.simple.compact;
   31.35 -
   31.36 -    <para>The <literal>changelog</literal> style hints at the
   31.37 -      expressive power of Mercurial's templating engine.  This style
   31.38 -      attempts to follow the GNU Project's changelog
   31.39 -      guidelines<citation>web:changelog</citation>.</para>
   31.40 -
   31.41 -    &interaction.template.simple.changelog;
   31.42 -
   31.43 -    <para>You will not be shocked to learn that Mercurial's default
   31.44 -      output style is named <literal>default</literal>.</para>
   31.45 -
   31.46 -    <sect2>
   31.47 -      <title>Setting a default style</title>
   31.48 -
   31.49 -      <para>You can modify the output style that Mercurial will use
   31.50 -	for every command by editing your <filename
   31.51 -	  role="special">~/.hgrc</filename> file, naming the style
   31.52 -	you would prefer to use.</para>
   31.53 -
   31.54 -      <programlisting>[ui]
   31.55 -style = compact</programlisting>
   31.56 -
   31.57 -      <para>If you write a style of your own, you can use it by either
   31.58 -	providing the path to your style file, or copying your style
   31.59 -	file into a location where Mercurial can find it (typically
   31.60 -	the <literal>templates</literal> subdirectory of your
   31.61 -	Mercurial install directory).</para>
   31.62 -
   31.63 -    </sect2>
   31.64 -  </sect1>
   31.65 -  <sect1>
   31.66 -    <title>Commands that support styles and templates</title>
   31.67 -
   31.68 -    <para>All of Mercurial's
   31.69 -      <quote><literal>log</literal>-like</quote> commands let you use
   31.70 -      styles and templates: <command role="hg-cmd">hg
   31.71 -	incoming</command>, <command role="hg-cmd">hg log</command>,
   31.72 -      <command role="hg-cmd">hg outgoing</command>, and <command
   31.73 -	role="hg-cmd">hg tip</command>.</para>
   31.74 -
   31.75 -    <para>As I write this manual, these are so far the only commands
   31.76 -      that support styles and templates.  Since these are the most
   31.77 -      important commands that need customisable output, there has been
   31.78 -      little pressure from the Mercurial user community to add style
   31.79 -      and template support to other commands.</para>
   31.80 -
   31.81 -  </sect1>
   31.82 -  <sect1>
   31.83 -    <title>The basics of templating</title>
   31.84 -
   31.85 -    <para>At its simplest, a Mercurial template is a piece of text.
   31.86 -      Some of the text never changes, while other parts are
   31.87 -      <emphasis>expanded</emphasis>, or replaced with new text, when
   31.88 -      necessary.</para>
   31.89 -
   31.90 -    <para>Before we continue, let's look again at a simple example of
   31.91 -      Mercurial's normal output.</para>
   31.92 -
   31.93 -    &interaction.template.simple.normal;
   31.94 -
   31.95 -    <para>Now, let's run the same command, but using a template to
   31.96 -      change its output.</para>
   31.97 -
   31.98 -    &interaction.template.simple.simplest;
   31.99 -
  31.100 -    <para>The example above illustrates the simplest possible
  31.101 -      template; it's just a piece of static text, printed once for
  31.102 -      each changeset.  The <option
  31.103 -	role="hg-opt-log">--template</option> option to the <command
  31.104 -	role="hg-cmd">hg log</command> command tells Mercurial to use
  31.105 -      the given text as the template when printing each
  31.106 -      changeset.</para>
  31.107 -
  31.108 -    <para>Notice that the template string above ends with the text
  31.109 -      <quote><literal>\n</literal></quote>.  This is an
  31.110 -      <emphasis>escape sequence</emphasis>, telling Mercurial to print
  31.111 -      a newline at the end of each template item.  If you omit this
  31.112 -      newline, Mercurial will run each piece of output together.  See
  31.113 -      section <xref linkend="sec.template.escape"/> for more details
  31.114 -      of escape sequences.</para>
  31.115 -
  31.116 -    <para>A template that prints a fixed string of text all the time
  31.117 -      isn't very useful; let's try something a bit more
  31.118 -      complex.</para>
  31.119 -
  31.120 -    &interaction.template.simple.simplesub;
  31.121 -
  31.122 -    <para>As you can see, the string
  31.123 -      <quote><literal>{desc}</literal></quote> in the template has
  31.124 -      been replaced in the output with the description of each
  31.125 -      changeset.  Every time Mercurial finds text enclosed in curly
  31.126 -      braces (<quote><literal>{</literal></quote> and
  31.127 -      <quote><literal>}</literal></quote>), it will try to replace the braces
  31.128 -      and text with the expansion of whatever is inside.  To print a
  31.129 -      literal curly brace, you must escape it, as described in section
  31.130 -      <xref
  31.131 -	linkend="sec.template.escape"/>.</para>
  31.132 -
  31.133 -  </sect1>
  31.134 -  <sect1 id="sec.template.keyword">
  31.135 -    <title>Common template keywords</title>
  31.136 -
  31.137 -    <para>You can start writing simple templates immediately using the
  31.138 -      keywords below.</para>
  31.139 -
  31.140 -    <itemizedlist>
  31.141 -      <listitem><para><literal
  31.142 -	    role="template-keyword">author</literal>: String.  The
  31.143 -	  unmodified author of the changeset.</para>
  31.144 -      </listitem>
  31.145 -      <listitem><para><literal
  31.146 -	    role="template-keyword">branches</literal>: String.  The
  31.147 -	  name of the branch on which the changeset was committed.
  31.148 -	  Will be empty if the branch name was
  31.149 -	  <literal>default</literal>.</para>
  31.150 -      </listitem>
  31.151 -      <listitem><para><literal role="template-keyword">date</literal>:
  31.152 -	  Date information.  The date when the changeset was
  31.153 -	  committed.  This is <emphasis>not</emphasis> human-readable;
  31.154 -	  you must pass it through a filter that will render it
  31.155 -	  appropriately.  See section <xref
  31.156 -	    linkend="sec.template.filter"/> for more information
  31.157 -	  on filters. The date is expressed as a pair of numbers.  The
  31.158 -	  first number is a Unix UTC timestamp (seconds since January
  31.159 -	  1, 1970); the second is the offset of the committer's
  31.160 -	  timezone from UTC, in seconds.</para>
  31.161 -      </listitem>
  31.162 -      <listitem><para><literal role="template-keyword">desc</literal>:
  31.163 -	  String.  The text of the changeset description.</para>
  31.164 -      </listitem>
  31.165 -      <listitem><para><literal
  31.166 -	    role="template-keyword">files</literal>: List of strings.
  31.167 -	  All files modified, added, or removed by this
  31.168 -	  changeset.</para>
  31.169 -      </listitem>
  31.170 -      <listitem><para><literal
  31.171 -	    role="template-keyword">file_adds</literal>: List of
  31.172 -	  strings.  Files added by this changeset.</para>
  31.173 -      </listitem>
  31.174 -      <listitem><para><literal
  31.175 -	    role="template-keyword">file_dels</literal>: List of
  31.176 -	  strings.  Files removed by this changeset.</para>
  31.177 -      </listitem>
  31.178 -      <listitem><para><literal role="template-keyword">node</literal>:
  31.179 -	  String.  The changeset identification hash, as a
  31.180 -	  40-character hexadecimal string.</para>
  31.181 -      </listitem>
  31.182 -      <listitem><para><literal
  31.183 -	    role="template-keyword">parents</literal>: List of
  31.184 -	  strings.  The parents of the changeset.</para>
  31.185 -      </listitem>
  31.186 -      <listitem><para><literal role="template-keyword">rev</literal>:
  31.187 -	  Integer.  The repository-local changeset revision
  31.188 -	  number.</para>
  31.189 -      </listitem>
  31.190 -      <listitem><para><literal role="template-keyword">tags</literal>:
  31.191 -	  List of strings.  Any tags associated with the
  31.192 -	  changeset.</para>
  31.193 -      </listitem></itemizedlist>
  31.194 -
  31.195 -    <para>A few simple experiments will show us what to expect when we
  31.196 -      use these keywords; you can see the results below.</para>
  31.197 -
  31.198 -&interaction.template.simple.keywords;
  31.199 -
  31.200 -    <para>As we noted above, the date keyword does not produce
  31.201 -      human-readable output, so we must treat it specially.  This
  31.202 -      involves using a <emphasis>filter</emphasis>, about which more
  31.203 -      in section <xref
  31.204 -	linkend="sec.template.filter"/>.</para>
  31.205 -
  31.206 -    &interaction.template.simple.datekeyword;
  31.207 -
  31.208 -  </sect1>
  31.209 -  <sect1 id="sec.template.escape">
  31.210 -    <title>Escape sequences</title>
  31.211 -
  31.212 -    <para>Mercurial's templating engine recognises the most commonly
  31.213 -      used escape sequences in strings.  When it sees a backslash
  31.214 -      (<quote><literal>\</literal></quote>) character, it looks at the
  31.215 -      following character and substitutes the two characters with a
  31.216 -      single replacement, as described below.</para>
  31.217 -
  31.218 -    <itemizedlist>
  31.219 -      <listitem><para><literal>\</literal>:
  31.220 -	  Backslash, <quote><literal>\</literal></quote>, ASCII
  31.221 -	  134.</para>
  31.222 -      </listitem>
  31.223 -      <listitem><para><literal>\n</literal>: Newline,
  31.224 -	  ASCII 12.</para>
  31.225 -      </listitem>
  31.226 -      <listitem><para><literal>\r</literal>: Carriage
  31.227 -	  return, ASCII 15.</para>
  31.228 -      </listitem>
  31.229 -      <listitem><para><literal>\t</literal>: Tab, ASCII
  31.230 -	  11.</para>
  31.231 -      </listitem>
  31.232 -      <listitem><para><literal>\v</literal>: Vertical
  31.233 -	  tab, ASCII 13.</para>
  31.234 -      </listitem>
  31.235 -      <listitem><para><literal>{</literal>: Open curly
  31.236 -	  brace, <quote><literal>{</literal></quote>, ASCII
  31.237 -	  173.</para>
  31.238 -      </listitem>
  31.239 -      <listitem><para><literal>}</literal>: Close curly
  31.240 -	  brace, <quote><literal>}</literal></quote>, ASCII
  31.241 -	  175.</para>
  31.242 -      </listitem></itemizedlist>
  31.243 -
  31.244 -    <para>As indicated above, if you want the expansion of a template
  31.245 -      to contain a literal <quote><literal>\</literal></quote>,
  31.246 -      <quote><literal>{</literal></quote>, or
  31.247 -      <quote><literal>{</literal></quote> character, you must escape
  31.248 -      it.</para>
  31.249 -
  31.250 -  </sect1>
  31.251 -  <sect1 id="sec.template.filter">
  31.252 -    <title>Filtering keywords to change their results</title>
  31.253 -
  31.254 -    <para>Some of the results of template expansion are not
  31.255 -      immediately easy to use.  Mercurial lets you specify an optional
  31.256 -      chain of <emphasis>filters</emphasis> to modify the result of
  31.257 -      expanding a keyword.  You have already seen a common filter,
  31.258 -      <literal role="template-kw-filt-date">isodate</literal>, in
  31.259 -      action above, to make a date readable.</para>
  31.260 -
  31.261 -    <para>Below is a list of the most commonly used filters that
  31.262 -      Mercurial supports.  While some filters can be applied to any
  31.263 -      text, others can only be used in specific circumstances.  The
  31.264 -      name of each filter is followed first by an indication of where
  31.265 -      it can be used, then a description of its effect.</para>
  31.266 -
  31.267 -    <itemizedlist>
  31.268 -      <listitem><para><literal
  31.269 -	    role="template-filter">addbreaks</literal>: Any text. Add
  31.270 -	  an XHTML <quote><literal>&lt;br/&gt;</literal></quote> tag
  31.271 -	  before the end of every line except the last.  For example,
  31.272 -	  <quote><literal>foo\nbar</literal></quote> becomes
  31.273 -	  <quote><literal>foo&lt;br/&gt;\nbar</literal></quote>.</para>
  31.274 -      </listitem>
  31.275 -      <listitem><para><literal
  31.276 -	    role="template-kw-filt-date">age</literal>: <literal
  31.277 -	    role="template-keyword">date</literal> keyword.  Render
  31.278 -	  the age of the date, relative to the current time.  Yields a
  31.279 -	  string like <quote><literal>10
  31.280 -	      minutes</literal></quote>.</para>
  31.281 -      </listitem>
  31.282 -      <listitem><para><literal
  31.283 -	    role="template-filter">basename</literal>: Any text, but
  31.284 -	  most useful for the <literal
  31.285 -	    role="template-keyword">files</literal> keyword and its
  31.286 -	  relatives.  Treat the text as a path, and return the
  31.287 -	  basename. For example,
  31.288 -	  <quote><literal>foo/bar/baz</literal></quote> becomes
  31.289 -	  <quote><literal>baz</literal></quote>.</para>
  31.290 -      </listitem>
  31.291 -      <listitem><para><literal
  31.292 -	    role="template-kw-filt-date">date</literal>: <literal
  31.293 -	    role="template-keyword">date</literal> keyword.  Render a
  31.294 -	  date in a similar format to the Unix <literal
  31.295 -	    role="template-keyword">date</literal> command, but with
  31.296 -	  timezone included.  Yields a string like <quote><literal>Mon
  31.297 -	      Sep 04 15:13:13 2006 -0700</literal></quote>.</para>
  31.298 -      </listitem>
  31.299 -      <listitem><para><literal
  31.300 -	    role="template-kw-filt-author">domain</literal>: Any text,
  31.301 -	  but most useful for the <literal
  31.302 -	    role="template-keyword">author</literal> keyword.  Finds
  31.303 -	  the first string that looks like an email address, and
  31.304 -	  extract just the domain component.  For example,
  31.305 -	  <quote><literal>Bryan O'Sullivan
  31.306 -	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
  31.307 -	  <quote><literal>serpentine.com</literal></quote>.</para>
  31.308 -      </listitem>
  31.309 -      <listitem><para><literal
  31.310 -	    role="template-kw-filt-author">email</literal>: Any text,
  31.311 -	  but most useful for the <literal
  31.312 -	    role="template-keyword">author</literal> keyword.  Extract
  31.313 -	  the first string that looks like an email address.  For
  31.314 -	  example, <quote><literal>Bryan O'Sullivan
  31.315 -	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
  31.316 -	  <quote><literal>bos@serpentine.com</literal></quote>.</para>
  31.317 -      </listitem>
  31.318 -      <listitem><para><literal
  31.319 -	    role="template-filter">escape</literal>: Any text.
  31.320 -	  Replace the special XML/XHTML characters
  31.321 -	  <quote><literal>&amp;</literal></quote>,
  31.322 -	  <quote><literal>&lt;</literal></quote> and
  31.323 -	  <quote><literal>&gt;</literal></quote> with XML
  31.324 -	  entities.</para>
  31.325 -      </listitem>
  31.326 -      <listitem><para><literal
  31.327 -	    role="template-filter">fill68</literal>: Any text.  Wrap
  31.328 -	  the text to fit in 68 columns.  This is useful before you
  31.329 -	  pass text through the <literal
  31.330 -	    role="template-filter">tabindent</literal> filter, and
  31.331 -	  still want it to fit in an 80-column fixed-font
  31.332 -	  window.</para>
  31.333 -      </listitem>
  31.334 -      <listitem><para><literal
  31.335 -	    role="template-filter">fill76</literal>: Any text.  Wrap
  31.336 -	  the text to fit in 76 columns.</para>
  31.337 -      </listitem>
  31.338 -      <listitem><para><literal
  31.339 -	    role="template-filter">firstline</literal>: Any text.
  31.340 -	  Yield the first line of text, without any trailing
  31.341 -	  newlines.</para>
  31.342 -      </listitem>
  31.343 -      <listitem><para><literal
  31.344 -	    role="template-kw-filt-date">hgdate</literal>: <literal
  31.345 -	    role="template-keyword">date</literal> keyword.  Render
  31.346 -	  the date as a pair of readable numbers.  Yields a string
  31.347 -	  like <quote><literal>1157407993
  31.348 -	      25200</literal></quote>.</para>
  31.349 -      </listitem>
  31.350 -      <listitem><para><literal
  31.351 -	    role="template-kw-filt-date">isodate</literal>: <literal
  31.352 -	    role="template-keyword">date</literal> keyword.  Render
  31.353 -	  the date as a text string in ISO 8601 format.  Yields a
  31.354 -	  string like <quote><literal>2006-09-04 15:13:13
  31.355 -	      -0700</literal></quote>.</para>
  31.356 -      </listitem>
  31.357 -      <listitem><para><literal
  31.358 -	    role="template-filter">obfuscate</literal>: Any text, but
  31.359 -	  most useful for the <literal
  31.360 -	    role="template-keyword">author</literal> keyword.  Yield
  31.361 -	  the input text rendered as a sequence of XML entities.  This
  31.362 -	  helps to defeat some particularly stupid screen-scraping
  31.363 -	  email harvesting spambots.</para>
  31.364 -      </listitem>
  31.365 -      <listitem><para><literal
  31.366 -	    role="template-kw-filt-author">person</literal>: Any text,
  31.367 -	  but most useful for the <literal
  31.368 -	    role="template-keyword">author</literal> keyword.  Yield
  31.369 -	  the text before an email address. For example,
  31.370 -	  <quote><literal>Bryan O'Sullivan
  31.371 -	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
  31.372 -	  <quote><literal>Bryan O'Sullivan</literal></quote>.</para>
  31.373 -      </listitem>
  31.374 -      <listitem><para><literal
  31.375 -	    role="template-kw-filt-date">rfc822date</literal>:
  31.376 -	  <literal role="template-keyword">date</literal> keyword.
  31.377 -	  Render a date using the same format used in email headers.
  31.378 -	  Yields a string like <quote><literal>Mon, 04 Sep 2006
  31.379 -	      15:13:13 -0700</literal></quote>.</para>
  31.380 -      </listitem>
  31.381 -      <listitem><para><literal
  31.382 -	    role="template-kw-filt-node">short</literal>: Changeset
  31.383 -	  hash.  Yield the short form of a changeset hash, i.e. a
  31.384 -	  12-character hexadecimal string.</para>
  31.385 -      </listitem>
  31.386 -      <listitem><para><literal
  31.387 -	    role="template-kw-filt-date">shortdate</literal>: <literal
  31.388 -	    role="template-keyword">date</literal> keyword.  Render
  31.389 -	  the year, month, and day of the date.  Yields a string like
  31.390 -	  <quote><literal>2006-09-04</literal></quote>.</para>
  31.391 -      </listitem>
  31.392 -      <listitem><para><literal role="template-filter">strip</literal>:
  31.393 -	  Any text.  Strip all leading and trailing whitespace from
  31.394 -	  the string.</para>
  31.395 -      </listitem>
  31.396 -      <listitem><para><literal
  31.397 -	    role="template-filter">tabindent</literal>: Any text.
  31.398 -	  Yield the text, with every line except the first starting
  31.399 -	  with a tab character.</para>
  31.400 -      </listitem>
  31.401 -      <listitem><para><literal
  31.402 -	    role="template-filter">urlescape</literal>: Any text.
  31.403 -	  Escape all characters that are considered
  31.404 -	  <quote>special</quote> by URL parsers.  For example,
  31.405 -	  <literal>foo bar</literal> becomes
  31.406 -	  <literal>foo%20bar</literal>.</para>
  31.407 -      </listitem>
  31.408 -      <listitem><para><literal
  31.409 -	    role="template-kw-filt-author">user</literal>: Any text,
  31.410 -	  but most useful for the <literal
  31.411 -	    role="template-keyword">author</literal> keyword.  Return
  31.412 -	  the <quote>user</quote> portion of an email address.  For
  31.413 -	  example, <quote><literal>Bryan O'Sullivan
  31.414 -	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
  31.415 -	  <quote><literal>bos</literal></quote>.</para>
  31.416 -      </listitem></itemizedlist>
  31.417 -
  31.418 -&interaction.template.simple.manyfilters;
  31.419 -
  31.420 -    <note>
  31.421 -      <para>  If you try to apply a filter to a piece of data that it
  31.422 -	cannot process, Mercurial will fail and print a Python
  31.423 -	exception.  For example, trying to run the output of the
  31.424 -	<literal role="template-keyword">desc</literal> keyword into
  31.425 -	the <literal role="template-kw-filt-date">isodate</literal>
  31.426 -	filter is not a good idea.</para>
  31.427 -    </note>
  31.428 -
  31.429 -    <sect2>
  31.430 -      <title>Combining filters</title>
  31.431 -
  31.432 -      <para>It is easy to combine filters to yield output in the form
  31.433 -	you would like.  The following chain of filters tidies up a
  31.434 -	description, then makes sure that it fits cleanly into 68
  31.435 -	columns, then indents it by a further 8 characters (at least
  31.436 -	on Unix-like systems, where a tab is conventionally 8
  31.437 -	characters wide).</para>
  31.438 -
  31.439 -      &interaction.template.simple.combine;
  31.440 -
  31.441 -      <para>Note the use of <quote><literal>\t</literal></quote> (a
  31.442 -	tab character) in the template to force the first line to be
  31.443 -	indented; this is necessary since <literal
  31.444 -	  role="template-keyword">tabindent</literal> indents all
  31.445 -	lines <emphasis>except</emphasis> the first.</para>
  31.446 -
  31.447 -      <para>Keep in mind that the order of filters in a chain is
  31.448 -	significant.  The first filter is applied to the result of the
  31.449 -	keyword; the second to the result of the first filter; and so
  31.450 -	on.  For example, using <literal>fill68|tabindent</literal>
  31.451 -	gives very different results from
  31.452 -	<literal>tabindent|fill68</literal>.</para>
  31.453 -
  31.454 -
  31.455 -    </sect2>
  31.456 -  </sect1>
  31.457 -  <sect1>
  31.458 -    <title>From templates to styles</title>
  31.459 -
  31.460 -    <para>A command line template provides a quick and simple way to
  31.461 -      format some output.  Templates can become verbose, though, and
  31.462 -      it's useful to be able to give a template a name.  A style file
  31.463 -      is a template with a name, stored in a file.</para>
  31.464 -
  31.465 -    <para>More than that, using a style file unlocks the power of
  31.466 -      Mercurial's templating engine in ways that are not possible
  31.467 -      using the command line <option
  31.468 -	role="hg-opt-log">--template</option> option.</para>
  31.469 -
  31.470 -    <sect2>
  31.471 -      <title>The simplest of style files</title>
  31.472 -
  31.473 -      <para>Our simple style file contains just one line:</para>
  31.474 -
  31.475 -      &interaction.template.simple.rev;
  31.476 -
  31.477 -      <para>This tells Mercurial, <quote>if you're printing a
  31.478 -	  changeset, use the text on the right as the
  31.479 -	  template</quote>.</para>
  31.480 -
  31.481 -    </sect2>
  31.482 -    <sect2>
  31.483 -      <title>Style file syntax</title>
  31.484 -
  31.485 -      <para>The syntax rules for a style file are simple.</para>
  31.486 -
  31.487 -      <itemizedlist>
  31.488 -	<listitem><para>The file is processed one line at a
  31.489 -	    time.</para>
  31.490 -	</listitem>
  31.491 -	<listitem><para>Leading and trailing white space are
  31.492 -	    ignored.</para>
  31.493 -	</listitem>
  31.494 -	<listitem><para>Empty lines are skipped.</para>
  31.495 -	</listitem>
  31.496 -	<listitem><para>If a line starts with either of the characters
  31.497 -	    <quote><literal>#</literal></quote> or
  31.498 -	    <quote><literal>;</literal></quote>, the entire line is
  31.499 -	    treated as a comment, and skipped as if empty.</para>
  31.500 -	</listitem>
  31.501 -	<listitem><para>A line starts with a keyword.  This must start
  31.502 -	    with an alphabetic character or underscore, and can
  31.503 -	    subsequently contain any alphanumeric character or
  31.504 -	    underscore.  (In regexp notation, a keyword must match
  31.505 -	    <literal>[A-Za-z_][A-Za-z0-9_]*</literal>.)</para>
  31.506 -	</listitem>
  31.507 -	<listitem><para>The next element must be an
  31.508 -	    <quote><literal>=</literal></quote> character, which can
  31.509 -	    be preceded or followed by an arbitrary amount of white
  31.510 -	    space.</para>
  31.511 -	</listitem>
  31.512 -	<listitem><para>If the rest of the line starts and ends with
  31.513 -	    matching quote characters (either single or double quote),
  31.514 -	    it is treated as a template body.</para>
  31.515 -	</listitem>
  31.516 -	<listitem><para>If the rest of the line <emphasis>does
  31.517 -	      not</emphasis> start with a quote character, it is
  31.518 -	    treated as the name of a file; the contents of this file
  31.519 -	    will be read and used as a template body.</para>
  31.520 -	</listitem></itemizedlist>
  31.521 -
  31.522 -    </sect2>
  31.523 -  </sect1>
  31.524 -  <sect1>
  31.525 -    <title>Style files by example</title>
  31.526 -
  31.527 -    <para>To illustrate how to write a style file, we will construct a
  31.528 -      few by example.  Rather than provide a complete style file and
  31.529 -      walk through it, we'll mirror the usual process of developing a
  31.530 -      style file by starting with something very simple, and walking
  31.531 -      through a series of successively more complete examples.</para>
  31.532 -
  31.533 -    <sect2>
  31.534 -      <title>Identifying mistakes in style files</title>
  31.535 -
  31.536 -      <para>If Mercurial encounters a problem in a style file you are
  31.537 -	working on, it prints a terse error message that, once you
  31.538 -	figure out what it means, is actually quite useful.</para>
  31.539 -
  31.540 -&interaction.template.svnstyle.syntax.input;
  31.541 -
  31.542 -      <para>Notice that <filename>broken.style</filename> attempts to
  31.543 -	define a <literal>changeset</literal> keyword, but forgets to
  31.544 -	give any content for it. When instructed to use this style
  31.545 -	file, Mercurial promptly complains.</para>
  31.546 -
  31.547 -      &interaction.template.svnstyle.syntax.error;
  31.548 -
  31.549 -      <para>This error message looks intimidating, but it is not too
  31.550 -	hard to follow.</para>
  31.551 -
  31.552 -      <itemizedlist>
  31.553 -	<listitem><para>The first component is simply Mercurial's way
  31.554 -	    of saying <quote>I am giving up</quote>.</para>
  31.555 -	  <programlisting>___abort___: broken.style:1: parse error</programlisting>
  31.556 -	</listitem>
  31.557 -	<listitem><para>Next comes the name of the style file that
  31.558 -	    contains the error.</para>
  31.559 -	  <programlisting>abort: ___broken.style___:1: parse error</programlisting>
  31.560 -	</listitem>
  31.561 -	<listitem><para>Following the file name is the line number
  31.562 -	    where the error was encountered.</para>
  31.563 -	  <programlisting>abort: broken.style:___1___: parse error</programlisting>
  31.564 -	</listitem>
  31.565 -	<listitem><para>Finally, a description of what went
  31.566 -	    wrong.</para>
  31.567 -	  <programlisting>abort: broken.style:1: ___parse error___</programlisting>
  31.568 -	</listitem>
  31.569 -	<listitem><para>The description of the problem is not always
  31.570 -	    clear (as in this case), but even when it is cryptic, it
  31.571 -	    is almost always trivial to visually inspect the offending
  31.572 -	    line in the style file and see what is wrong.</para>
  31.573 -	</listitem></itemizedlist>
  31.574 -
  31.575 -    </sect2>
  31.576 -    <sect2>
  31.577 -      <title>Uniquely identifying a repository</title>
  31.578 -
  31.579 -      <para>If you would like to be able to identify a Mercurial
  31.580 -	repository <quote>fairly uniquely</quote> using a short string
  31.581 -	as an identifier, you can use the first revision in the
  31.582 -	repository.</para>
  31.583 -
  31.584 -      &interaction.template.svnstyle.id;
  31.585 -
  31.586 -      <para>This is not guaranteed to be unique, but it is
  31.587 -	nevertheless useful in many cases.</para>
  31.588 -      <itemizedlist>
  31.589 -	<listitem><para>It will not work in a completely empty
  31.590 -	    repository, because such a repository does not have a
  31.591 -	    revision zero.</para>
  31.592 -	</listitem>
  31.593 -	<listitem><para>Neither will it work in the (extremely rare)
  31.594 -	    case where a repository is a merge of two or more formerly
  31.595 -	    independent repositories, and you still have those
  31.596 -	    repositories around.</para>
  31.597 -	</listitem></itemizedlist>
  31.598 -      <para>Here are some uses to which you could put this
  31.599 -	identifier:</para>
  31.600 -      <itemizedlist>
  31.601 -	<listitem><para>As a key into a table for a database that
  31.602 -	    manages repositories on a server.</para>
  31.603 -	</listitem>
  31.604 -	<listitem><para>As half of a {<emphasis>repository
  31.605 -	      ID</emphasis>, <emphasis>revision ID</emphasis>} tuple.
  31.606 -	    Save this information away when you run an automated build
  31.607 -	    or other activity, so that you can <quote>replay</quote>
  31.608 -	    the build later if necessary.</para>
  31.609 -	</listitem></itemizedlist>
  31.610 -
  31.611 -    </sect2>
  31.612 -    <sect2>
  31.613 -      <title>Mimicking Subversion's output</title>
  31.614 -
  31.615 -      <para>Let's try to emulate the default output format used by
  31.616 -	another revision control tool, Subversion.</para>
  31.617 -
  31.618 -      &interaction.template.svnstyle.short;
  31.619 -
  31.620 -      <para>Since Subversion's output style is fairly simple, it is
  31.621 -	easy to copy-and-paste a hunk of its output into a file, and
  31.622 -	replace the text produced above by Subversion with the
  31.623 -	template values we'd like to see expanded.</para>
  31.624 -
  31.625 -      &interaction.template.svnstyle.template;
  31.626 -
  31.627 -      <para>There are a few small ways in which this template deviates
  31.628 -	from the output produced by Subversion.</para>
  31.629 -      <itemizedlist>
  31.630 -	<listitem><para>Subversion prints a <quote>readable</quote>
  31.631 -	    date (the <quote><literal>Wed, 27 Sep 2006</literal></quote> in the
  31.632 -	    example output above) in parentheses.  Mercurial's
  31.633 -	    templating engine does not provide a way to display a date
  31.634 -	    in this format without also printing the time and time
  31.635 -	    zone.</para>
  31.636 -	</listitem>
  31.637 -	<listitem><para>We emulate Subversion's printing of
  31.638 -	    <quote>separator</quote> lines full of
  31.639 -	    <quote><literal>-</literal></quote> characters by ending
  31.640 -	    the template with such a line. We use the templating
  31.641 -	    engine's <literal role="template-keyword">header</literal>
  31.642 -	    keyword to print a separator line as the first line of
  31.643 -	    output (see below), thus achieving similar output to
  31.644 -	    Subversion.</para>
  31.645 -	</listitem>
  31.646 -	<listitem><para>Subversion's output includes a count in the
  31.647 -	    header of the number of lines in the commit message.  We
  31.648 -	    cannot replicate this in Mercurial; the templating engine
  31.649 -	    does not currently provide a filter that counts the number
  31.650 -	    of lines the template generates.</para>
  31.651 -	</listitem></itemizedlist>
  31.652 -      <para>It took me no more than a minute or two of work to replace
  31.653 -	literal text from an example of Subversion's output with some
  31.654 -	keywords and filters to give the template above.  The style
  31.655 -	file simply refers to the template.</para>
  31.656 -
  31.657 -      &interaction.template.svnstyle.style;
  31.658 -
  31.659 -      <para>We could have included the text of the template file
  31.660 -	directly in the style file by enclosing it in quotes and
  31.661 -	replacing the newlines with
  31.662 -	<quote><literal>\n</literal></quote> sequences, but it would
  31.663 -	have made the style file too difficult to read.  Readability
  31.664 -	is a good guide when you're trying to decide whether some text
  31.665 -	belongs in a style file, or in a template file that the style
  31.666 -	file points to.  If the style file will look too big or
  31.667 -	cluttered if you insert a literal piece of text, drop it into
  31.668 -	a template instead.</para>
  31.669 -
  31.670 -    </sect2>
  31.671 -  </sect1>
  31.672 -</chapter>
  31.673 -
  31.674 -<!--
  31.675 -local variables: 
  31.676 -sgml-parent-document: ("00book.xml" "book" "chapter")
  31.677 -end:
  31.678 --->
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/en/ch12-mq-collab.xml	Fri Mar 20 16:43:35 2009 +0800
    32.3 @@ -0,0 +1,518 @@
    32.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    32.5 +
    32.6 +<chapter id="chap.mq-collab">
    32.7 +  <?dbhtml filename="advanced-uses-of-mercurial-queues.html"?>
    32.8 +  <title>Advanced uses of Mercurial Queues</title>
    32.9 +
   32.10 +  <para id="x_15d">While it's easy to pick up straightforward uses of Mercurial
   32.11 +    Queues, use of a little discipline and some of MQ's less
   32.12 +    frequently used capabilities makes it possible to work in
   32.13 +    complicated development environments.</para>
   32.14 +
   32.15 +  <para id="x_15e">In this chapter, I will use as an example a technique I have
   32.16 +    used to manage the development of an Infiniband device driver for
   32.17 +    the Linux kernel.  The driver in question is large (at least as
   32.18 +    drivers go), with 25,000 lines of code spread across 35 source
   32.19 +    files.  It is maintained by a small team of developers.</para>
   32.20 +
   32.21 +  <para id="x_15f">While much of the material in this chapter is specific to
   32.22 +    Linux, the same principles apply to any code base for which you're
   32.23 +    not the primary owner, and upon which you need to do a lot of
   32.24 +    development.</para>
   32.25 +
   32.26 +  <sect1>
   32.27 +    <title>The problem of many targets</title>
   32.28 +
   32.29 +    <para id="x_160">The Linux kernel changes rapidly, and has never been
   32.30 +      internally stable; developers frequently make drastic changes
   32.31 +      between releases. This means that a version of the driver that
   32.32 +      works well with a particular released version of the kernel will
   32.33 +      not even <emphasis>compile</emphasis> correctly against,
   32.34 +      typically, any other version.</para>
   32.35 +
   32.36 +    <para id="x_161">To maintain a driver, we have to keep a number of distinct
   32.37 +      versions of Linux in mind.</para>
   32.38 +    <itemizedlist>
   32.39 +      <listitem><para id="x_162">One target is the main Linux kernel development
   32.40 +	  tree. Maintenance of the code is in this case partly shared
   32.41 +	  by other developers in the kernel community, who make
   32.42 +	  <quote>drive-by</quote> modifications to the driver as they
   32.43 +	  develop and refine kernel subsystems.</para>
   32.44 +      </listitem>
   32.45 +      <listitem><para id="x_163">We also maintain a number of
   32.46 +	  <quote>backports</quote> to older versions of the Linux
   32.47 +	  kernel, to support the needs of customers who are running
   32.48 +	  older Linux distributions that do not incorporate our
   32.49 +	  drivers.  (To <emphasis>backport</emphasis> a piece of code
   32.50 +	  is to modify it to work in an older version of its target
   32.51 +	  environment than the version it was developed for.)</para>
   32.52 +      </listitem>
   32.53 +      <listitem><para id="x_164">Finally, we make software releases on a schedule
   32.54 +	  that is necessarily not aligned with those used by Linux
   32.55 +	  distributors and kernel developers, so that we can deliver
   32.56 +	  new features to customers without forcing them to upgrade
   32.57 +	  their entire kernels or distributions.</para>
   32.58 +      </listitem></itemizedlist>
   32.59 +
   32.60 +    <sect2>
   32.61 +      <title>Tempting approaches that don't work well</title>
   32.62 +
   32.63 +      <para id="x_165">There are two <quote>standard</quote> ways to maintain a
   32.64 +	piece of software that has to target many different
   32.65 +	environments.</para>
   32.66 +
   32.67 +      <para id="x_166">The first is to maintain a number of branches, each
   32.68 +	intended for a single target.  The trouble with this approach
   32.69 +	is that you must maintain iron discipline in the flow of
   32.70 +	changes between repositories. A new feature or bug fix must
   32.71 +	start life in a <quote>pristine</quote> repository, then
   32.72 +	percolate out to every backport repository.  Backport changes
   32.73 +	are more limited in the branches they should propagate to; a
   32.74 +	backport change that is applied to a branch where it doesn't
   32.75 +	belong will probably stop the driver from compiling.</para>
   32.76 +
   32.77 +      <para id="x_167">The second is to maintain a single source tree filled with
   32.78 +	conditional statements that turn chunks of code on or off
   32.79 +	depending on the intended target.  Because these
   32.80 +	<quote>ifdefs</quote> are not allowed in the Linux kernel
   32.81 +	tree, a manual or automatic process must be followed to strip
   32.82 +	them out and yield a clean tree.  A code base maintained in
   32.83 +	this fashion rapidly becomes a rat's nest of conditional
   32.84 +	blocks that are difficult to understand and maintain.</para>
   32.85 +
   32.86 +      <para id="x_168">Neither of these approaches is well suited to a situation
   32.87 +	where you don't <quote>own</quote> the canonical copy of a
   32.88 +	source tree.  In the case of a Linux driver that is
   32.89 +	distributed with the standard kernel, Linus's tree contains
   32.90 +	the copy of the code that will be treated by the world as
   32.91 +	canonical.  The upstream version of <quote>my</quote> driver
   32.92 +	can be modified by people I don't know, without me even
   32.93 +	finding out about it until after the changes show up in
   32.94 +	Linus's tree.</para>
   32.95 +
   32.96 +      <para id="x_169">These approaches have the added weakness of making it
   32.97 +	difficult to generate well-formed patches to submit
   32.98 +	upstream.</para>
   32.99 +
  32.100 +      <para id="x_16a">In principle, Mercurial Queues seems like a good candidate
  32.101 +	to manage a development scenario such as the above.  While
  32.102 +	this is indeed the case, MQ contains a few added features that
  32.103 +	make the job more pleasant.</para>
  32.104 +
  32.105 +    </sect2>
  32.106 +  </sect1>
  32.107 +  <sect1>
  32.108 +    <title>Conditionally applying patches with guards</title>
  32.109 +
  32.110 +    <para id="x_16b">Perhaps the best way to maintain sanity with so many targets
  32.111 +      is to be able to choose specific patches to apply for a given
  32.112 +      situation.  MQ provides a feature called <quote>guards</quote>
  32.113 +      (which originates with quilt's <literal>guards</literal>
  32.114 +      command) that does just this.  To start off, let's create a
  32.115 +      simple repository for experimenting in.</para>
  32.116 +
  32.117 +    &interaction.mq.guards.init;
  32.118 +
  32.119 +    <para id="x_16c">This gives us a tiny repository that contains two patches
  32.120 +      that don't have any dependencies on each other, because they
  32.121 +      touch different files.</para>
  32.122 +
  32.123 +    <para id="x_16d">The idea behind conditional application is that you can
  32.124 +      <quote>tag</quote> a patch with a <emphasis>guard</emphasis>,
  32.125 +      which is simply a text string of your choosing, then tell MQ to
  32.126 +      select specific guards to use when applying patches.  MQ will
  32.127 +      then either apply, or skip over, a guarded patch, depending on
  32.128 +      the guards that you have selected.</para>
  32.129 +
  32.130 +    <para id="x_16e">A patch can have an arbitrary number of guards; each one is
  32.131 +      <emphasis>positive</emphasis> (<quote>apply this patch if this
  32.132 +	guard is selected</quote>) or <emphasis>negative</emphasis>
  32.133 +      (<quote>skip this patch if this guard is selected</quote>).  A
  32.134 +      patch with no guards is always applied.</para>
  32.135 +
  32.136 +  </sect1>
  32.137 +  <sect1>
  32.138 +    <title>Controlling the guards on a patch</title>
  32.139 +
  32.140 +    <para id="x_16f">The <command role="hg-ext-mq">qguard</command> command lets
  32.141 +      you determine which guards should apply to a patch, or display
  32.142 +      the guards that are already in effect. Without any arguments, it
  32.143 +      displays the guards on the current topmost patch.</para>
  32.144 +
  32.145 +      &interaction.mq.guards.qguard;
  32.146 +
  32.147 +    <para id="x_170">To set a positive guard on a patch, prefix the name of the
  32.148 +      guard with a <quote><literal>+</literal></quote>.</para>
  32.149 +
  32.150 +      &interaction.mq.guards.qguard.pos;
  32.151 +
  32.152 +    <para id="x_171">To set a negative guard
  32.153 +      on a patch, prefix the name of the guard with a
  32.154 +      <quote><literal>-</literal></quote>.</para>
  32.155 +
  32.156 +    &interaction.mq.guards.qguard.neg;
  32.157 +
  32.158 +    <note>
  32.159 +      <para id="x_172">  The <command role="hg-ext-mq">qguard</command> command
  32.160 +	<emphasis>sets</emphasis> the guards on a patch; it doesn't
  32.161 +	<emphasis>modify</emphasis> them.  What this means is that if
  32.162 +	you run <command role="hg-cmd">hg qguard +a +b</command> on a
  32.163 +	patch, then <command role="hg-cmd">hg qguard +c</command> on
  32.164 +	the same patch, the <emphasis>only</emphasis> guard that will
  32.165 +	be set on it afterwards is <literal>+c</literal>.</para>
  32.166 +    </note>
  32.167 +
  32.168 +    <para id="x_173">Mercurial stores guards in the <filename
  32.169 +	role="special">series</filename> file; the form in which they
  32.170 +      are stored is easy both to understand and to edit by hand. (In
  32.171 +      other words, you don't have to use the <command
  32.172 +	role="hg-ext-mq">qguard</command> command if you don't want
  32.173 +      to; it's okay to simply edit the <filename
  32.174 +	role="special">series</filename> file.)</para>
  32.175 +
  32.176 +    &interaction.mq.guards.series;
  32.177 +
  32.178 +  </sect1>
  32.179 +  <sect1>
  32.180 +    <title>Selecting the guards to use</title>
  32.181 +
  32.182 +    <para id="x_174">The <command role="hg-ext-mq">qselect</command> command
  32.183 +      determines which guards are active at a given time.  The effect
  32.184 +      of this is to determine which patches MQ will apply the next
  32.185 +      time you run <command role="hg-ext-mq">qpush</command>.  It has
  32.186 +      no other effect; in particular, it doesn't do anything to
  32.187 +      patches that are already applied.</para>
  32.188 +
  32.189 +    <para id="x_175">With no arguments, the <command
  32.190 +	role="hg-ext-mq">qselect</command> command lists the guards
  32.191 +      currently in effect, one per line of output.  Each argument is
  32.192 +      treated as the name of a guard to apply.</para>
  32.193 +
  32.194 +      &interaction.mq.guards.qselect.foo;
  32.195 +
  32.196 +    <para id="x_176">In case you're interested, the currently selected guards are
  32.197 +      stored in the <filename role="special">guards</filename> file.</para>
  32.198 +
  32.199 +    &interaction.mq.guards.qselect.cat;
  32.200 +
  32.201 +    <para id="x_177">We can see the effect the selected guards have when we run
  32.202 +      <command role="hg-ext-mq">qpush</command>.</para>
  32.203 +
  32.204 +    &interaction.mq.guards.qselect.qpush;
  32.205 +
  32.206 +    <para id="x_178">A guard cannot start with a
  32.207 +      <quote><literal>+</literal></quote> or
  32.208 +      <quote><literal>-</literal></quote> character.  The name of a
  32.209 +      guard must not contain white space, but most other characters
  32.210 +      are acceptable.  If you try to use a guard with an invalid name,
  32.211 +      MQ will complain:</para>
  32.212 +
  32.213 +    &interaction.mq.guards.qselect.error;
  32.214 +      
  32.215 +    <para id="x_179">Changing the selected guards changes the patches that are
  32.216 +      applied.</para>
  32.217 +
  32.218 +    &interaction.mq.guards.qselect.quux;
  32.219 +
  32.220 +    <para id="x_17a">You can see in the example below that negative guards take
  32.221 +      precedence over positive guards.</para>
  32.222 +
  32.223 +    &interaction.mq.guards.qselect.foobar;
  32.224 +
  32.225 +  </sect1>
  32.226 +  <sect1>
  32.227 +    <title>MQ's rules for applying patches</title>
  32.228 +
  32.229 +    <para id="x_17b">The rules that MQ uses when deciding whether to apply a
  32.230 +      patch are as follows.</para>
  32.231 +    <itemizedlist>
  32.232 +      <listitem><para id="x_17c">A patch that has no guards is always
  32.233 +	  applied.</para>
  32.234 +      </listitem>
  32.235 +      <listitem><para id="x_17d">If the patch has any negative guard that matches
  32.236 +	  any currently selected guard, the patch is skipped.</para>
  32.237 +      </listitem>
  32.238 +      <listitem><para id="x_17e">If the patch has any positive guard that matches
  32.239 +	  any currently selected guard, the patch is applied.</para>
  32.240 +      </listitem>
  32.241 +      <listitem><para id="x_17f">If the patch has positive or negative guards,
  32.242 +	  but none matches any currently selected guard, the patch is
  32.243 +	  skipped.</para>
  32.244 +      </listitem></itemizedlist>
  32.245 +
  32.246 +  </sect1>
  32.247 +  <sect1>
  32.248 +    <title>Trimming the work environment</title>
  32.249 +
  32.250 +    <para id="x_180">In working on the device driver I mentioned earlier, I don't
  32.251 +      apply the patches to a normal Linux kernel tree.  Instead, I use
  32.252 +      a repository that contains only a snapshot of the source files
  32.253 +      and headers that are relevant to Infiniband development.  This
  32.254 +      repository is 1% the size of a kernel repository, so it's easier
  32.255 +      to work with.</para>
  32.256 +
  32.257 +    <para id="x_181">I then choose a <quote>base</quote> version on top of which
  32.258 +      the patches are applied.  This is a snapshot of the Linux kernel
  32.259 +      tree as of a revision of my choosing.  When I take the snapshot,
  32.260 +      I record the changeset ID from the kernel repository in the
  32.261 +      commit message.  Since the snapshot preserves the
  32.262 +      <quote>shape</quote> and content of the relevant parts of the
  32.263 +      kernel tree, I can apply my patches on top of either my tiny
  32.264 +      repository or a normal kernel tree.</para>
  32.265 +
  32.266 +    <para id="x_182">Normally, the base tree atop which the patches apply should
  32.267 +      be a snapshot of a very recent upstream tree.  This best
  32.268 +      facilitates the development of patches that can easily be
  32.269 +      submitted upstream with few or no modifications.</para>
  32.270 +
  32.271 +  </sect1>
  32.272 +  <sect1>
  32.273 +    <title>Dividing up the <filename role="special">series</filename>
  32.274 +      file</title>
  32.275 +
  32.276 +    <para id="x_183">I categorise the patches in the <filename
  32.277 +	role="special">series</filename> file into a number of logical
  32.278 +      groups.  Each section of like patches begins with a block of
  32.279 +      comments that describes the purpose of the patches that
  32.280 +      follow.</para>
  32.281 +
  32.282 +    <para id="x_184">The sequence of patch groups that I maintain follows.  The
  32.283 +      ordering of these groups is important; I'll describe why after I
  32.284 +      introduce the groups.</para>
  32.285 +    <itemizedlist>
  32.286 +      <listitem><para id="x_185">The <quote>accepted</quote> group.  Patches that
  32.287 +	  the development team has submitted to the maintainer of the
  32.288 +	  Infiniband subsystem, and which he has accepted, but which
  32.289 +	  are not present in the snapshot that the tiny repository is
  32.290 +	  based on.  These are <quote>read only</quote> patches,
  32.291 +	  present only to transform the tree into a similar state as
  32.292 +	  it is in the upstream maintainer's repository.</para>
  32.293 +      </listitem>
  32.294 +      <listitem><para id="x_186">The <quote>rework</quote> group.  Patches that I
  32.295 +	  have submitted, but that the upstream maintainer has
  32.296 +	  requested modifications to before he will accept
  32.297 +	  them.</para>
  32.298 +      </listitem>
  32.299 +      <listitem><para id="x_187">The <quote>pending</quote> group.  Patches that
  32.300 +	  I have not yet submitted to the upstream maintainer, but
  32.301 +	  which we have finished working on. These will be <quote>read
  32.302 +	    only</quote> for a while.  If the upstream maintainer
  32.303 +	  accepts them upon submission, I'll move them to the end of
  32.304 +	  the <quote>accepted</quote> group.  If he requests that I
  32.305 +	  modify any, I'll move them to the beginning of the
  32.306 +	  <quote>rework</quote> group.</para>
  32.307 +      </listitem>
  32.308 +      <listitem><para id="x_188">The <quote>in progress</quote> group.  Patches
  32.309 +	  that are actively being developed, and should not be
  32.310 +	  submitted anywhere yet.</para>
  32.311 +      </listitem>
  32.312 +      <listitem><para id="x_189">The <quote>backport</quote> group.  Patches that
  32.313 +	  adapt the source tree to older versions of the kernel
  32.314 +	  tree.</para>
  32.315 +      </listitem>
  32.316 +      <listitem><para id="x_18a">The <quote>do not ship</quote> group.  Patches
  32.317 +	  that for some reason should never be submitted upstream.
  32.318 +	  For example, one such patch might change embedded driver
  32.319 +	  identification strings to make it easier to distinguish, in
  32.320 +	  the field, between an out-of-tree version of the driver and
  32.321 +	  a version shipped by a distribution vendor.</para>
  32.322 +      </listitem></itemizedlist>
  32.323 +
  32.324 +    <para id="x_18b">Now to return to the reasons for ordering groups of patches
  32.325 +      in this way.  We would like the lowest patches in the stack to
  32.326 +      be as stable as possible, so that we will not need to rework
  32.327 +      higher patches due to changes in context.  Putting patches that
  32.328 +      will never be changed first in the <filename
  32.329 +	role="special">series</filename> file serves this
  32.330 +      purpose.</para>
  32.331 +
  32.332 +    <para id="x_18c">We would also like the patches that we know we'll need to
  32.333 +      modify to be applied on top of a source tree that resembles the
  32.334 +      upstream tree as closely as possible.  This is why we keep
  32.335 +      accepted patches around for a while.</para>
  32.336 +
  32.337 +    <para id="x_18d">The <quote>backport</quote> and <quote>do not ship</quote>
  32.338 +      patches float at the end of the <filename
  32.339 +	role="special">series</filename> file.  The backport patches
  32.340 +      must be applied on top of all other patches, and the <quote>do
  32.341 +	not ship</quote> patches might as well stay out of harm's
  32.342 +      way.</para>
  32.343 +
  32.344 +  </sect1>
  32.345 +  <sect1>
  32.346 +    <title>Maintaining the patch series</title>
  32.347 +
  32.348 +    <para id="x_18e">In my work, I use a number of guards to control which
  32.349 +      patches are to be applied.</para>
  32.350 +
  32.351 +    <itemizedlist>
  32.352 +      <listitem><para id="x_18f"><quote>Accepted</quote> patches are guarded with
  32.353 +	  <literal>accepted</literal>.  I enable this guard most of
  32.354 +	  the time.  When I'm applying the patches on top of a tree
  32.355 +	  where the patches are already present, I can turn this patch
  32.356 +	  off, and the patches that follow it will apply
  32.357 +	  cleanly.</para>
  32.358 +      </listitem>
  32.359 +      <listitem><para id="x_190">Patches that are <quote>finished</quote>, but
  32.360 +	  not yet submitted, have no guards.  If I'm applying the
  32.361 +	  patch stack to a copy of the upstream tree, I don't need to
  32.362 +	  enable any guards in order to get a reasonably safe source
  32.363 +	  tree.</para>
  32.364 +      </listitem>
  32.365 +      <listitem><para id="x_191">Those patches that need reworking before being
  32.366 +	  resubmitted are guarded with
  32.367 +	  <literal>rework</literal>.</para>
  32.368 +      </listitem>
  32.369 +      <listitem><para id="x_192">For those patches that are still under
  32.370 +	  development, I use <literal>devel</literal>.</para>
  32.371 +      </listitem>
  32.372 +      <listitem><para id="x_193">A backport patch may have several guards, one
  32.373 +	  for each version of the kernel to which it applies.  For
  32.374 +	  example, a patch that backports a piece of code to 2.6.9
  32.375 +	  will have a <literal>2.6.9</literal> guard.</para>
  32.376 +      </listitem></itemizedlist>
  32.377 +    <para id="x_194">This variety of guards gives me considerable flexibility in
  32.378 +      determining what kind of source tree I want to end up with.  For
  32.379 +      most situations, the selection of appropriate guards is
  32.380 +      automated during the build process, but I can manually tune the
  32.381 +      guards to use for less common circumstances.</para>
  32.382 +
  32.383 +    <sect2>
  32.384 +      <title>The art of writing backport patches</title>
  32.385 +
  32.386 +      <para id="x_195">Using MQ, writing a backport patch is a simple process.
  32.387 +	All such a patch has to do is modify a piece of code that uses
  32.388 +	a kernel feature not present in the older version of the
  32.389 +	kernel, so that the driver continues to work correctly under
  32.390 +	that older version.</para>
  32.391 +
  32.392 +      <para id="x_196">A useful goal when writing a good backport patch is to
  32.393 +	make your code look as if it was written for the older version
  32.394 +	of the kernel you're targeting.  The less obtrusive the patch,
  32.395 +	the easier it will be to understand and maintain.  If you're
  32.396 +	writing a collection of backport patches to avoid the
  32.397 +	<quote>rat's nest</quote> effect of lots of
  32.398 +	<literal>#ifdef</literal>s (hunks of source code that are only
  32.399 +	used conditionally) in your code, don't introduce
  32.400 +	version-dependent <literal>#ifdef</literal>s into the patches.
  32.401 +	Instead, write several patches, each of which makes
  32.402 +	unconditional changes, and control their application using
  32.403 +	guards.</para>
  32.404 +
  32.405 +      <para id="x_197">There are two reasons to divide backport patches into a
  32.406 +	distinct group, away from the <quote>regular</quote> patches
  32.407 +	whose effects they modify. The first is that intermingling the
  32.408 +	two makes it more difficult to use a tool like the <literal
  32.409 +	  role="hg-ext">patchbomb</literal> extension to automate the
  32.410 +	process of submitting the patches to an upstream maintainer.
  32.411 +	The second is that a backport patch could perturb the context
  32.412 +	in which a subsequent regular patch is applied, making it
  32.413 +	impossible to apply the regular patch cleanly
  32.414 +	<emphasis>without</emphasis> the earlier backport patch
  32.415 +	already being applied.</para>
  32.416 +
  32.417 +    </sect2>
  32.418 +  </sect1>
  32.419 +  <sect1>
  32.420 +    <title>Useful tips for developing with MQ</title>
  32.421 +
  32.422 +    <sect2>
  32.423 +      <title>Organising patches in directories</title>
  32.424 +
  32.425 +      <para id="x_198">If you're working on a substantial project with MQ, it's
  32.426 +	not difficult to accumulate a large number of patches.  For
  32.427 +	example, I have one patch repository that contains over 250
  32.428 +	patches.</para>
  32.429 +
  32.430 +      <para id="x_199">If you can group these patches into separate logical
  32.431 +	categories, you can if you like store them in different
  32.432 +	directories; MQ has no problems with patch names that contain
  32.433 +	path separators.</para>
  32.434 +
  32.435 +    </sect2>
  32.436 +    <sect2 id="mq-collab.tips.interdiff">
  32.437 +      <title>Viewing the history of a patch</title>
  32.438 +
  32.439 +      <para id="x_19a">If you're developing a set of patches over a long time,
  32.440 +	it's a good idea to maintain them in a repository, as
  32.441 +	discussed in section <xref linkend="sec.mq.repo"/>.  If you do
  32.442 +	so, you'll quickly
  32.443 +	discover that using the <command role="hg-cmd">hg
  32.444 +	  diff</command> command to look at the history of changes to
  32.445 +	a patch is unworkable.  This is in part because you're looking
  32.446 +	at the second derivative of the real code (a diff of a diff),
  32.447 +	but also because MQ adds noise to the process by modifying
  32.448 +	time stamps and directory names when it updates a
  32.449 +	patch.</para>
  32.450 +
  32.451 +      <para id="x_19b">However, you can use the <literal
  32.452 +	  role="hg-ext">extdiff</literal> extension, which is bundled
  32.453 +	with Mercurial, to turn a diff of two versions of a patch into
  32.454 +	something readable.  To do this, you will need a third-party
  32.455 +	package called <literal role="package">patchutils</literal>
  32.456 +	<citation>web:patchutils</citation>.  This provides a command
  32.457 +	named <command>interdiff</command>, which shows the
  32.458 +	differences between two diffs as a diff.  Used on two versions
  32.459 +	of the same diff, it generates a diff that represents the diff
  32.460 +	from the first to the second version.</para>
  32.461 +
  32.462 +      <para id="x_19c">You can enable the <literal
  32.463 +	  role="hg-ext">extdiff</literal> extension in the usual way,
  32.464 +	by adding a line to the <literal
  32.465 +	  role="rc-extensions">extensions</literal> section of your
  32.466 +	<filename role="special">~/.hgrc</filename>.</para>
  32.467 +      <programlisting>[extensions]
  32.468 +extdiff =</programlisting>
  32.469 +      <para id="x_19d">The <command>interdiff</command> command expects to be
  32.470 +	passed the names of two files, but the <literal
  32.471 +	  role="hg-ext">extdiff</literal> extension passes the program
  32.472 +	it runs a pair of directories, each of which can contain an
  32.473 +	arbitrary number of files.  We thus need a small program that
  32.474 +	will run <command>interdiff</command> on each pair of files in
  32.475 +	these two directories.  This program is available as <filename
  32.476 +	  role="special">hg-interdiff</filename> in the <filename
  32.477 +	  class="directory">examples</filename> directory of the
  32.478 +	source code repository that accompanies this book. <!--
  32.479 +	&example.hg-interdiff; --></para>
  32.480 +
  32.481 +      <para id="x_19e">With the <filename role="special">hg-interdiff</filename>
  32.482 +	program in your shell's search path, you can run it as
  32.483 +	follows, from inside an MQ patch directory:</para>
  32.484 +      <programlisting>hg extdiff -p hg-interdiff -r A:B my-change.patch</programlisting>
  32.485 +      <para id="x_19f">Since you'll probably want to use this long-winded command
  32.486 +	a lot, you can get <literal role="hg-ext">hgext</literal> to
  32.487 +	make it available as a normal Mercurial command, again by
  32.488 +	editing your <filename
  32.489 +	  role="special">~/.hgrc</filename>.</para>
  32.490 +      <programlisting>[extdiff]
  32.491 +cmd.interdiff = hg-interdiff</programlisting>
  32.492 +      <para id="x_1a0">This directs <literal role="hg-ext">hgext</literal> to
  32.493 +	make an <literal>interdiff</literal> command available, so you
  32.494 +	can now shorten the previous invocation of <command
  32.495 +	  role="hg-ext-extdiff">extdiff</command> to something a
  32.496 +	little more wieldy.</para>
  32.497 +      <programlisting>hg interdiff -r A:B my-change.patch</programlisting>
  32.498 +
  32.499 +      <note>
  32.500 +	<para id="x_1a1">  The <command>interdiff</command> command works well
  32.501 +	  only if the underlying files against which versions of a
  32.502 +	  patch are generated remain the same.  If you create a patch,
  32.503 +	  modify the underlying files, and then regenerate the patch,
  32.504 +	  <command>interdiff</command> may not produce useful
  32.505 +	  output.</para>
  32.506 +      </note>
  32.507 +
  32.508 +      <para id="x_1a2">The <literal role="hg-ext">extdiff</literal> extension is
  32.509 +	useful for more than merely improving the presentation of MQ
  32.510 +	patches.  To read more about it, go to section <xref
  32.511 +	  linkend="sec.hgext.extdiff"/>.</para>
  32.512 +
  32.513 +    </sect2>
  32.514 +  </sect1>
  32.515 +</chapter>
  32.516 +
  32.517 +<!--
  32.518 +local variables: 
  32.519 +sgml-parent-document: ("00book.xml" "book" "chapter")
  32.520 +end:
  32.521 +-->
    33.1 --- a/en/ch12-mq.xml	Fri Mar 20 15:40:06 2009 +0800
    33.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.3 @@ -1,1323 +0,0 @@
    33.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    33.5 -
    33.6 -<chapter id="chap.mq">
    33.7 -  <?dbhtml filename="managing-change-with-mercurial-queues.html"?>
    33.8 -  <title>Managing change with Mercurial Queues</title>
    33.9 -
   33.10 -  <sect1 id="sec.mq.patch-mgmt">
   33.11 -    <title>The patch management problem</title>
   33.12 -
   33.13 -    <para>Here is a common scenario: you need to install a software
   33.14 -      package from source, but you find a bug that you must fix in the
   33.15 -      source before you can start using the package.  You make your
   33.16 -      changes, forget about the package for a while, and a few months
   33.17 -      later you need to upgrade to a newer version of the package.  If
   33.18 -      the newer version of the package still has the bug, you must
   33.19 -      extract your fix from the older source tree and apply it against
   33.20 -      the newer version.  This is a tedious task, and it's easy to
   33.21 -      make mistakes.</para>
   33.22 -
   33.23 -    <para>This is a simple case of the <quote>patch management</quote>
   33.24 -      problem.  You have an <quote>upstream</quote> source tree that
   33.25 -      you can't change; you need to make some local changes on top of
   33.26 -      the upstream tree; and you'd like to be able to keep those
   33.27 -      changes separate, so that you can apply them to newer versions
   33.28 -      of the upstream source.</para>
   33.29 -
   33.30 -    <para>The patch management problem arises in many situations.
   33.31 -      Probably the most visible is that a user of an open source
   33.32 -      software project will contribute a bug fix or new feature to the
   33.33 -      project's maintainers in the form of a patch.</para>
   33.34 -
   33.35 -    <para>Distributors of operating systems that include open source
   33.36 -      software often need to make changes to the packages they
   33.37 -      distribute so that they will build properly in their
   33.38 -      environments.</para>
   33.39 -
   33.40 -    <para>When you have few changes to maintain, it is easy to manage
   33.41 -      a single patch using the standard <command>diff</command> and
   33.42 -      <command>patch</command> programs (see section <xref
   33.43 -	linkend="sec.mq.patch"/> for a discussion of these
   33.44 -      tools). Once the number of changes grows, it starts to make
   33.45 -      sense to maintain patches as discrete <quote>chunks of
   33.46 -	work,</quote> so that for example a single patch will contain
   33.47 -      only one bug fix (the patch might modify several files, but it's
   33.48 -      doing <quote>only one thing</quote>), and you may have a number
   33.49 -      of such patches for different bugs you need fixed and local
   33.50 -      changes you require.  In this situation, if you submit a bug fix
   33.51 -      patch to the upstream maintainers of a package and they include
   33.52 -      your fix in a subsequent release, you can simply drop that
   33.53 -      single patch when you're updating to the newer release.</para>
   33.54 -
   33.55 -    <para>Maintaining a single patch against an upstream tree is a
   33.56 -      little tedious and error-prone, but not difficult.  However, the
   33.57 -      complexity of the problem grows rapidly as the number of patches
   33.58 -      you have to maintain increases.  With more than a tiny number of
   33.59 -      patches in hand, understanding which ones you have applied and
   33.60 -      maintaining them moves from messy to overwhelming.</para>
   33.61 -
   33.62 -    <para>Fortunately, Mercurial includes a powerful extension,
   33.63 -      Mercurial Queues (or simply <quote>MQ</quote>), that massively
   33.64 -      simplifies the patch management problem.</para>
   33.65 -
   33.66 -  </sect1>
   33.67 -  <sect1 id="sec.mq.history">
   33.68 -    <title>The prehistory of Mercurial Queues</title>
   33.69 -
   33.70 -    <para>During the late 1990s, several Linux kernel developers
   33.71 -      started to maintain <quote>patch series</quote> that modified
   33.72 -      the behaviour of the Linux kernel.  Some of these series were
   33.73 -      focused on stability, some on feature coverage, and others were
   33.74 -      more speculative.</para>
   33.75 -
   33.76 -    <para>The sizes of these patch series grew rapidly.  In 2002,
   33.77 -      Andrew Morton published some shell scripts he had been using to
   33.78 -      automate the task of managing his patch queues.  Andrew was
   33.79 -      successfully using these scripts to manage hundreds (sometimes
   33.80 -      thousands) of patches on top of the Linux kernel.</para>
   33.81 -
   33.82 -    <sect2 id="sec.mq.quilt">
   33.83 -      <title>A patchwork quilt</title>
   33.84 -
   33.85 -      <para>In early 2003, Andreas Gruenbacher and Martin Quinson
   33.86 -	borrowed the approach of Andrew's scripts and published a tool
   33.87 -	called <quote>patchwork quilt</quote>
   33.88 -	<citation>web:quilt</citation>, or simply <quote>quilt</quote>
   33.89 -	(see <citation>gruenbacher:2005</citation> for a paper
   33.90 -	describing it).  Because quilt substantially automated patch
   33.91 -	management, it rapidly gained a large following among open
   33.92 -	source software developers.</para>
   33.93 -
   33.94 -      <para>Quilt manages a <emphasis>stack of patches</emphasis> on
   33.95 -	top of a directory tree. To begin, you tell quilt to manage a
   33.96 -	directory tree, and tell it which files you want to manage; it
   33.97 -	stores away the names and contents of those files.  To fix a
   33.98 -	bug, you create a new patch (using a single command), edit the
   33.99 -	files you need to fix, then <quote>refresh</quote> the
  33.100 -	patch.</para>
  33.101 -
  33.102 -      <para>The refresh step causes quilt to scan the directory tree;
  33.103 -	it updates the patch with all of the changes you have made.
  33.104 -	You can create another patch on top of the first, which will
  33.105 -	track the changes required to modify the tree from <quote>tree
  33.106 -	  with one patch applied</quote> to <quote>tree with two
  33.107 -	  patches applied</quote>.</para>
  33.108 -
  33.109 -      <para>You can <emphasis>change</emphasis> which patches are
  33.110 -	applied to the tree.  If you <quote>pop</quote> a patch, the
  33.111 -	changes made by that patch will vanish from the directory
  33.112 -	tree.  Quilt remembers which patches you have popped, though,
  33.113 -	so you can <quote>push</quote> a popped patch again, and the
  33.114 -	directory tree will be restored to contain the modifications
  33.115 -	in the patch.  Most importantly, you can run the
  33.116 -	<quote>refresh</quote> command at any time, and the topmost
  33.117 -	applied patch will be updated.  This means that you can, at
  33.118 -	any time, change both which patches are applied and what
  33.119 -	modifications those patches make.</para>
  33.120 -
  33.121 -      <para>Quilt knows nothing about revision control tools, so it
  33.122 -	works equally well on top of an unpacked tarball or a
  33.123 -	Subversion working copy.</para>
  33.124 -
  33.125 -    </sect2>
  33.126 -    <sect2 id="sec.mq.quilt-mq">
  33.127 -      <title>From patchwork quilt to Mercurial Queues</title>
  33.128 -
  33.129 -      <para>In mid-2005, Chris Mason took the features of quilt and
  33.130 -	wrote an extension that he called Mercurial Queues, which
  33.131 -	added quilt-like behaviour to Mercurial.</para>
  33.132 -
  33.133 -      <para>The key difference between quilt and MQ is that quilt
  33.134 -	knows nothing about revision control systems, while MQ is
  33.135 -	<emphasis>integrated</emphasis> into Mercurial.  Each patch
  33.136 -	that you push is represented as a Mercurial changeset.  Pop a
  33.137 -	patch, and the changeset goes away.</para>
  33.138 -
  33.139 -      <para>Because quilt does not care about revision control tools,
  33.140 -	it is still a tremendously useful piece of software to know
  33.141 -	about for situations where you cannot use Mercurial and
  33.142 -	MQ.</para>
  33.143 -
  33.144 -    </sect2>
  33.145 -  </sect1>
  33.146 -  <sect1>
  33.147 -    <title>The huge advantage of MQ</title>
  33.148 -
  33.149 -    <para>I cannot overstate the value that MQ offers through the
  33.150 -      unification of patches and revision control.</para>
  33.151 -
  33.152 -    <para>A major reason that patches have persisted in the free
  33.153 -      software and open source world&emdash;in spite of the
  33.154 -      availability of increasingly capable revision control tools over
  33.155 -      the years&emdash;is the <emphasis>agility</emphasis> they
  33.156 -      offer.</para>
  33.157 -
  33.158 -    <para>Traditional revision control tools make a permanent,
  33.159 -      irreversible record of everything that you do.  While this has
  33.160 -      great value, it's also somewhat stifling.  If you want to
  33.161 -      perform a wild-eyed experiment, you have to be careful in how
  33.162 -      you go about it, or you risk leaving unneeded&emdash;or worse,
  33.163 -      misleading or destabilising&emdash;traces of your missteps and
  33.164 -      errors in the permanent revision record.</para>
  33.165 -
  33.166 -    <para>By contrast, MQ's marriage of distributed revision control
  33.167 -      with patches makes it much easier to isolate your work.  Your
  33.168 -      patches live on top of normal revision history, and you can make
  33.169 -      them disappear or reappear at will.  If you don't like a patch,
  33.170 -      you can drop it.  If a patch isn't quite as you want it to be,
  33.171 -      simply fix it&emdash;as many times as you need to, until you
  33.172 -      have refined it into the form you desire.</para>
  33.173 -
  33.174 -    <para>As an example, the integration of patches with revision
  33.175 -      control makes understanding patches and debugging their
  33.176 -      effects&emdash;and their interplay with the code they're based
  33.177 -      on&emdash;<emphasis>enormously</emphasis> easier. Since every
  33.178 -      applied patch has an associated changeset, you can give <command
  33.179 -	role="hg-cmd">hg log</command> a file name to see which
  33.180 -      changesets and patches affected the file.  You can use the
  33.181 -      <command role="hg-cmd">hg bisect</command> command to
  33.182 -      binary-search through all changesets and applied patches to see
  33.183 -      where a bug got introduced or fixed.  You can use the <command
  33.184 -	role="hg-cmd">hg annotate</command> command to see which
  33.185 -      changeset or patch modified a particular line of a source file.
  33.186 -      And so on.</para>
  33.187 -
  33.188 -  </sect1>
  33.189 -  <sect1 id="sec.mq.patch">
  33.190 -    <title>Understanding patches</title>
  33.191 -
  33.192 -    <para>Because MQ doesn't hide its patch-oriented nature, it is
  33.193 -      helpful to understand what patches are, and a little about the
  33.194 -      tools that work with them.</para>
  33.195 -
  33.196 -    <para>The traditional Unix <command>diff</command> command
  33.197 -      compares two files, and prints a list of differences between
  33.198 -      them. The <command>patch</command> command understands these
  33.199 -      differences as <emphasis>modifications</emphasis> to make to a
  33.200 -      file.  Take a look below for a simple example of these commands
  33.201 -      in action.</para>
  33.202 -
  33.203 -&interaction.mq.dodiff.diff;
  33.204 -
  33.205 -    <para>The type of file that <command>diff</command> generates (and
  33.206 -      <command>patch</command> takes as input) is called a
  33.207 -      <quote>patch</quote> or a <quote>diff</quote>; there is no
  33.208 -      difference between a patch and a diff.  (We'll use the term
  33.209 -      <quote>patch</quote>, since it's more commonly used.)</para>
  33.210 -
  33.211 -    <para>A patch file can start with arbitrary text; the
  33.212 -      <command>patch</command> command ignores this text, but MQ uses
  33.213 -      it as the commit message when creating changesets.  To find the
  33.214 -      beginning of the patch content, <command>patch</command>
  33.215 -      searches for the first line that starts with the string
  33.216 -      <quote><literal>diff -</literal></quote>.</para>
  33.217 -
  33.218 -    <para>MQ works with <emphasis>unified</emphasis> diffs
  33.219 -      (<command>patch</command> can accept several other diff formats,
  33.220 -      but MQ doesn't).  A unified diff contains two kinds of header.
  33.221 -      The <emphasis>file header</emphasis> describes the file being
  33.222 -      modified; it contains the name of the file to modify.  When
  33.223 -      <command>patch</command> sees a new file header, it looks for a
  33.224 -      file with that name to start modifying.</para>
  33.225 -
  33.226 -    <para>After the file header comes a series of
  33.227 -      <emphasis>hunks</emphasis>.  Each hunk starts with a header;
  33.228 -      this identifies the range of line numbers within the file that
  33.229 -      the hunk should modify.  Following the header, a hunk starts and
  33.230 -      ends with a few (usually three) lines of text from the
  33.231 -      unmodified file; these are called the
  33.232 -      <emphasis>context</emphasis> for the hunk.  If there's only a
  33.233 -      small amount of context between successive hunks,
  33.234 -      <command>diff</command> doesn't print a new hunk header; it just
  33.235 -      runs the hunks together, with a few lines of context between
  33.236 -      modifications.</para>
  33.237 -
  33.238 -    <para>Each line of context begins with a space character.  Within
  33.239 -      the hunk, a line that begins with
  33.240 -      <quote><literal>-</literal></quote> means <quote>remove this
  33.241 -	line,</quote> while a line that begins with
  33.242 -      <quote><literal>+</literal></quote> means <quote>insert this
  33.243 -	line.</quote>  For example, a line that is modified is
  33.244 -      represented by one deletion and one insertion.</para>
  33.245 -
  33.246 -    <para>We will return to some of the more subtle aspects of patches
  33.247 -      later (in section <xref linkend="sec.mq.adv-patch"/>), but you
  33.248 -      should have
  33.249 -      enough information now to use MQ.</para>
  33.250 -
  33.251 -  </sect1>
  33.252 -  <sect1 id="sec.mq.start">
  33.253 -    <title>Getting started with Mercurial Queues</title>
  33.254 -
  33.255 -    <para>Because MQ is implemented as an extension, you must
  33.256 -      explicitly enable before you can use it.  (You don't need to
  33.257 -      download anything; MQ ships with the standard Mercurial
  33.258 -      distribution.)  To enable MQ, edit your <filename
  33.259 -	role="home">~/.hgrc</filename> file, and add the lines
  33.260 -      below.</para>
  33.261 -
  33.262 -    <programlisting>[extensions]
  33.263 -hgext.mq =</programlisting>
  33.264 -
  33.265 -    <para>Once the extension is enabled, it will make a number of new
  33.266 -      commands available.  To verify that the extension is working,
  33.267 -      you can use <command role="hg-cmd">hg help</command> to see if
  33.268 -      the <command role="hg-ext-mq">qinit</command> command is now
  33.269 -      available.</para>
  33.270 -
  33.271 -&interaction.mq.qinit-help.help;
  33.272 -
  33.273 -    <para>You can use MQ with <emphasis>any</emphasis> Mercurial
  33.274 -      repository, and its commands only operate within that
  33.275 -      repository.  To get started, simply prepare the repository using
  33.276 -      the <command role="hg-ext-mq">qinit</command> command.</para>
  33.277 -
  33.278 -&interaction.mq.tutorial.qinit;
  33.279 -
  33.280 -    <para>This command creates an empty directory called <filename
  33.281 -	role="special" class="directory">.hg/patches</filename>, where
  33.282 -      MQ will keep its metadata.  As with many Mercurial commands, the
  33.283 -      <command role="hg-ext-mq">qinit</command> command prints nothing
  33.284 -      if it succeeds.</para>
  33.285 -
  33.286 -    <sect2>
  33.287 -      <title>Creating a new patch</title>
  33.288 -
  33.289 -      <para>To begin work on a new patch, use the <command
  33.290 -	  role="hg-ext-mq">qnew</command> command.  This command takes
  33.291 -	one argument, the name of the patch to create.</para>
  33.292 -
  33.293 -      <para>MQ will use this as the name of an actual file in the
  33.294 -	<filename role="special"
  33.295 -	  class="directory">.hg/patches</filename> directory, as you
  33.296 -	can see below.</para>
  33.297 -
  33.298 -&interaction.mq.tutorial.qnew;
  33.299 -
  33.300 -      <para>Also newly present in the <filename role="special"
  33.301 -	  class="directory">.hg/patches</filename> directory are two
  33.302 -	other files, <filename role="special">series</filename> and
  33.303 -	<filename role="special">status</filename>.  The <filename
  33.304 -	  role="special">series</filename> file lists all of the
  33.305 -	patches that MQ knows about for this repository, with one
  33.306 -	patch per line.  Mercurial uses the <filename
  33.307 -	  role="special">status</filename> file for internal
  33.308 -	book-keeping; it tracks all of the patches that MQ has
  33.309 -	<emphasis>applied</emphasis> in this repository.</para>
  33.310 -
  33.311 -      <note>
  33.312 -	<para>  You may sometimes want to edit the <filename
  33.313 -	    role="special">series</filename> file by hand; for
  33.314 -	  example, to change the sequence in which some patches are
  33.315 -	  applied.  However, manually editing the <filename
  33.316 -	    role="special">status</filename> file is almost always a
  33.317 -	  bad idea, as it's easy to corrupt MQ's idea of what is
  33.318 -	  happening.</para>
  33.319 -      </note>
  33.320 -
  33.321 -      <para>Once you have created your new patch, you can edit files
  33.322 -	in the working directory as you usually would.  All of the
  33.323 -	normal Mercurial commands, such as <command role="hg-cmd">hg
  33.324 -	  diff</command> and <command role="hg-cmd">hg
  33.325 -	  annotate</command>, work exactly as they did before.</para>
  33.326 -
  33.327 -    </sect2>
  33.328 -    <sect2>
  33.329 -      <title>Refreshing a patch</title>
  33.330 -
  33.331 -      <para>When you reach a point where you want to save your work,
  33.332 -	use the <command role="hg-ext-mq">qrefresh</command> command
  33.333 -	to update the patch you are working on.</para>
  33.334 -
  33.335 -&interaction.mq.tutorial.qrefresh;
  33.336 -
  33.337 -      <para>This command folds the changes you have made in the
  33.338 -	working directory into your patch, and updates its
  33.339 -	corresponding changeset to contain those changes.</para>
  33.340 -
  33.341 -      <para>You can run <command role="hg-ext-mq">qrefresh</command>
  33.342 -	as often as you like, so it's a good way to
  33.343 -	<quote>checkpoint</quote> your work.  Refresh your patch at an
  33.344 -	opportune time; try an experiment; and if the experiment
  33.345 -	doesn't work out, <command role="hg-cmd">hg revert</command>
  33.346 -	your modifications back to the last time you refreshed.</para>
  33.347 -
  33.348 -&interaction.mq.tutorial.qrefresh2;
  33.349 -
  33.350 -    </sect2>
  33.351 -    <sect2>
  33.352 -      <title>Stacking and tracking patches</title>
  33.353 -
  33.354 -      <para>Once you have finished working on a patch, or need to work
  33.355 -	on another, you can use the <command
  33.356 -	  role="hg-ext-mq">qnew</command> command again to create a
  33.357 -	new patch. Mercurial will apply this patch on top of your
  33.358 -	existing patch.</para>
  33.359 -
  33.360 -&interaction.mq.tutorial.qnew2;
  33.361 -      <para>Notice that the patch contains the changes in our prior
  33.362 -	patch as part of its context (you can see this more clearly in
  33.363 -	the output of <command role="hg-cmd">hg
  33.364 -	  annotate</command>).</para>
  33.365 -
  33.366 -      <para>So far, with the exception of <command
  33.367 -	  role="hg-ext-mq">qnew</command> and <command
  33.368 -	  role="hg-ext-mq">qrefresh</command>, we've been careful to
  33.369 -	only use regular Mercurial commands.  However, MQ provides
  33.370 -	many commands that are easier to use when you are thinking
  33.371 -	about patches, as illustrated below.</para>
  33.372 -
  33.373 -&interaction.mq.tutorial.qseries;
  33.374 -
  33.375 -      <itemizedlist>
  33.376 -	<listitem><para>The <command
  33.377 -	      role="hg-ext-mq">qseries</command> command lists every
  33.378 -	    patch that MQ knows about in this repository, from oldest
  33.379 -	    to newest (most recently
  33.380 -	    <emphasis>created</emphasis>).</para>
  33.381 -	</listitem>
  33.382 -	<listitem><para>The <command
  33.383 -	      role="hg-ext-mq">qapplied</command> command lists every
  33.384 -	    patch that MQ has <emphasis>applied</emphasis> in this
  33.385 -	    repository, again from oldest to newest (most recently
  33.386 -	    applied).</para>
  33.387 -	</listitem></itemizedlist>
  33.388 -
  33.389 -    </sect2>
  33.390 -    <sect2>
  33.391 -      <title>Manipulating the patch stack</title>
  33.392 -
  33.393 -      <para>The previous discussion implied that there must be a
  33.394 -	difference between <quote>known</quote> and
  33.395 -	<quote>applied</quote> patches, and there is.  MQ can manage a
  33.396 -	patch without it being applied in the repository.</para>
  33.397 -
  33.398 -      <para>An <emphasis>applied</emphasis> patch has a corresponding
  33.399 -	changeset in the repository, and the effects of the patch and
  33.400 -	changeset are visible in the working directory.  You can undo
  33.401 -	the application of a patch using the <command
  33.402 -	  role="hg-ext-mq">qpop</command> command.  MQ still
  33.403 -	<emphasis>knows about</emphasis>, or manages, a popped patch,
  33.404 -	but the patch no longer has a corresponding changeset in the
  33.405 -	repository, and the working directory does not contain the
  33.406 -	changes made by the patch.  Figure <xref
  33.407 -	  endterm="fig.mq.stack.caption" linkend="fig.mq.stack"/> illustrates
  33.408 -	the difference between applied and tracked patches.</para>
  33.409 -
  33.410 -      <informalfigure id="fig.mq.stack">
  33.411 -        <mediaobject>
  33.412 -          <imageobject><imagedata fileref="images/mq-stack.png"/></imageobject>
  33.413 -          <textobject><phrase>XXX add text</phrase></textobject>
  33.414 -          <caption><para id="fig.mq.stack.caption">Applied and unapplied patches
  33.415 -            in the MQ patch stack</para></caption>
  33.416 -          </mediaobject>
  33.417 -      </informalfigure>
  33.418 -
  33.419 -      <para>You can reapply an unapplied, or popped, patch using the
  33.420 -	<command role="hg-ext-mq">qpush</command> command.  This
  33.421 -	creates a new changeset to correspond to the patch, and the
  33.422 -	patch's changes once again become present in the working
  33.423 -	directory.  See below for examples of <command
  33.424 -	  role="hg-ext-mq">qpop</command> and <command
  33.425 -	  role="hg-ext-mq">qpush</command> in action.</para>
  33.426 -&interaction.mq.tutorial.qpop;
  33.427 -
  33.428 -      <para>Notice that once we have popped a patch or two patches,
  33.429 -	the output of <command role="hg-ext-mq">qseries</command>
  33.430 -	remains the same, while that of <command
  33.431 -	  role="hg-ext-mq">qapplied</command> has changed.</para>
  33.432 -
  33.433 -
  33.434 -    </sect2>
  33.435 -    <sect2>
  33.436 -      <title>Pushing and popping many patches</title>
  33.437 -
  33.438 -      <para>While <command role="hg-ext-mq">qpush</command> and
  33.439 -	<command role="hg-ext-mq">qpop</command> each operate on a
  33.440 -	single patch at a time by default, you can push and pop many
  33.441 -	patches in one go.  The <option
  33.442 -	  role="hg-ext-mq-cmd-qpush-opt">hg -a</option> option to
  33.443 -	<command role="hg-ext-mq">qpush</command> causes it to push
  33.444 -	all unapplied patches, while the <option
  33.445 -	  role="hg-ext-mq-cmd-qpop-opt">-a</option> option to <command
  33.446 -	  role="hg-ext-mq">qpop</command> causes it to pop all applied
  33.447 -	patches.  (For some more ways to push and pop many patches,
  33.448 -	see section <xref linkend="sec.mq.perf"/>
  33.449 -	below.)</para>
  33.450 -
  33.451 -&interaction.mq.tutorial.qpush-a;
  33.452 -
  33.453 -    </sect2>
  33.454 -    <sect2>
  33.455 -      <title>Safety checks, and overriding them</title>
  33.456 -
  33.457 -      <para>Several MQ commands check the working directory before
  33.458 -	they do anything, and fail if they find any modifications.
  33.459 -	They do this to ensure that you won't lose any changes that
  33.460 -	you have made, but not yet incorporated into a patch.  The
  33.461 -	example below illustrates this; the <command
  33.462 -	  role="hg-ext-mq">qnew</command> command will not create a
  33.463 -	new patch if there are outstanding changes, caused in this
  33.464 -	case by the <command role="hg-cmd">hg add</command> of
  33.465 -	<filename>file3</filename>.</para>
  33.466 -
  33.467 -&interaction.mq.tutorial.add;
  33.468 -
  33.469 -      <para>Commands that check the working directory all take an
  33.470 -	<quote>I know what I'm doing</quote> option, which is always
  33.471 -	named <option>-f</option>.  The exact meaning of
  33.472 -	<option>-f</option> depends on the command.  For example,
  33.473 -	<command role="hg-cmd">hg qnew <option
  33.474 -	    role="hg-ext-mq-cmd-qnew-opt">hg -f</option></command>
  33.475 -	will incorporate any outstanding changes into the new patch it
  33.476 -	creates, but <command role="hg-cmd">hg qpop <option
  33.477 -	    role="hg-ext-mq-cmd-qpop-opt">hg -f</option></command>
  33.478 -	will revert modifications to any files affected by the patch
  33.479 -	that it is popping.  Be sure to read the documentation for a
  33.480 -	command's <option>-f</option> option before you use it!</para>
  33.481 -
  33.482 -    </sect2>
  33.483 -    <sect2>
  33.484 -      <title>Working on several patches at once</title>
  33.485 -
  33.486 -      <para>The <command role="hg-ext-mq">qrefresh</command> command
  33.487 -	always refreshes the <emphasis>topmost</emphasis> applied
  33.488 -	patch.  This means that you can suspend work on one patch (by
  33.489 -	refreshing it), pop or push to make a different patch the top,
  33.490 -	and work on <emphasis>that</emphasis> patch for a
  33.491 -	while.</para>
  33.492 -
  33.493 -      <para>Here's an example that illustrates how you can use this
  33.494 -	ability. Let's say you're developing a new feature as two
  33.495 -	patches.  The first is a change to the core of your software,
  33.496 -	and the second&emdash;layered on top of the
  33.497 -	first&emdash;changes the user interface to use the code you
  33.498 -	just added to the core.  If you notice a bug in the core while
  33.499 -	you're working on the UI patch, it's easy to fix the core.
  33.500 -	Simply <command role="hg-ext-mq">qrefresh</command> the UI
  33.501 -	patch to save your in-progress changes, and <command
  33.502 -	  role="hg-ext-mq">qpop</command> down to the core patch.  Fix
  33.503 -	the core bug, <command role="hg-ext-mq">qrefresh</command> the
  33.504 -	core patch, and <command role="hg-ext-mq">qpush</command> back
  33.505 -	to the UI patch to continue where you left off.</para>
  33.506 -
  33.507 -    </sect2>
  33.508 -  </sect1>
  33.509 -  <sect1 id="sec.mq.adv-patch">
  33.510 -    <title>More about patches</title>
  33.511 -
  33.512 -    <para>MQ uses the GNU <command>patch</command> command to apply
  33.513 -      patches, so it's helpful to know a few more detailed aspects of
  33.514 -      how <command>patch</command> works, and about patches
  33.515 -      themselves.</para>
  33.516 -
  33.517 -    <sect2>
  33.518 -      <title>The strip count</title>
  33.519 -
  33.520 -      <para>If you look at the file headers in a patch, you will
  33.521 -	notice that the pathnames usually have an extra component on
  33.522 -	the front that isn't present in the actual path name.  This is
  33.523 -	a holdover from the way that people used to generate patches
  33.524 -	(people still do this, but it's somewhat rare with modern
  33.525 -	revision control tools).</para>
  33.526 -
  33.527 -      <para>Alice would unpack a tarball, edit her files, then decide
  33.528 -	that she wanted to create a patch.  So she'd rename her
  33.529 -	working directory, unpack the tarball again (hence the need
  33.530 -	for the rename), and use the <option
  33.531 -	  role="cmd-opt-diff">-r</option> and <option
  33.532 -	  role="cmd-opt-diff">-N</option> options to
  33.533 -	<command>diff</command> to recursively generate a patch
  33.534 -	between the unmodified directory and the modified one.  The
  33.535 -	result would be that the name of the unmodified directory
  33.536 -	would be at the front of the left-hand path in every file
  33.537 -	header, and the name of the modified directory would be at the
  33.538 -	front of the right-hand path.</para>
  33.539 -
  33.540 -      <para>Since someone receiving a patch from the Alices of the net
  33.541 -	would be unlikely to have unmodified and modified directories
  33.542 -	with exactly the same names, the <command>patch</command>
  33.543 -	command has a <option role="cmd-opt-patch">-p</option> option
  33.544 -	that indicates the number of leading path name components to
  33.545 -	strip when trying to apply a patch.  This number is called the
  33.546 -	<emphasis>strip count</emphasis>.</para>
  33.547 -
  33.548 -      <para>An option of <quote><literal>-p1</literal></quote> means
  33.549 -	<quote>use a strip count of one</quote>.  If
  33.550 -	<command>patch</command> sees a file name
  33.551 -	<filename>foo/bar/baz</filename> in a file header, it will
  33.552 -	strip <filename>foo</filename> and try to patch a file named
  33.553 -	<filename>bar/baz</filename>.  (Strictly speaking, the strip
  33.554 -	count refers to the number of <emphasis>path
  33.555 -	  separators</emphasis> (and the components that go with them
  33.556 -	) to strip.  A strip count of one will turn
  33.557 -	<filename>foo/bar</filename> into <filename>bar</filename>,
  33.558 -	but <filename>/foo/bar</filename> (notice the extra leading
  33.559 -	slash) into <filename>foo/bar</filename>.)</para>
  33.560 -
  33.561 -      <para>The <quote>standard</quote> strip count for patches is
  33.562 -	one; almost all patches contain one leading path name
  33.563 -	component that needs to be stripped. Mercurial's <command
  33.564 -	  role="hg-cmd">hg diff</command> command generates path names
  33.565 -	in this form, and the <command role="hg-cmd">hg
  33.566 -	  import</command> command and MQ expect patches to have a
  33.567 -	strip count of one.</para>
  33.568 -
  33.569 -      <para>If you receive a patch from someone that you want to add
  33.570 -	to your patch queue, and the patch needs a strip count other
  33.571 -	than one, you cannot just <command
  33.572 -	  role="hg-ext-mq">qimport</command> the patch, because
  33.573 -	<command role="hg-ext-mq">qimport</command> does not yet have
  33.574 -	a <literal>-p</literal> option (see <ulink role="hg-bug"
  33.575 -	  url="http://www.selenic.com/mercurial/bts/issue311">issue
  33.576 -	  311</ulink>).  Your best bet is to <command
  33.577 -	  role="hg-ext-mq">qnew</command> a patch of your own, then
  33.578 -	use <command>patch -pN</command> to apply their patch,
  33.579 -	followed by <command role="hg-cmd">hg addremove</command> to
  33.580 -	pick up any files added or removed by the patch, followed by
  33.581 -	<command role="hg-ext-mq">hg qrefresh</command>. This
  33.582 -	complexity may become unnecessary; see <ulink role="hg-bug"
  33.583 -	  url="http://www.selenic.com/mercurial/bts/issue311">issue
  33.584 -	  311</ulink> for details.
  33.585 -      </para>
  33.586 -    </sect2>
  33.587 -    <sect2>
  33.588 -      <title>Strategies for applying a patch</title>
  33.589 -
  33.590 -      <para>When <command>patch</command> applies a hunk, it tries a
  33.591 -	handful of successively less accurate strategies to try to
  33.592 -	make the hunk apply. This falling-back technique often makes
  33.593 -	it possible to take a patch that was generated against an old
  33.594 -	version of a file, and apply it against a newer version of
  33.595 -	that file.</para>
  33.596 -
  33.597 -      <para>First, <command>patch</command> tries an exact match,
  33.598 -	where the line numbers, the context, and the text to be
  33.599 -	modified must apply exactly.  If it cannot make an exact
  33.600 -	match, it tries to find an exact match for the context,
  33.601 -	without honouring the line numbering information.  If this
  33.602 -	succeeds, it prints a line of output saying that the hunk was
  33.603 -	applied, but at some <emphasis>offset</emphasis> from the
  33.604 -	original line number.</para>
  33.605 -
  33.606 -      <para>If a context-only match fails, <command>patch</command>
  33.607 -	removes the first and last lines of the context, and tries a
  33.608 -	<emphasis>reduced</emphasis> context-only match.  If the hunk
  33.609 -	with reduced context succeeds, it prints a message saying that
  33.610 -	it applied the hunk with a <emphasis>fuzz factor</emphasis>
  33.611 -	(the number after the fuzz factor indicates how many lines of
  33.612 -	context <command>patch</command> had to trim before the patch
  33.613 -	applied).</para>
  33.614 -
  33.615 -      <para>When neither of these techniques works,
  33.616 -	<command>patch</command> prints a message saying that the hunk
  33.617 -	in question was rejected.  It saves rejected hunks (also
  33.618 -	simply called <quote>rejects</quote>) to a file with the same
  33.619 -	name, and an added <filename role="special">.rej</filename>
  33.620 -	extension.  It also saves an unmodified copy of the file with
  33.621 -	a <filename role="special">.orig</filename> extension; the
  33.622 -	copy of the file without any extensions will contain any
  33.623 -	changes made by hunks that <emphasis>did</emphasis> apply
  33.624 -	cleanly.  If you have a patch that modifies
  33.625 -	<filename>foo</filename> with six hunks, and one of them fails
  33.626 -	to apply, you will have: an unmodified
  33.627 -	<filename>foo.orig</filename>, a <filename>foo.rej</filename>
  33.628 -	containing one hunk, and <filename>foo</filename>, containing
  33.629 -	the changes made by the five successful hunks.</para>
  33.630 -
  33.631 -    </sect2>
  33.632 -    <sect2>
  33.633 -      <title>Some quirks of patch representation</title>
  33.634 -
  33.635 -      <para>There are a few useful things to know about how
  33.636 -	<command>patch</command> works with files.</para>
  33.637 -      <itemizedlist>
  33.638 -	<listitem><para>This should already be obvious, but
  33.639 -	    <command>patch</command> cannot handle binary
  33.640 -	    files.</para>
  33.641 -	</listitem>
  33.642 -	<listitem><para>Neither does it care about the executable bit;
  33.643 -	    it creates new files as readable, but not
  33.644 -	    executable.</para>
  33.645 -	</listitem>
  33.646 -	<listitem><para><command>patch</command> treats the removal of
  33.647 -	    a file as a diff between the file to be removed and the
  33.648 -	    empty file.  So your idea of <quote>I deleted this
  33.649 -	      file</quote> looks like <quote>every line of this file
  33.650 -	      was deleted</quote> in a patch.</para>
  33.651 -	</listitem>
  33.652 -	<listitem><para>It treats the addition of a file as a diff
  33.653 -	    between the empty file and the file to be added.  So in a
  33.654 -	    patch, your idea of <quote>I added this file</quote> looks
  33.655 -	    like <quote>every line of this file was
  33.656 -	      added</quote>.</para>
  33.657 -	</listitem>
  33.658 -	<listitem><para>It treats a renamed file as the removal of the
  33.659 -	    old name, and the addition of the new name.  This means
  33.660 -	    that renamed files have a big footprint in patches.  (Note
  33.661 -	    also that Mercurial does not currently try to infer when
  33.662 -	    files have been renamed or copied in a patch.)</para>
  33.663 -	</listitem>
  33.664 -	<listitem><para><command>patch</command> cannot represent
  33.665 -	    empty files, so you cannot use a patch to represent the
  33.666 -	    notion <quote>I added this empty file to the
  33.667 -	      tree</quote>.</para>
  33.668 -	</listitem></itemizedlist>
  33.669 -    </sect2>
  33.670 -    <sect2>
  33.671 -      <title>Beware the fuzz</title>
  33.672 -
  33.673 -      <para>While applying a hunk at an offset, or with a fuzz factor,
  33.674 -	will often be completely successful, these inexact techniques
  33.675 -	naturally leave open the possibility of corrupting the patched
  33.676 -	file.  The most common cases typically involve applying a
  33.677 -	patch twice, or at an incorrect location in the file.  If
  33.678 -	<command>patch</command> or <command
  33.679 -	  role="hg-ext-mq">qpush</command> ever mentions an offset or
  33.680 -	fuzz factor, you should make sure that the modified files are
  33.681 -	correct afterwards.</para>
  33.682 -
  33.683 -      <para>It's often a good idea to refresh a patch that has applied
  33.684 -	with an offset or fuzz factor; refreshing the patch generates
  33.685 -	new context information that will make it apply cleanly.  I
  33.686 -	say <quote>often,</quote> not <quote>always,</quote> because
  33.687 -	sometimes refreshing a patch will make it fail to apply
  33.688 -	against a different revision of the underlying files.  In some
  33.689 -	cases, such as when you're maintaining a patch that must sit
  33.690 -	on top of multiple versions of a source tree, it's acceptable
  33.691 -	to have a patch apply with some fuzz, provided you've verified
  33.692 -	the results of the patching process in such cases.</para>
  33.693 -
  33.694 -    </sect2>
  33.695 -    <sect2>
  33.696 -      <title>Handling rejection</title>
  33.697 -
  33.698 -      <para>If <command role="hg-ext-mq">qpush</command> fails to
  33.699 -	apply a patch, it will print an error message and exit.  If it
  33.700 -	has left <filename role="special">.rej</filename> files
  33.701 -	behind, it is usually best to fix up the rejected hunks before
  33.702 -	you push more patches or do any further work.</para>
  33.703 -
  33.704 -      <para>If your patch <emphasis>used to</emphasis> apply cleanly,
  33.705 -	and no longer does because you've changed the underlying code
  33.706 -	that your patches are based on, Mercurial Queues can help; see
  33.707 -	section <xref
  33.708 -	  linkend="sec.mq.merge"/> for details.</para>
  33.709 -
  33.710 -      <para>Unfortunately, there aren't any great techniques for
  33.711 -	dealing with rejected hunks.  Most often, you'll need to view
  33.712 -	the <filename role="special">.rej</filename> file and edit the
  33.713 -	target file, applying the rejected hunks by hand.</para>
  33.714 -
  33.715 -      <para>If you're feeling adventurous, Neil Brown, a Linux kernel
  33.716 -	hacker, wrote a tool called <command>wiggle</command>
  33.717 -	<citation>web:wiggle</citation>, which is more vigorous than
  33.718 -	<command>patch</command> in its attempts to make a patch
  33.719 -	apply.</para>
  33.720 -
  33.721 -      <para>Another Linux kernel hacker, Chris Mason (the author of
  33.722 -	Mercurial Queues), wrote a similar tool called
  33.723 -	<command>mpatch</command> <citation>web:mpatch</citation>,
  33.724 -	which takes a simple approach to automating the application of
  33.725 -	hunks rejected by <command>patch</command>.  The
  33.726 -	<command>mpatch</command> command can help with four common
  33.727 -	reasons that a hunk may be rejected:</para>
  33.728 -
  33.729 -      <itemizedlist>
  33.730 -	<listitem><para>The context in the middle of a hunk has
  33.731 -	    changed.</para>
  33.732 -	</listitem>
  33.733 -	<listitem><para>A hunk is missing some context at the
  33.734 -	    beginning or end.</para>
  33.735 -	</listitem>
  33.736 -	<listitem><para>A large hunk might apply better&emdash;either
  33.737 -	    entirely or in part&emdash;if it was broken up into
  33.738 -	    smaller hunks.</para>
  33.739 -	</listitem>
  33.740 -	<listitem><para>A hunk removes lines with slightly different
  33.741 -	    content than those currently present in the file.</para>
  33.742 -	</listitem></itemizedlist>
  33.743 -
  33.744 -      <para>If you use <command>wiggle</command> or
  33.745 -	<command>mpatch</command>, you should be doubly careful to
  33.746 -	check your results when you're done.  In fact,
  33.747 -	<command>mpatch</command> enforces this method of
  33.748 -	double-checking the tool's output, by automatically dropping
  33.749 -	you into a merge program when it has done its job, so that you
  33.750 -	can verify its work and finish off any remaining
  33.751 -	merges.</para>
  33.752 -
  33.753 -    </sect2>
  33.754 -  </sect1>
  33.755 -  <sect1 id="sec.mq.perf">
  33.756 -    <title>Getting the best performance out of MQ</title>
  33.757 -
  33.758 -    <para>MQ is very efficient at handling a large number of patches.
  33.759 -      I ran some performance experiments in mid-2006 for a talk that I
  33.760 -      gave at the 2006 EuroPython conference
  33.761 -      <citation>web:europython</citation>.  I used as my data set the
  33.762 -      Linux 2.6.17-mm1 patch series, which consists of 1,738 patches.
  33.763 -      I applied these on top of a Linux kernel repository containing
  33.764 -      all 27,472 revisions between Linux 2.6.12-rc2 and Linux
  33.765 -      2.6.17.</para>
  33.766 -
  33.767 -    <para>On my old, slow laptop, I was able to <command
  33.768 -	role="hg-cmd">hg qpush <option
  33.769 -	  role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> all
  33.770 -      1,738 patches in 3.5 minutes, and <command role="hg-cmd">hg qpop
  33.771 -	<option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command>
  33.772 -      them all in 30 seconds.  (On a newer laptop, the time to push
  33.773 -      all patches dropped to two minutes.)  I could <command
  33.774 -	role="hg-ext-mq">qrefresh</command> one of the biggest patches
  33.775 -      (which made 22,779 lines of changes to 287 files) in 6.6
  33.776 -      seconds.</para>
  33.777 -
  33.778 -    <para>Clearly, MQ is well suited to working in large trees, but
  33.779 -      there are a few tricks you can use to get the best performance
  33.780 -      of it.</para>
  33.781 -
  33.782 -    <para>First of all, try to <quote>batch</quote> operations
  33.783 -      together.  Every time you run <command
  33.784 -	role="hg-ext-mq">qpush</command> or <command
  33.785 -	role="hg-ext-mq">qpop</command>, these commands scan the
  33.786 -      working directory once to make sure you haven't made some
  33.787 -      changes and then forgotten to run <command
  33.788 -	role="hg-ext-mq">qrefresh</command>.  On a small tree, the
  33.789 -      time that this scan takes is unnoticeable.  However, on a
  33.790 -      medium-sized tree (containing tens of thousands of files), it
  33.791 -      can take a second or more.</para>
  33.792 -
  33.793 -    <para>The <command role="hg-ext-mq">qpush</command> and <command
  33.794 -	role="hg-ext-mq">qpop</command> commands allow you to push and
  33.795 -      pop multiple patches at a time.  You can identify the
  33.796 -      <quote>destination patch</quote> that you want to end up at.
  33.797 -      When you <command role="hg-ext-mq">qpush</command> with a
  33.798 -      destination specified, it will push patches until that patch is
  33.799 -      at the top of the applied stack.  When you <command
  33.800 -	role="hg-ext-mq">qpop</command> to a destination, MQ will pop
  33.801 -      patches until the destination patch is at the top.</para>
  33.802 -
  33.803 -    <para>You can identify a destination patch using either the name
  33.804 -      of the patch, or by number.  If you use numeric addressing,
  33.805 -      patches are counted from zero; this means that the first patch
  33.806 -      is zero, the second is one, and so on.</para>
  33.807 -
  33.808 -  </sect1>
  33.809 -  <sect1 id="sec.mq.merge">
  33.810 -    <title>Updating your patches when the underlying code
  33.811 -      changes</title>
  33.812 -
  33.813 -    <para>It's common to have a stack of patches on top of an
  33.814 -      underlying repository that you don't modify directly.  If you're
  33.815 -      working on changes to third-party code, or on a feature that is
  33.816 -      taking longer to develop than the rate of change of the code
  33.817 -      beneath, you will often need to sync up with the underlying
  33.818 -      code, and fix up any hunks in your patches that no longer apply.
  33.819 -      This is called <emphasis>rebasing</emphasis> your patch
  33.820 -      series.</para>
  33.821 -
  33.822 -    <para>The simplest way to do this is to <command role="hg-cmd">hg
  33.823 -	qpop <option role="hg-ext-mq-cmd-qpop-opt">hg
  33.824 -	  -a</option></command> your patches, then <command
  33.825 -	role="hg-cmd">hg pull</command> changes into the underlying
  33.826 -      repository, and finally <command role="hg-cmd">hg qpush <option
  33.827 -	  role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> your
  33.828 -      patches again.  MQ will stop pushing any time it runs across a
  33.829 -      patch that fails to apply during conflicts, allowing you to fix
  33.830 -      your conflicts, <command role="hg-ext-mq">qrefresh</command> the
  33.831 -      affected patch, and continue pushing until you have fixed your
  33.832 -      entire stack.</para>
  33.833 -
  33.834 -    <para>This approach is easy to use and works well if you don't
  33.835 -      expect changes to the underlying code to affect how well your
  33.836 -      patches apply. If your patch stack touches code that is modified
  33.837 -      frequently or invasively in the underlying repository, however,
  33.838 -      fixing up rejected hunks by hand quickly becomes
  33.839 -      tiresome.</para>
  33.840 -
  33.841 -    <para>It's possible to partially automate the rebasing process.
  33.842 -      If your patches apply cleanly against some revision of the
  33.843 -      underlying repo, MQ can use this information to help you to
  33.844 -      resolve conflicts between your patches and a different
  33.845 -      revision.</para>
  33.846 -
  33.847 -    <para>The process is a little involved.</para>
  33.848 -    <orderedlist>
  33.849 -      <listitem><para>To begin, <command role="hg-cmd">hg qpush
  33.850 -	    -a</command> all of your patches on top of the revision
  33.851 -	  where you know that they apply cleanly.</para>
  33.852 -      </listitem>
  33.853 -      <listitem><para>Save a backup copy of your patch directory using
  33.854 -	  <command role="hg-cmd">hg qsave <option
  33.855 -	      role="hg-ext-mq-cmd-qsave-opt">hg -e</option> <option
  33.856 -	      role="hg-ext-mq-cmd-qsave-opt">hg -c</option></command>.
  33.857 -	  This prints the name of the directory that it has saved the
  33.858 -	  patches in.  It will save the patches to a directory called
  33.859 -	  <filename role="special"
  33.860 -	    class="directory">.hg/patches.N</filename>, where
  33.861 -	  <literal>N</literal> is a small integer.  It also commits a
  33.862 -	  <quote>save changeset</quote> on top of your applied
  33.863 -	  patches; this is for internal book-keeping, and records the
  33.864 -	  states of the <filename role="special">series</filename> and
  33.865 -	  <filename role="special">status</filename> files.</para>
  33.866 -      </listitem>
  33.867 -      <listitem><para>Use <command role="hg-cmd">hg pull</command> to
  33.868 -	  bring new changes into the underlying repository.  (Don't
  33.869 -	  run <command role="hg-cmd">hg pull -u</command>; see below
  33.870 -	  for why.)</para>
  33.871 -      </listitem>
  33.872 -      <listitem><para>Update to the new tip revision, using <command
  33.873 -	    role="hg-cmd">hg update <option
  33.874 -	      role="hg-opt-update">-C</option></command> to override
  33.875 -	  the patches you have pushed.</para>
  33.876 -      </listitem>
  33.877 -      <listitem><para>Merge all patches using <command>hg qpush -m
  33.878 -	    -a</command>.  The <option
  33.879 -	    role="hg-ext-mq-cmd-qpush-opt">-m</option> option to
  33.880 -	  <command role="hg-ext-mq">qpush</command> tells MQ to
  33.881 -	  perform a three-way merge if the patch fails to
  33.882 -	  apply.</para>
  33.883 -      </listitem></orderedlist>
  33.884 -
  33.885 -    <para>During the <command role="hg-cmd">hg qpush <option
  33.886 -	  role="hg-ext-mq-cmd-qpush-opt">hg -m</option></command>,
  33.887 -      each patch in the <filename role="special">series</filename>
  33.888 -      file is applied normally.  If a patch applies with fuzz or
  33.889 -      rejects, MQ looks at the queue you <command
  33.890 -	role="hg-ext-mq">qsave</command>d, and performs a three-way
  33.891 -      merge with the corresponding changeset.  This merge uses
  33.892 -      Mercurial's normal merge machinery, so it may pop up a GUI merge
  33.893 -      tool to help you to resolve problems.</para>
  33.894 -
  33.895 -    <para>When you finish resolving the effects of a patch, MQ
  33.896 -      refreshes your patch based on the result of the merge.</para>
  33.897 -
  33.898 -    <para>At the end of this process, your repository will have one
  33.899 -      extra head from the old patch queue, and a copy of the old patch
  33.900 -      queue will be in <filename role="special"
  33.901 -	class="directory">.hg/patches.N</filename>. You can remove the
  33.902 -      extra head using <command role="hg-cmd">hg qpop -a -n
  33.903 -	patches.N</command> or <command role="hg-cmd">hg
  33.904 -	strip</command>.  You can delete <filename role="special"
  33.905 -	class="directory">.hg/patches.N</filename> once you are sure
  33.906 -      that you no longer need it as a backup.</para>
  33.907 -
  33.908 -  </sect1>
  33.909 -  <sect1>
  33.910 -    <title>Identifying patches</title>
  33.911 -
  33.912 -    <para>MQ commands that work with patches let you refer to a patch
  33.913 -      either by using its name or by a number.  By name is obvious
  33.914 -      enough; pass the name <filename>foo.patch</filename> to <command
  33.915 -	role="hg-ext-mq">qpush</command>, for example, and it will
  33.916 -      push patches until <filename>foo.patch</filename> is
  33.917 -      applied.</para>
  33.918 -
  33.919 -    <para>As a shortcut, you can refer to a patch using both a name
  33.920 -      and a numeric offset; <literal>foo.patch-2</literal> means
  33.921 -      <quote>two patches before <literal>foo.patch</literal></quote>,
  33.922 -      while <literal>bar.patch+4</literal> means <quote>four patches
  33.923 -	after <literal>bar.patch</literal></quote>.</para>
  33.924 -
  33.925 -    <para>Referring to a patch by index isn't much different.  The
  33.926 -      first patch printed in the output of <command
  33.927 -	role="hg-ext-mq">qseries</command> is patch zero (yes, it's
  33.928 -      one of those start-at-zero counting systems); the second is
  33.929 -      patch one; and so on.</para>
  33.930 -
  33.931 -    <para>MQ also makes it easy to work with patches when you are
  33.932 -      using normal Mercurial commands.  Every command that accepts a
  33.933 -      changeset ID will also accept the name of an applied patch.  MQ
  33.934 -      augments the tags normally in the repository with an eponymous
  33.935 -      one for each applied patch.  In addition, the special tags
  33.936 -      <literal role="tag">qbase</literal> and
  33.937 -      <literal role="tag">qtip</literal> identify
  33.938 -      the <quote>bottom-most</quote> and topmost applied patches,
  33.939 -      respectively.</para>
  33.940 -
  33.941 -    <para>These additions to Mercurial's normal tagging capabilities
  33.942 -      make dealing with patches even more of a breeze.</para>
  33.943 -    <itemizedlist>
  33.944 -      <listitem><para>Want to patchbomb a mailing list with your
  33.945 -	  latest series of changes?</para>
  33.946 -	<programlisting>hg email qbase:qtip</programlisting>
  33.947 -	<para>  (Don't know what <quote>patchbombing</quote> is?  See
  33.948 -	  section <xref linkend="sec.hgext.patchbomb"/>.)</para>
  33.949 -      </listitem>
  33.950 -      <listitem><para>Need to see all of the patches since
  33.951 -	  <literal>foo.patch</literal> that have touched files in a
  33.952 -	  subdirectory of your tree?</para>
  33.953 -	<programlisting>hg log -r foo.patch:qtip subdir</programlisting>
  33.954 -      </listitem>
  33.955 -    </itemizedlist>
  33.956 -
  33.957 -    <para>Because MQ makes the names of patches available to the rest
  33.958 -      of Mercurial through its normal internal tag machinery, you
  33.959 -      don't need to type in the entire name of a patch when you want
  33.960 -      to identify it by name.</para>
  33.961 -
  33.962 -    <para>Another nice consequence of representing patch names as tags
  33.963 -      is that when you run the <command role="hg-cmd">hg log</command>
  33.964 -      command, it will display a patch's name as a tag, simply as part
  33.965 -      of its normal output.  This makes it easy to visually
  33.966 -      distinguish applied patches from underlying
  33.967 -      <quote>normal</quote> revisions.  The following example shows a
  33.968 -      few normal Mercurial commands in use with applied
  33.969 -      patches.</para>
  33.970 -
  33.971 -&interaction.mq.id.output;
  33.972 -
  33.973 -  </sect1>
  33.974 -  <sect1>
  33.975 -    <title>Useful things to know about</title>
  33.976 -
  33.977 -    <para>There are a number of aspects of MQ usage that don't fit
  33.978 -      tidily into sections of their own, but that are good to know.
  33.979 -      Here they are, in one place.</para>
  33.980 -
  33.981 -    <itemizedlist>
  33.982 -      <listitem><para>Normally, when you <command
  33.983 -	    role="hg-ext-mq">qpop</command> a patch and <command
  33.984 -	    role="hg-ext-mq">qpush</command> it again, the changeset
  33.985 -	  that represents the patch after the pop/push will have a
  33.986 -	  <emphasis>different identity</emphasis> than the changeset
  33.987 -	  that represented the hash beforehand.  See section <xref
  33.988 -	    linkend="sec.mqref.cmd.qpush"/> for
  33.989 -	  information as to why this is.</para>
  33.990 -      </listitem>
  33.991 -      <listitem><para>It's not a good idea to <command
  33.992 -	    role="hg-cmd">hg merge</command> changes from another
  33.993 -	  branch with a patch changeset, at least if you want to
  33.994 -	  maintain the <quote>patchiness</quote> of that changeset and
  33.995 -	  changesets below it on the patch stack.  If you try to do
  33.996 -	  this, it will appear to succeed, but MQ will become
  33.997 -	  confused.</para>
  33.998 -      </listitem></itemizedlist>
  33.999 -
 33.1000 -  </sect1>
 33.1001 -  <sect1 id="sec.mq.repo">
 33.1002 -    <title>Managing patches in a repository</title>
 33.1003 -
 33.1004 -    <para>Because MQ's <filename role="special"
 33.1005 -	class="directory">.hg/patches</filename> directory resides
 33.1006 -      outside a Mercurial repository's working directory, the
 33.1007 -      <quote>underlying</quote> Mercurial repository knows nothing
 33.1008 -      about the management or presence of patches.</para>
 33.1009 -
 33.1010 -    <para>This presents the interesting possibility of managing the
 33.1011 -      contents of the patch directory as a Mercurial repository in its
 33.1012 -      own right.  This can be a useful way to work.  For example, you
 33.1013 -      can work on a patch for a while, <command
 33.1014 -	role="hg-ext-mq">qrefresh</command> it, then <command
 33.1015 -	role="hg-cmd">hg commit</command> the current state of the
 33.1016 -      patch.  This lets you <quote>roll back</quote> to that version
 33.1017 -      of the patch later on.</para>
 33.1018 -
 33.1019 -    <para>You can then share different versions of the same patch
 33.1020 -      stack among multiple underlying repositories.  I use this when I
 33.1021 -      am developing a Linux kernel feature.  I have a pristine copy of
 33.1022 -      my kernel sources for each of several CPU architectures, and a
 33.1023 -      cloned repository under each that contains the patches I am
 33.1024 -      working on.  When I want to test a change on a different
 33.1025 -      architecture, I push my current patches to the patch repository
 33.1026 -      associated with that kernel tree, pop and push all of my
 33.1027 -      patches, and build and test that kernel.</para>
 33.1028 -
 33.1029 -    <para>Managing patches in a repository makes it possible for
 33.1030 -      multiple developers to work on the same patch series without
 33.1031 -      colliding with each other, all on top of an underlying source
 33.1032 -      base that they may or may not control.</para>
 33.1033 -
 33.1034 -    <sect2>
 33.1035 -      <title>MQ support for patch repositories</title>
 33.1036 -
 33.1037 -      <para>MQ helps you to work with the <filename role="special"
 33.1038 -	  class="directory">.hg/patches</filename> directory as a
 33.1039 -	repository; when you prepare a repository for working with
 33.1040 -	patches using <command role="hg-ext-mq">qinit</command>, you
 33.1041 -	can pass the <option role="hg-ext-mq-cmd-qinit-opt">hg
 33.1042 -	  -c</option> option to create the <filename role="special"
 33.1043 -	  class="directory">.hg/patches</filename> directory as a
 33.1044 -	Mercurial repository.</para>
 33.1045 -
 33.1046 -      <note>
 33.1047 -	<para>  If you forget to use the <option
 33.1048 -	    role="hg-ext-mq-cmd-qinit-opt">hg -c</option> option, you
 33.1049 -	  can simply go into the <filename role="special"
 33.1050 -	    class="directory">.hg/patches</filename> directory at any
 33.1051 -	  time and run <command role="hg-cmd">hg init</command>.
 33.1052 -	  Don't forget to add an entry for the <filename
 33.1053 -	    role="special">status</filename> file to the <filename
 33.1054 -	    role="special">.hgignore</filename> file, though</para>
 33.1055 -
 33.1056 -	<para>  (<command role="hg-cmd">hg qinit <option
 33.1057 -	      role="hg-ext-mq-cmd-qinit-opt">hg -c</option></command>
 33.1058 -	  does this for you automatically); you
 33.1059 -	  <emphasis>really</emphasis> don't want to manage the
 33.1060 -	  <filename role="special">status</filename> file.</para>
 33.1061 -      </note>
 33.1062 -
 33.1063 -      <para>As a convenience, if MQ notices that the <filename
 33.1064 -	  class="directory">.hg/patches</filename> directory is a
 33.1065 -	repository, it will automatically <command role="hg-cmd">hg
 33.1066 -	  add</command> every patch that you create and import.</para>
 33.1067 -
 33.1068 -      <para>MQ provides a shortcut command, <command
 33.1069 -	  role="hg-ext-mq">qcommit</command>, that runs <command
 33.1070 -	  role="hg-cmd">hg commit</command> in the <filename
 33.1071 -	  role="special" class="directory">.hg/patches</filename>
 33.1072 -	directory.  This saves some bothersome typing.</para>
 33.1073 -
 33.1074 -      <para>Finally, as a convenience to manage the patch directory,
 33.1075 -	you can define the alias <command>mq</command> on Unix
 33.1076 -	systems. For example, on Linux systems using the
 33.1077 -	<command>bash</command> shell, you can include the following
 33.1078 -	snippet in your <filename
 33.1079 -	  role="home">~/.bashrc</filename>.</para>
 33.1080 -
 33.1081 -      <programlisting>alias mq=`hg -R $(hg root)/.hg/patches'</programlisting>
 33.1082 -
 33.1083 -      <para>You can then issue commands of the form <command>mq
 33.1084 -	  pull</command> from the main repository.</para>
 33.1085 -
 33.1086 -    </sect2>
 33.1087 -    <sect2>
 33.1088 -      <title>A few things to watch out for</title>
 33.1089 -
 33.1090 -      <para>MQ's support for working with a repository full of patches
 33.1091 -	is limited in a few small respects.</para>
 33.1092 -
 33.1093 -      <para>MQ cannot automatically detect changes that you make to
 33.1094 -	the patch directory.  If you <command role="hg-cmd">hg
 33.1095 -	  pull</command>, manually edit, or <command role="hg-cmd">hg
 33.1096 -	  update</command> changes to patches or the <filename
 33.1097 -	  role="special">series</filename> file, you will have to
 33.1098 -	<command role="hg-cmd">hg qpop <option
 33.1099 -	    role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> and
 33.1100 -	then <command role="hg-cmd">hg qpush <option
 33.1101 -	    role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> in
 33.1102 -	the underlying repository to see those changes show up there.
 33.1103 -	If you forget to do this, you can confuse MQ's idea of which
 33.1104 -	patches are applied.</para>
 33.1105 -
 33.1106 -    </sect2>
 33.1107 -  </sect1>
 33.1108 -  <sect1 id="sec.mq.tools">
 33.1109 -    <title>Third party tools for working with patches</title>
 33.1110 -
 33.1111 -    <para>Once you've been working with patches for a while, you'll
 33.1112 -      find yourself hungry for tools that will help you to understand
 33.1113 -      and manipulate the patches you're dealing with.</para>
 33.1114 -
 33.1115 -    <para>The <command>diffstat</command> command
 33.1116 -      <citation>web:diffstat</citation> generates a histogram of the
 33.1117 -      modifications made to each file in a patch.  It provides a good
 33.1118 -      way to <quote>get a sense of</quote> a patch&emdash;which files
 33.1119 -      it affects, and how much change it introduces to each file and
 33.1120 -      as a whole.  (I find that it's a good idea to use
 33.1121 -      <command>diffstat</command>'s <option
 33.1122 -	role="cmd-opt-diffstat">-p</option> option as a matter of
 33.1123 -      course, as otherwise it will try to do clever things with
 33.1124 -      prefixes of file names that inevitably confuse at least
 33.1125 -      me.)</para>
 33.1126 -
 33.1127 -&interaction.mq.tools.tools;
 33.1128 -
 33.1129 -    <para>The <literal role="package">patchutils</literal> package
 33.1130 -      <citation>web:patchutils</citation> is invaluable. It provides a
 33.1131 -      set of small utilities that follow the <quote>Unix
 33.1132 -	philosophy;</quote> each does one useful thing with a patch.
 33.1133 -      The <literal role="package">patchutils</literal> command I use
 33.1134 -      most is <command>filterdiff</command>, which extracts subsets
 33.1135 -      from a patch file.  For example, given a patch that modifies
 33.1136 -      hundreds of files across dozens of directories, a single
 33.1137 -      invocation of <command>filterdiff</command> can generate a
 33.1138 -      smaller patch that only touches files whose names match a
 33.1139 -      particular glob pattern.  See section <xref
 33.1140 -	linkend="mq-collab.tips.interdiff"/> for another
 33.1141 -      example.</para>
 33.1142 -
 33.1143 -  </sect1>
 33.1144 -  <sect1>
 33.1145 -    <title>Good ways to work with patches</title>
 33.1146 -
 33.1147 -    <para>Whether you are working on a patch series to submit to a
 33.1148 -      free software or open source project, or a series that you
 33.1149 -      intend to treat as a sequence of regular changesets when you're
 33.1150 -      done, you can use some simple techniques to keep your work well
 33.1151 -      organised.</para>
 33.1152 -
 33.1153 -    <para>Give your patches descriptive names.  A good name for a
 33.1154 -      patch might be <filename>rework-device-alloc.patch</filename>,
 33.1155 -      because it will immediately give you a hint what the purpose of
 33.1156 -      the patch is.  Long names shouldn't be a problem; you won't be
 33.1157 -      typing the names often, but you <emphasis>will</emphasis> be
 33.1158 -      running commands like <command
 33.1159 -	role="hg-ext-mq">qapplied</command> and <command
 33.1160 -	role="hg-ext-mq">qtop</command> over and over. Good naming
 33.1161 -      becomes especially important when you have a number of patches
 33.1162 -      to work with, or if you are juggling a number of different tasks
 33.1163 -      and your patches only get a fraction of your attention.</para>
 33.1164 -
 33.1165 -    <para>Be aware of what patch you're working on.  Use the <command
 33.1166 -	role="hg-ext-mq">qtop</command> command and skim over the text
 33.1167 -      of your patches frequently&emdash;for example, using <command
 33.1168 -	role="hg-cmd">hg tip <option
 33.1169 -	  role="hg-opt-tip">-p</option></command>)&emdash;to be sure
 33.1170 -      of where you stand.  I have several times worked on and <command
 33.1171 -	role="hg-ext-mq">qrefresh</command>ed a patch other than the
 33.1172 -      one I intended, and it's often tricky to migrate changes into
 33.1173 -      the right patch after making them in the wrong one.</para>
 33.1174 -
 33.1175 -    <para>For this reason, it is very much worth investing a little
 33.1176 -      time to learn how to use some of the third-party tools I
 33.1177 -      described in section <xref linkend="sec.mq.tools"/>,
 33.1178 -      particularly
 33.1179 -      <command>diffstat</command> and <command>filterdiff</command>.
 33.1180 -      The former will give you a quick idea of what changes your patch
 33.1181 -      is making, while the latter makes it easy to splice hunks
 33.1182 -      selectively out of one patch and into another.</para>
 33.1183 -
 33.1184 -  </sect1>
 33.1185 -  <sect1>
 33.1186 -    <title>MQ cookbook</title>
 33.1187 -
 33.1188 -    <sect2>
 33.1189 -      <title>Manage <quote>trivial</quote> patches</title>
 33.1190 -
 33.1191 -      <para>Because the overhead of dropping files into a new
 33.1192 -	Mercurial repository is so low, it makes a lot of sense to
 33.1193 -	manage patches this way even if you simply want to make a few
 33.1194 -	changes to a source tarball that you downloaded.</para>
 33.1195 -
 33.1196 -      <para>Begin by downloading and unpacking the source tarball, and
 33.1197 -	turning it into a Mercurial repository.</para>
 33.1198 -
 33.1199 -      &interaction.mq.tarball.download;
 33.1200 -
 33.1201 -      <para>Continue by creating a patch stack and making your
 33.1202 -	changes.</para>
 33.1203 -
 33.1204 -      &interaction.mq.tarball.qinit;
 33.1205 -
 33.1206 -      <para>Let's say a few weeks or months pass, and your package
 33.1207 -	author releases a new version.  First, bring their changes
 33.1208 -	into the repository.</para>
 33.1209 -
 33.1210 -      &interaction.mq.tarball.newsource;
 33.1211 -
 33.1212 -      <para>The pipeline starting with <command role="hg-cmd">hg
 33.1213 -	  locate</command> above deletes all files in the working
 33.1214 -	directory, so that <command role="hg-cmd">hg
 33.1215 -	  commit</command>'s <option
 33.1216 -	  role="hg-opt-commit">--addremove</option> option can
 33.1217 -	actually tell which files have really been removed in the
 33.1218 -	newer version of the source.</para>
 33.1219 -
 33.1220 -      <para>Finally, you can apply your patches on top of the new
 33.1221 -	tree.</para>
 33.1222 -
 33.1223 -      &interaction.mq.tarball.repush;
 33.1224 -
 33.1225 -    </sect2>
 33.1226 -    <sect2 id="sec.mq.combine">
 33.1227 -      <title>Combining entire patches</title>
 33.1228 -
 33.1229 -      <para>MQ provides a command, <command
 33.1230 -	  role="hg-ext-mq">qfold</command> that lets you combine
 33.1231 -	entire patches.  This <quote>folds</quote> the patches you
 33.1232 -	name, in the order you name them, into the topmost applied
 33.1233 -	patch, and concatenates their descriptions onto the end of its
 33.1234 -	description.  The patches that you fold must be unapplied
 33.1235 -	before you fold them.</para>
 33.1236 -
 33.1237 -      <para>The order in which you fold patches matters.  If your
 33.1238 -	topmost applied patch is <literal>foo</literal>, and you
 33.1239 -	<command role="hg-ext-mq">qfold</command>
 33.1240 -	<literal>bar</literal> and <literal>quux</literal> into it,
 33.1241 -	you will end up with a patch that has the same effect as if
 33.1242 -	you applied first <literal>foo</literal>, then
 33.1243 -	<literal>bar</literal>, followed by
 33.1244 -	<literal>quux</literal>.</para>
 33.1245 -
 33.1246 -    </sect2>
 33.1247 -    <sect2>
 33.1248 -      <title>Merging part of one patch into another</title>
 33.1249 -
 33.1250 -      <para>Merging <emphasis>part</emphasis> of one patch into
 33.1251 -	another is more difficult than combining entire
 33.1252 -	patches.</para>
 33.1253 -
 33.1254 -      <para>If you want to move changes to entire files, you can use
 33.1255 -	<command>filterdiff</command>'s <option
 33.1256 -	  role="cmd-opt-filterdiff">-i</option> and <option
 33.1257 -	  role="cmd-opt-filterdiff">-x</option> options to choose the
 33.1258 -	modifications to snip out of one patch, concatenating its
 33.1259 -	output onto the end of the patch you want to merge into.  You
 33.1260 -	usually won't need to modify the patch you've merged the
 33.1261 -	changes from.  Instead, MQ will report some rejected hunks
 33.1262 -	when you <command role="hg-ext-mq">qpush</command> it (from
 33.1263 -	the hunks you moved into the other patch), and you can simply
 33.1264 -	<command role="hg-ext-mq">qrefresh</command> the patch to drop
 33.1265 -	the duplicate hunks.</para>
 33.1266 -
 33.1267 -      <para>If you have a patch that has multiple hunks modifying a
 33.1268 -	file, and you only want to move a few of those hunks, the job
 33.1269 -	becomes more messy, but you can still partly automate it.  Use
 33.1270 -	<command>lsdiff -nvv</command> to print some metadata about
 33.1271 -	the patch.</para>
 33.1272 -
 33.1273 -      &interaction.mq.tools.lsdiff;
 33.1274 -
 33.1275 -      <para>This command prints three different kinds of
 33.1276 -	number:</para>
 33.1277 -      <itemizedlist>
 33.1278 -	<listitem><para>(in the first column) a <emphasis>file
 33.1279 -	      number</emphasis> to identify each file modified in the
 33.1280 -	    patch;</para>
 33.1281 -	</listitem>
 33.1282 -	<listitem><para>(on the next line, indented) the line number
 33.1283 -	    within a modified file where a hunk starts; and</para>
 33.1284 -	</listitem>
 33.1285 -	<listitem><para>(on the same line) a <emphasis>hunk
 33.1286 -	      number</emphasis> to identify that hunk.</para>
 33.1287 -	</listitem></itemizedlist>
 33.1288 -
 33.1289 -      <para>You'll have to use some visual inspection, and reading of
 33.1290 -	the patch, to identify the file and hunk numbers you'll want,
 33.1291 -	but you can then pass them to to
 33.1292 -	<command>filterdiff</command>'s <option
 33.1293 -	  role="cmd-opt-filterdiff">--files</option> and <option
 33.1294 -	  role="cmd-opt-filterdiff">--hunks</option> options, to
 33.1295 -	select exactly the file and hunk you want to extract.</para>
 33.1296 -
 33.1297 -      <para>Once you have this hunk, you can concatenate it onto the
 33.1298 -	end of your destination patch and continue with the remainder
 33.1299 -	of section <xref linkend="sec.mq.combine"/>.</para>
 33.1300 -
 33.1301 -    </sect2>
 33.1302 -  </sect1>
 33.1303 -  <sect1>
 33.1304 -    <title>Differences between quilt and MQ</title>
 33.1305 -
 33.1306 -    <para>If you are already familiar with quilt, MQ provides a
 33.1307 -      similar command set.  There are a few differences in the way
 33.1308 -      that it works.</para>
 33.1309 -
 33.1310 -    <para>You will already have noticed that most quilt commands have
 33.1311 -      MQ counterparts that simply begin with a
 33.1312 -      <quote><literal>q</literal></quote>.  The exceptions are quilt's
 33.1313 -      <literal>add</literal> and <literal>remove</literal> commands,
 33.1314 -      the counterparts for which are the normal Mercurial <command
 33.1315 -	role="hg-cmd">hg add</command> and <command role="hg-cmd">hg
 33.1316 -	remove</command> commands.  There is no MQ equivalent of the
 33.1317 -      quilt <literal>edit</literal> command.</para>
 33.1318 -
 33.1319 -  </sect1>
 33.1320 -</chapter>
 33.1321 -
 33.1322 -<!--
 33.1323 -local variables: 
 33.1324 -sgml-parent-document: ("00book.xml" "book" "chapter")
 33.1325 -end:
 33.1326 --->
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/en/ch13-hgext.xml	Fri Mar 20 16:43:35 2009 +0800
    34.3 @@ -0,0 +1,554 @@
    34.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    34.5 +
    34.6 +<chapter id="chap.hgext">
    34.7 +  <?dbhtml filename="adding-functionality-with-extensions.html"?>
    34.8 +  <title>Adding functionality with extensions</title>
    34.9 +
   34.10 +  <para>While the core of Mercurial is quite complete from a
   34.11 +    functionality standpoint, it's deliberately shorn of fancy
   34.12 +    features.  This approach of preserving simplicity keeps the
   34.13 +    software easy to deal with for both maintainers and users.</para>
   34.14 +
   34.15 +  <para>However, Mercurial doesn't box you in with an inflexible
   34.16 +    command set: you can add features to it as
   34.17 +    <emphasis>extensions</emphasis> (sometimes known as
   34.18 +    <emphasis>plugins</emphasis>).  We've already discussed a few of
   34.19 +    these extensions in earlier chapters.</para>
   34.20 +  <itemizedlist>
   34.21 +    <listitem><para>Section <xref linkend="sec.tour-merge.fetch"/>
   34.22 +	covers the <literal role="hg-ext">fetch</literal> extension;
   34.23 +	this combines pulling new changes and merging them with local
   34.24 +	changes into a single command, <command
   34.25 +	  role="hg-ext-fetch">fetch</command>.</para>
   34.26 +    </listitem>
   34.27 +    <listitem><para>In chapter <xref linkend="chap.hook"/>, we covered
   34.28 +	several extensions that are useful for hook-related
   34.29 +	functionality: <literal role="hg-ext">acl</literal> adds
   34.30 +	access control lists; <literal
   34.31 +	  role="hg-ext">bugzilla</literal> adds integration with the
   34.32 +	Bugzilla bug tracking system; and <literal
   34.33 +	  role="hg-ext">notify</literal> sends notification emails on
   34.34 +	new changes.</para>
   34.35 +    </listitem>
   34.36 +    <listitem><para>The Mercurial Queues patch management extension is
   34.37 +	so invaluable that it merits two chapters and an appendix all
   34.38 +	to itself. Chapter <xref linkend="chap.mq"/> covers the
   34.39 +	basics; chapter <xref
   34.40 +	  linkend="chap.mq-collab"/> discusses advanced topics;
   34.41 +	and appendix <xref linkend="chap.mqref"/> goes into detail on
   34.42 +	each
   34.43 +	command.</para>
   34.44 +    </listitem></itemizedlist>
   34.45 +
   34.46 +  <para>In this chapter, we'll cover some of the other extensions that
   34.47 +    are available for Mercurial, and briefly touch on some of the
   34.48 +    machinery you'll need to know about if you want to write an
   34.49 +    extension of your own.</para>
   34.50 +  <itemizedlist>
   34.51 +    <listitem><para>In section <xref linkend="sec.hgext.inotify"/>,
   34.52 +	we'll discuss the possibility of <emphasis>huge</emphasis>
   34.53 +	performance improvements using the <literal
   34.54 +	  role="hg-ext">inotify</literal> extension.</para>
   34.55 +    </listitem></itemizedlist>
   34.56 +
   34.57 +  <sect1 id="sec.hgext.inotify">
   34.58 +    <title>Improve performance with the <literal
   34.59 +	role="hg-ext">inotify</literal> extension</title>
   34.60 +
   34.61 +    <para>Are you interested in having some of the most common
   34.62 +      Mercurial operations run as much as a hundred times faster?
   34.63 +      Read on!</para>
   34.64 +
   34.65 +    <para>Mercurial has great performance under normal circumstances.
   34.66 +      For example, when you run the <command role="hg-cmd">hg
   34.67 +	status</command> command, Mercurial has to scan almost every
   34.68 +      directory and file in your repository so that it can display
   34.69 +      file status.  Many other Mercurial commands need to do the same
   34.70 +      work behind the scenes; for example, the <command
   34.71 +	role="hg-cmd">hg diff</command> command uses the status
   34.72 +      machinery to avoid doing an expensive comparison operation on
   34.73 +      files that obviously haven't changed.</para>
   34.74 +
   34.75 +    <para>Because obtaining file status is crucial to good
   34.76 +      performance, the authors of Mercurial have optimised this code
   34.77 +      to within an inch of its life.  However, there's no avoiding the
   34.78 +      fact that when you run <command role="hg-cmd">hg
   34.79 +	status</command>, Mercurial is going to have to perform at
   34.80 +      least one expensive system call for each managed file to
   34.81 +      determine whether it's changed since the last time Mercurial
   34.82 +      checked.  For a sufficiently large repository, this can take a
   34.83 +      long time.</para>
   34.84 +
   34.85 +    <para>To put a number on the magnitude of this effect, I created a
   34.86 +      repository containing 150,000 managed files.  I timed <command
   34.87 +	role="hg-cmd">hg status</command> as taking ten seconds to
   34.88 +      run, even when <emphasis>none</emphasis> of those files had been
   34.89 +      modified.</para>
   34.90 +
   34.91 +    <para>Many modern operating systems contain a file notification
   34.92 +      facility. If a program signs up to an appropriate service, the
   34.93 +      operating system will notify it every time a file of interest is
   34.94 +      created, modified, or deleted.  On Linux systems, the kernel
   34.95 +      component that does this is called
   34.96 +      <literal>inotify</literal>.</para>
   34.97 +
   34.98 +    <para>Mercurial's <literal role="hg-ext">inotify</literal>
   34.99 +      extension talks to the kernel's <literal>inotify</literal>
  34.100 +      component to optimise <command role="hg-cmd">hg status</command>
  34.101 +      commands.  The extension has two components.  A daemon sits in
  34.102 +      the background and receives notifications from the
  34.103 +      <literal>inotify</literal> subsystem.  It also listens for
  34.104 +      connections from a regular Mercurial command.  The extension
  34.105 +      modifies Mercurial's behaviour so that instead of scanning the
  34.106 +      filesystem, it queries the daemon.  Since the daemon has perfect
  34.107 +      information about the state of the repository, it can respond
  34.108 +      with a result instantaneously, avoiding the need to scan every
  34.109 +      directory and file in the repository.</para>
  34.110 +
  34.111 +    <para>Recall the ten seconds that I measured plain Mercurial as
  34.112 +      taking to run <command role="hg-cmd">hg status</command> on a
  34.113 +      150,000 file repository.  With the <literal
  34.114 +	role="hg-ext">inotify</literal> extension enabled, the time
  34.115 +      dropped to 0.1 seconds, a factor of <emphasis>one
  34.116 +	hundred</emphasis> faster.</para>
  34.117 +
  34.118 +    <para>Before we continue, please pay attention to some
  34.119 +      caveats.</para>
  34.120 +    <itemizedlist>
  34.121 +      <listitem><para>The <literal role="hg-ext">inotify</literal>
  34.122 +	  extension is Linux-specific.  Because it interfaces directly
  34.123 +	  to the Linux kernel's <literal>inotify</literal> subsystem,
  34.124 +	  it does not work on other operating systems.</para>
  34.125 +      </listitem>
  34.126 +      <listitem><para>It should work on any Linux distribution that
  34.127 +	  was released after early 2005.  Older distributions are
  34.128 +	  likely to have a kernel that lacks
  34.129 +	  <literal>inotify</literal>, or a version of
  34.130 +	  <literal>glibc</literal> that does not have the necessary
  34.131 +	  interfacing support.</para>
  34.132 +      </listitem>
  34.133 +      <listitem><para>Not all filesystems are suitable for use with
  34.134 +	  the <literal role="hg-ext">inotify</literal> extension.
  34.135 +	  Network filesystems such as NFS are a non-starter, for
  34.136 +	  example, particularly if you're running Mercurial on several
  34.137 +	  systems, all mounting the same network filesystem.  The
  34.138 +	  kernel's <literal>inotify</literal> system has no way of
  34.139 +	  knowing about changes made on another system.  Most local
  34.140 +	  filesystems (e.g. ext3, XFS, ReiserFS) should work
  34.141 +	  fine.</para>
  34.142 +      </listitem></itemizedlist>
  34.143 +
  34.144 +    <para>The <literal role="hg-ext">inotify</literal> extension is
  34.145 +      not yet shipped with Mercurial as of May 2007, so it's a little
  34.146 +      more involved to set up than other extensions.  But the
  34.147 +      performance improvement is worth it!</para>
  34.148 +
  34.149 +    <para>The extension currently comes in two parts: a set of patches
  34.150 +      to the Mercurial source code, and a library of Python bindings
  34.151 +      to the <literal>inotify</literal> subsystem.</para>
  34.152 +    <note>
  34.153 +      <para>  There are <emphasis>two</emphasis> Python
  34.154 +	<literal>inotify</literal> binding libraries.  One of them is
  34.155 +	called <literal>pyinotify</literal>, and is packaged by some
  34.156 +	Linux distributions as <literal>python-inotify</literal>.
  34.157 +	This is <emphasis>not</emphasis> the one you'll need, as it is
  34.158 +	too buggy and inefficient to be practical.</para>
  34.159 +    </note>
  34.160 +    <para>To get going, it's best to already have a functioning copy
  34.161 +      of Mercurial installed.</para>
  34.162 +    <note>
  34.163 +      <para>  If you follow the instructions below, you'll be
  34.164 +	<emphasis>replacing</emphasis> and overwriting any existing
  34.165 +	installation of Mercurial that you might already have, using
  34.166 +	the latest <quote>bleeding edge</quote> Mercurial code. Don't
  34.167 +	say you weren't warned!</para>
  34.168 +    </note>
  34.169 +    <orderedlist>
  34.170 +      <listitem><para>Clone the Python <literal>inotify</literal>
  34.171 +	  binding repository.  Build and install it.</para>
  34.172 +	<programlisting>hg clone http://hg.kublai.com/python/inotify
  34.173 +cd inotify
  34.174 +python setup.py build --force
  34.175 +sudo python setup.py install --skip-build</programlisting>
  34.176 +      </listitem>
  34.177 +      <listitem><para>Clone the <filename
  34.178 +	    class="directory">crew</filename> Mercurial repository.
  34.179 +	  Clone the <literal role="hg-ext">inotify</literal> patch
  34.180 +	  repository so that Mercurial Queues will be able to apply
  34.181 +	  patches to your cope of the <filename
  34.182 +	    class="directory">crew</filename> repository.</para>
  34.183 +	<programlisting>hg clone http://hg.intevation.org/mercurial/crew
  34.184 +hg clone crew inotify
  34.185 +hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches</programlisting>
  34.186 +      </listitem>
  34.187 +      <listitem><para>Make sure that you have the Mercurial Queues
  34.188 +	  extension, <literal role="hg-ext">mq</literal>, enabled.  If
  34.189 +	  you've never used MQ, read section <xref
  34.190 +	    linkend="sec.mq.start"/> to get started
  34.191 +	  quickly.</para>
  34.192 +      </listitem>
  34.193 +      <listitem><para>Go into the <filename
  34.194 +	    class="directory">inotify</filename> repo, and apply all
  34.195 +	  of the <literal role="hg-ext">inotify</literal> patches
  34.196 +	  using the <option role="hg-ext-mq-cmd-qpush-opt">hg
  34.197 +	    -a</option> option to the <command
  34.198 +	    role="hg-ext-mq">qpush</command> command.</para>
  34.199 +	<programlisting>cd inotify
  34.200 +hg qpush -a</programlisting>
  34.201 +      </listitem>
  34.202 +      <listitem><para>  If you get an error message from <command
  34.203 +	    role="hg-ext-mq">qpush</command>, you should not continue.
  34.204 +	  Instead, ask for help.</para>
  34.205 +      </listitem>
  34.206 +      <listitem><para>Build and install the patched version of
  34.207 +	  Mercurial.</para>
  34.208 +	<programlisting>python setup.py build --force
  34.209 +sudo python setup.py install --skip-build</programlisting>
  34.210 +      </listitem>
  34.211 +    </orderedlist>
  34.212 +    <para>Once you've build a suitably patched version of Mercurial,
  34.213 +      all you need to do to enable the <literal
  34.214 +	role="hg-ext">inotify</literal> extension is add an entry to
  34.215 +      your <filename role="special">~/.hgrc</filename>.</para>
  34.216 +    <programlisting>[extensions] inotify =</programlisting>
  34.217 +    <para>When the <literal role="hg-ext">inotify</literal> extension
  34.218 +      is enabled, Mercurial will automatically and transparently start
  34.219 +      the status daemon the first time you run a command that needs
  34.220 +      status in a repository.  It runs one status daemon per
  34.221 +      repository.</para>
  34.222 +
  34.223 +    <para>The status daemon is started silently, and runs in the
  34.224 +      background.  If you look at a list of running processes after
  34.225 +      you've enabled the <literal role="hg-ext">inotify</literal>
  34.226 +      extension and run a few commands in different repositories,
  34.227 +      you'll thus see a few <literal>hg</literal> processes sitting
  34.228 +      around, waiting for updates from the kernel and queries from
  34.229 +      Mercurial.</para>
  34.230 +
  34.231 +    <para>The first time you run a Mercurial command in a repository
  34.232 +      when you have the <literal role="hg-ext">inotify</literal>
  34.233 +      extension enabled, it will run with about the same performance
  34.234 +      as a normal Mercurial command.  This is because the status
  34.235 +      daemon needs to perform a normal status scan so that it has a
  34.236 +      baseline against which to apply later updates from the kernel.
  34.237 +      However, <emphasis>every</emphasis> subsequent command that does
  34.238 +      any kind of status check should be noticeably faster on
  34.239 +      repositories of even fairly modest size.  Better yet, the bigger
  34.240 +      your repository is, the greater a performance advantage you'll
  34.241 +      see.  The <literal role="hg-ext">inotify</literal> daemon makes
  34.242 +      status operations almost instantaneous on repositories of all
  34.243 +      sizes!</para>
  34.244 +
  34.245 +    <para>If you like, you can manually start a status daemon using
  34.246 +      the <command role="hg-ext-inotify">inserve</command> command.
  34.247 +      This gives you slightly finer control over how the daemon ought
  34.248 +      to run.  This command will of course only be available when the
  34.249 +      <literal role="hg-ext">inotify</literal> extension is
  34.250 +      enabled.</para>
  34.251 +
  34.252 +    <para>When you're using the <literal
  34.253 +	role="hg-ext">inotify</literal> extension, you should notice
  34.254 +      <emphasis>no difference at all</emphasis> in Mercurial's
  34.255 +      behaviour, with the sole exception of status-related commands
  34.256 +      running a whole lot faster than they used to.  You should
  34.257 +      specifically expect that commands will not print different
  34.258 +      output; neither should they give different results. If either of
  34.259 +      these situations occurs, please report a bug.</para>
  34.260 +
  34.261 +  </sect1>
  34.262 +  <sect1 id="sec.hgext.extdiff">
  34.263 +    <title>Flexible diff support with the <literal
  34.264 +	role="hg-ext">extdiff</literal> extension</title>
  34.265 +
  34.266 +    <para>Mercurial's built-in <command role="hg-cmd">hg
  34.267 +	diff</command> command outputs plaintext unified diffs.</para>
  34.268 +
  34.269 +    &interaction.extdiff.diff;
  34.270 +
  34.271 +    <para>If you would like to use an external tool to display
  34.272 +      modifications, you'll want to use the <literal
  34.273 +	role="hg-ext">extdiff</literal> extension.  This will let you
  34.274 +      use, for example, a graphical diff tool.</para>
  34.275 +
  34.276 +    <para>The <literal role="hg-ext">extdiff</literal> extension is
  34.277 +      bundled with Mercurial, so it's easy to set up.  In the <literal
  34.278 +	role="rc-extensions">extensions</literal> section of your
  34.279 +      <filename role="special">~/.hgrc</filename>, simply add a
  34.280 +      one-line entry to enable the extension.</para>
  34.281 +    <programlisting>[extensions]
  34.282 +extdiff =</programlisting>
  34.283 +    <para>This introduces a command named <command
  34.284 +	role="hg-ext-extdiff">extdiff</command>, which by default uses
  34.285 +      your system's <command>diff</command> command to generate a
  34.286 +      unified diff in the same form as the built-in <command
  34.287 +	role="hg-cmd">hg diff</command> command.</para>
  34.288 +    
  34.289 +    &interaction.extdiff.extdiff;
  34.290 +
  34.291 +    <para>The result won't be exactly the same as with the built-in
  34.292 +      <command role="hg-cmd">hg diff</command> variations, because the
  34.293 +      output of <command>diff</command> varies from one system to
  34.294 +      another, even when passed the same options.</para>
  34.295 +
  34.296 +    <para>As the <quote><literal>making snapshot</literal></quote>
  34.297 +      lines of output above imply, the <command
  34.298 +	role="hg-ext-extdiff">extdiff</command> command works by
  34.299 +      creating two snapshots of your source tree.  The first snapshot
  34.300 +      is of the source revision; the second, of the target revision or
  34.301 +      working directory.  The <command
  34.302 +	role="hg-ext-extdiff">extdiff</command> command generates
  34.303 +      these snapshots in a temporary directory, passes the name of
  34.304 +      each directory to an external diff viewer, then deletes the
  34.305 +      temporary directory.  For efficiency, it only snapshots the
  34.306 +      directories and files that have changed between the two
  34.307 +      revisions.</para>
  34.308 +
  34.309 +    <para>Snapshot directory names have the same base name as your
  34.310 +      repository. If your repository path is <filename
  34.311 +	class="directory">/quux/bar/foo</filename>, then <filename
  34.312 +	class="directory">foo</filename> will be the name of each
  34.313 +      snapshot directory.  Each snapshot directory name has its
  34.314 +      changeset ID appended, if appropriate.  If a snapshot is of
  34.315 +      revision <literal>a631aca1083f</literal>, the directory will be
  34.316 +      named <filename class="directory">foo.a631aca1083f</filename>.
  34.317 +      A snapshot of the working directory won't have a changeset ID
  34.318 +      appended, so it would just be <filename
  34.319 +	class="directory">foo</filename> in this example.  To see what
  34.320 +      this looks like in practice, look again at the <command
  34.321 +	role="hg-ext-extdiff">extdiff</command> example above.  Notice
  34.322 +      that the diff has the snapshot directory names embedded in its
  34.323 +      header.</para>
  34.324 +
  34.325 +    <para>The <command role="hg-ext-extdiff">extdiff</command> command
  34.326 +      accepts two important options. The <option
  34.327 +	role="hg-ext-extdiff-cmd-extdiff-opt">hg -p</option> option
  34.328 +      lets you choose a program to view differences with, instead of
  34.329 +      <command>diff</command>.  With the <option
  34.330 +	role="hg-ext-extdiff-cmd-extdiff-opt">hg -o</option> option,
  34.331 +      you can change the options that <command
  34.332 +	role="hg-ext-extdiff">extdiff</command> passes to the program
  34.333 +      (by default, these options are
  34.334 +      <quote><literal>-Npru</literal></quote>, which only make sense
  34.335 +      if you're running <command>diff</command>).  In other respects,
  34.336 +      the <command role="hg-ext-extdiff">extdiff</command> command
  34.337 +      acts similarly to the built-in <command role="hg-cmd">hg
  34.338 +	diff</command> command: you use the same option names, syntax,
  34.339 +      and arguments to specify the revisions you want, the files you
  34.340 +      want, and so on.</para>
  34.341 +
  34.342 +    <para>As an example, here's how to run the normal system
  34.343 +      <command>diff</command> command, getting it to generate context
  34.344 +      diffs (using the <option role="cmd-opt-diff">-c</option> option)
  34.345 +      instead of unified diffs, and five lines of context instead of
  34.346 +      the default three (passing <literal>5</literal> as the argument
  34.347 +      to the <option role="cmd-opt-diff">-C</option> option).</para>
  34.348 +
  34.349 +      &interaction.extdiff.extdiff-ctx;
  34.350 +
  34.351 +    <para>Launching a visual diff tool is just as easy.  Here's how to
  34.352 +      launch the <command>kdiff3</command> viewer.</para>
  34.353 +    <programlisting>hg extdiff -p kdiff3 -o</programlisting>
  34.354 +
  34.355 +    <para>If your diff viewing command can't deal with directories,
  34.356 +      you can easily work around this with a little scripting.  For an
  34.357 +      example of such scripting in action with the <literal
  34.358 +	role="hg-ext">mq</literal> extension and the
  34.359 +      <command>interdiff</command> command, see section <xref
  34.360 +	linkend="mq-collab.tips.interdiff"/>.</para>
  34.361 +
  34.362 +    <sect2>
  34.363 +      <title>Defining command aliases</title>
  34.364 +
  34.365 +      <para>It can be cumbersome to remember the options to both the
  34.366 +	<command role="hg-ext-extdiff">extdiff</command> command and
  34.367 +	the diff viewer you want to use, so the <literal
  34.368 +	  role="hg-ext">extdiff</literal> extension lets you define
  34.369 +	<emphasis>new</emphasis> commands that will invoke your diff
  34.370 +	viewer with exactly the right options.</para>
  34.371 +
  34.372 +      <para>All you need to do is edit your <filename
  34.373 +	  role="special">~/.hgrc</filename>, and add a section named
  34.374 +	<literal role="rc-extdiff">extdiff</literal>.  Inside this
  34.375 +	section, you can define multiple commands.  Here's how to add
  34.376 +	a <literal>kdiff3</literal> command.  Once you've defined
  34.377 +	this, you can type <quote><literal>hg kdiff3</literal></quote>
  34.378 +	and the <literal role="hg-ext">extdiff</literal> extension
  34.379 +	will run <command>kdiff3</command> for you.</para>
  34.380 +      <programlisting>[extdiff]
  34.381 +cmd.kdiff3 =</programlisting>
  34.382 +      <para>If you leave the right hand side of the definition empty,
  34.383 +	as above, the <literal role="hg-ext">extdiff</literal>
  34.384 +	extension uses the name of the command you defined as the name
  34.385 +	of the external program to run.  But these names don't have to
  34.386 +	be the same.  Here, we define a command named
  34.387 +	<quote><literal>hg wibble</literal></quote>, which runs
  34.388 +	<command>kdiff3</command>.</para>
  34.389 +      <programlisting>[extdiff]
  34.390 + cmd.wibble = kdiff3</programlisting>
  34.391 +
  34.392 +      <para>You can also specify the default options that you want to
  34.393 +	invoke your diff viewing program with.  The prefix to use is
  34.394 +	<quote><literal>opts.</literal></quote>, followed by the name
  34.395 +	of the command to which the options apply.  This example
  34.396 +	defines a <quote><literal>hg vimdiff</literal></quote> command
  34.397 +	that runs the <command>vim</command> editor's
  34.398 +	<literal>DirDiff</literal> extension.</para>
  34.399 +      <programlisting>[extdiff]
  34.400 + cmd.vimdiff = vim
  34.401 +opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)'</programlisting>
  34.402 +
  34.403 +    </sect2>
  34.404 +  </sect1>
  34.405 +  <sect1 id="sec.hgext.transplant">
  34.406 +    <title>Cherrypicking changes with the <literal
  34.407 +	role="hg-ext">transplant</literal> extension</title>
  34.408 +
  34.409 +    <para>Need to have a long chat with Brendan about this.</para>
  34.410 +
  34.411 +  </sect1>
  34.412 +  <sect1 id="sec.hgext.patchbomb">
  34.413 +    <title>Send changes via email with the <literal
  34.414 +	role="hg-ext">patchbomb</literal> extension</title>
  34.415 +
  34.416 +    <para>Many projects have a culture of <quote>change
  34.417 +	review</quote>, in which people send their modifications to a
  34.418 +      mailing list for others to read and comment on before they
  34.419 +      commit the final version to a shared repository.  Some projects
  34.420 +      have people who act as gatekeepers; they apply changes from
  34.421 +      other people to a repository to which those others don't have
  34.422 +      access.</para>
  34.423 +
  34.424 +    <para>Mercurial makes it easy to send changes over email for
  34.425 +      review or application, via its <literal
  34.426 +	role="hg-ext">patchbomb</literal> extension.  The extension is
  34.427 +      so named because changes are formatted as patches, and it's usual
  34.428 +      to send one changeset per email message.  Sending a long series
  34.429 +      of changes by email is thus much like <quote>bombing</quote> the
  34.430 +      recipient's inbox, hence <quote>patchbomb</quote>.</para>
  34.431 +
  34.432 +    <para>As usual, the basic configuration of the <literal
  34.433 +	role="hg-ext">patchbomb</literal> extension takes just one or
  34.434 +      two lines in your <filename role="special">
  34.435 +	/.hgrc</filename>.</para>
  34.436 +    <programlisting>[extensions]
  34.437 +patchbomb =</programlisting>
  34.438 +    <para>Once you've enabled the extension, you will have a new
  34.439 +      command available, named <command
  34.440 +	role="hg-ext-patchbomb">email</command>.</para>
  34.441 +
  34.442 +    <para>The safest and best way to invoke the <command
  34.443 +	role="hg-ext-patchbomb">email</command> command is to
  34.444 +      <emphasis>always</emphasis> run it first with the <option
  34.445 +	role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option.
  34.446 +      This will show you what the command <emphasis>would</emphasis>
  34.447 +      send, without actually sending anything.  Once you've had a
  34.448 +      quick glance over the changes and verified that you are sending
  34.449 +      the right ones, you can rerun the same command, with the <option
  34.450 +	role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option
  34.451 +      removed.</para>
  34.452 +
  34.453 +    <para>The <command role="hg-ext-patchbomb">email</command> command
  34.454 +      accepts the same kind of revision syntax as every other
  34.455 +      Mercurial command.  For example, this command will send every
  34.456 +      revision between 7 and <literal>tip</literal>, inclusive.</para>
  34.457 +    <programlisting>hg email -n 7:tip</programlisting>
  34.458 +    <para>You can also specify a <emphasis>repository</emphasis> to
  34.459 +      compare with.  If you provide a repository but no revisions, the
  34.460 +      <command role="hg-ext-patchbomb">email</command> command will
  34.461 +      send all revisions in the local repository that are not present
  34.462 +      in the remote repository.  If you additionally specify revisions
  34.463 +      or a branch name (the latter using the <option
  34.464 +	role="hg-ext-patchbomb-cmd-email-opt">hg -b</option> option),
  34.465 +      this will constrain the revisions sent.</para>
  34.466 +
  34.467 +    <para>It's perfectly safe to run the <command
  34.468 +	role="hg-ext-patchbomb">email</command> command without the
  34.469 +      names of the people you want to send to: if you do this, it will
  34.470 +      just prompt you for those values interactively.  (If you're
  34.471 +      using a Linux or Unix-like system, you should have enhanced
  34.472 +      <literal>readline</literal>-style editing capabilities when
  34.473 +      entering those headers, too, which is useful.)</para>
  34.474 +
  34.475 +    <para>When you are sending just one revision, the <command
  34.476 +	role="hg-ext-patchbomb">email</command> command will by
  34.477 +      default use the first line of the changeset description as the
  34.478 +      subject of the single email message it sends.</para>
  34.479 +
  34.480 +    <para>If you send multiple revisions, the <command
  34.481 +	role="hg-ext-patchbomb">email</command> command will usually
  34.482 +      send one message per changeset.  It will preface the series with
  34.483 +      an introductory message, in which you should describe the
  34.484 +      purpose of the series of changes you're sending.</para>
  34.485 +
  34.486 +    <sect2>
  34.487 +      <title>Changing the behaviour of patchbombs</title>
  34.488 +
  34.489 +      <para>Not every project has exactly the same conventions for
  34.490 +	sending changes in email; the <literal
  34.491 +	  role="hg-ext">patchbomb</literal> extension tries to
  34.492 +	accommodate a number of variations through command line
  34.493 +	options.</para>
  34.494 +      <itemizedlist>
  34.495 +	<listitem><para>You can write a subject for the introductory
  34.496 +	    message on the command line using the <option
  34.497 +	      role="hg-ext-patchbomb-cmd-email-opt">hg -s</option>
  34.498 +	    option.  This takes one argument, the text of the subject
  34.499 +	    to use.</para>
  34.500 +	</listitem>
  34.501 +	<listitem><para>To change the email address from which the
  34.502 +	    messages originate, use the <option
  34.503 +	      role="hg-ext-patchbomb-cmd-email-opt">hg -f</option>
  34.504 +	    option.  This takes one argument, the email address to
  34.505 +	    use.</para>
  34.506 +	</listitem>
  34.507 +	<listitem><para>The default behaviour is to send unified diffs
  34.508 +	    (see section <xref linkend="sec.mq.patch"/> for a
  34.509 +	    description of the
  34.510 +	    format), one per message.  You can send a binary bundle
  34.511 +	    instead with the <option
  34.512 +	      role="hg-ext-patchbomb-cmd-email-opt">hg -b</option>
  34.513 +	    option.</para>
  34.514 +	</listitem>
  34.515 +	<listitem><para>Unified diffs are normally prefaced with a
  34.516 +	    metadata header.  You can omit this, and send unadorned
  34.517 +	    diffs, with the <option
  34.518 +	      role="hg-ext-patchbomb-cmd-email-opt">hg
  34.519 +	      --plain</option> option.</para>
  34.520 +	</listitem>
  34.521 +	<listitem><para>Diffs are normally sent <quote>inline</quote>,
  34.522 +	    in the same body part as the description of a patch.  This
  34.523 +	    makes it easiest for the largest number of readers to
  34.524 +	    quote and respond to parts of a diff, as some mail clients
  34.525 +	    will only quote the first MIME body part in a message. If
  34.526 +	    you'd prefer to send the description and the diff in
  34.527 +	    separate body parts, use the <option
  34.528 +	      role="hg-ext-patchbomb-cmd-email-opt">hg -a</option>
  34.529 +	    option.</para>
  34.530 +	</listitem>
  34.531 +	<listitem><para>Instead of sending mail messages, you can
  34.532 +	    write them to an <literal>mbox</literal>-format mail
  34.533 +	    folder using the <option
  34.534 +	      role="hg-ext-patchbomb-cmd-email-opt">hg -m</option>
  34.535 +	    option.  That option takes one argument, the name of the
  34.536 +	    file to write to.</para>
  34.537 +	</listitem>
  34.538 +	<listitem><para>If you would like to add a
  34.539 +	    <command>diffstat</command>-format summary to each patch,
  34.540 +	    and one to the introductory message, use the <option
  34.541 +	      role="hg-ext-patchbomb-cmd-email-opt">hg -d</option>
  34.542 +	    option.  The <command>diffstat</command> command displays
  34.543 +	    a table containing the name of each file patched, the
  34.544 +	    number of lines affected, and a histogram showing how much
  34.545 +	    each file is modified.  This gives readers a qualitative
  34.546 +	    glance at how complex a patch is.</para>
  34.547 +	</listitem></itemizedlist>
  34.548 +
  34.549 +    </sect2>
  34.550 +  </sect1>
  34.551 +</chapter>
  34.552 +
  34.553 +<!--
  34.554 +local variables: 
  34.555 +sgml-parent-document: ("00book.xml" "book" "chapter")
  34.556 +end:
  34.557 +-->
    35.1 --- a/en/ch13-mq-collab.xml	Fri Mar 20 15:40:06 2009 +0800
    35.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.3 @@ -1,518 +0,0 @@
    35.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    35.5 -
    35.6 -<chapter id="chap.mq-collab">
    35.7 -  <?dbhtml filename="advanced-uses-of-mercurial-queues.html"?>
    35.8 -  <title>Advanced uses of Mercurial Queues</title>
    35.9 -
   35.10 -  <para>While it's easy to pick up straightforward uses of Mercurial
   35.11 -    Queues, use of a little discipline and some of MQ's less
   35.12 -    frequently used capabilities makes it possible to work in
   35.13 -    complicated development environments.</para>
   35.14 -
   35.15 -  <para>In this chapter, I will use as an example a technique I have
   35.16 -    used to manage the development of an Infiniband device driver for
   35.17 -    the Linux kernel.  The driver in question is large (at least as
   35.18 -    drivers go), with 25,000 lines of code spread across 35 source
   35.19 -    files.  It is maintained by a small team of developers.</para>
   35.20 -
   35.21 -  <para>While much of the material in this chapter is specific to
   35.22 -    Linux, the same principles apply to any code base for which you're
   35.23 -    not the primary owner, and upon which you need to do a lot of
   35.24 -    development.</para>
   35.25 -
   35.26 -  <sect1>
   35.27 -    <title>The problem of many targets</title>
   35.28 -
   35.29 -    <para>The Linux kernel changes rapidly, and has never been
   35.30 -      internally stable; developers frequently make drastic changes
   35.31 -      between releases. This means that a version of the driver that
   35.32 -      works well with a particular released version of the kernel will
   35.33 -      not even <emphasis>compile</emphasis> correctly against,
   35.34 -      typically, any other version.</para>
   35.35 -
   35.36 -    <para>To maintain a driver, we have to keep a number of distinct
   35.37 -      versions of Linux in mind.</para>
   35.38 -    <itemizedlist>
   35.39 -      <listitem><para>One target is the main Linux kernel development
   35.40 -	  tree. Maintenance of the code is in this case partly shared
   35.41 -	  by other developers in the kernel community, who make
   35.42 -	  <quote>drive-by</quote> modifications to the driver as they
   35.43 -	  develop and refine kernel subsystems.</para>
   35.44 -      </listitem>
   35.45 -      <listitem><para>We also maintain a number of
   35.46 -	  <quote>backports</quote> to older versions of the Linux
   35.47 -	  kernel, to support the needs of customers who are running
   35.48 -	  older Linux distributions that do not incorporate our
   35.49 -	  drivers.  (To <emphasis>backport</emphasis> a piece of code
   35.50 -	  is to modify it to work in an older version of its target
   35.51 -	  environment than the version it was developed for.)</para>
   35.52 -      </listitem>
   35.53 -      <listitem><para>Finally, we make software releases on a schedule
   35.54 -	  that is necessarily not aligned with those used by Linux
   35.55 -	  distributors and kernel developers, so that we can deliver
   35.56 -	  new features to customers without forcing them to upgrade
   35.57 -	  their entire kernels or distributions.</para>
   35.58 -      </listitem></itemizedlist>
   35.59 -
   35.60 -    <sect2>
   35.61 -      <title>Tempting approaches that don't work well</title>
   35.62 -
   35.63 -      <para>There are two <quote>standard</quote> ways to maintain a
   35.64 -	piece of software that has to target many different
   35.65 -	environments.</para>
   35.66 -
   35.67 -      <para>The first is to maintain a number of branches, each
   35.68 -	intended for a single target.  The trouble with this approach
   35.69 -	is that you must maintain iron discipline in the flow of
   35.70 -	changes between repositories. A new feature or bug fix must
   35.71 -	start life in a <quote>pristine</quote> repository, then
   35.72 -	percolate out to every backport repository.  Backport changes
   35.73 -	are more limited in the branches they should propagate to; a
   35.74 -	backport change that is applied to a branch where it doesn't
   35.75 -	belong will probably stop the driver from compiling.</para>
   35.76 -
   35.77 -      <para>The second is to maintain a single source tree filled with
   35.78 -	conditional statements that turn chunks of code on or off
   35.79 -	depending on the intended target.  Because these
   35.80 -	<quote>ifdefs</quote> are not allowed in the Linux kernel
   35.81 -	tree, a manual or automatic process must be followed to strip
   35.82 -	them out and yield a clean tree.  A code base maintained in
   35.83 -	this fashion rapidly becomes a rat's nest of conditional
   35.84 -	blocks that are difficult to understand and maintain.</para>
   35.85 -
   35.86 -      <para>Neither of these approaches is well suited to a situation
   35.87 -	where you don't <quote>own</quote> the canonical copy of a
   35.88 -	source tree.  In the case of a Linux driver that is
   35.89 -	distributed with the standard kernel, Linus's tree contains
   35.90 -	the copy of the code that will be treated by the world as
   35.91 -	canonical.  The upstream version of <quote>my</quote> driver
   35.92 -	can be modified by people I don't know, without me even
   35.93 -	finding out about it until after the changes show up in
   35.94 -	Linus's tree.</para>
   35.95 -
   35.96 -      <para>These approaches have the added weakness of making it
   35.97 -	difficult to generate well-formed patches to submit
   35.98 -	upstream.</para>
   35.99 -
  35.100 -      <para>In principle, Mercurial Queues seems like a good candidate
  35.101 -	to manage a development scenario such as the above.  While
  35.102 -	this is indeed the case, MQ contains a few added features that
  35.103 -	make the job more pleasant.</para>
  35.104 -
  35.105 -    </sect2>
  35.106 -  </sect1>
  35.107 -  <sect1>
  35.108 -    <title>Conditionally applying patches with guards</title>
  35.109 -
  35.110 -    <para>Perhaps the best way to maintain sanity with so many targets
  35.111 -      is to be able to choose specific patches to apply for a given
  35.112 -      situation.  MQ provides a feature called <quote>guards</quote>
  35.113 -      (which originates with quilt's <literal>guards</literal>
  35.114 -      command) that does just this.  To start off, let's create a
  35.115 -      simple repository for experimenting in.</para>
  35.116 -
  35.117 -    &interaction.mq.guards.init;
  35.118 -
  35.119 -    <para>This gives us a tiny repository that contains two patches
  35.120 -      that don't have any dependencies on each other, because they
  35.121 -      touch different files.</para>
  35.122 -
  35.123 -    <para>The idea behind conditional application is that you can
  35.124 -      <quote>tag</quote> a patch with a <emphasis>guard</emphasis>,
  35.125 -      which is simply a text string of your choosing, then tell MQ to
  35.126 -      select specific guards to use when applying patches.  MQ will
  35.127 -      then either apply, or skip over, a guarded patch, depending on
  35.128 -      the guards that you have selected.</para>
  35.129 -
  35.130 -    <para>A patch can have an arbitrary number of guards; each one is
  35.131 -      <emphasis>positive</emphasis> (<quote>apply this patch if this
  35.132 -	guard is selected</quote>) or <emphasis>negative</emphasis>
  35.133 -      (<quote>skip this patch if this guard is selected</quote>).  A
  35.134 -      patch with no guards is always applied.</para>
  35.135 -
  35.136 -  </sect1>
  35.137 -  <sect1>
  35.138 -    <title>Controlling the guards on a patch</title>
  35.139 -
  35.140 -    <para>The <command role="hg-ext-mq">qguard</command> command lets
  35.141 -      you determine which guards should apply to a patch, or display
  35.142 -      the guards that are already in effect. Without any arguments, it
  35.143 -      displays the guards on the current topmost patch.</para>
  35.144 -
  35.145 -      &interaction.mq.guards.qguard;
  35.146 -
  35.147 -    <para>To set a positive guard on a patch, prefix the name of the
  35.148 -      guard with a <quote><literal>+</literal></quote>.</para>
  35.149 -
  35.150 -      &interaction.mq.guards.qguard.pos;
  35.151 -
  35.152 -    <para>To set a negative guard
  35.153 -      on a patch, prefix the name of the guard with a
  35.154 -      <quote><literal>-</literal></quote>.</para>
  35.155 -
  35.156 -    &interaction.mq.guards.qguard.neg;
  35.157 -
  35.158 -    <note>
  35.159 -      <para>  The <command role="hg-ext-mq">qguard</command> command
  35.160 -	<emphasis>sets</emphasis> the guards on a patch; it doesn't
  35.161 -	<emphasis>modify</emphasis> them.  What this means is that if
  35.162 -	you run <command role="hg-cmd">hg qguard +a +b</command> on a
  35.163 -	patch, then <command role="hg-cmd">hg qguard +c</command> on
  35.164 -	the same patch, the <emphasis>only</emphasis> guard that will
  35.165 -	be set on it afterwards is <literal>+c</literal>.</para>
  35.166 -    </note>
  35.167 -
  35.168 -    <para>Mercurial stores guards in the <filename
  35.169 -	role="special">series</filename> file; the form in which they
  35.170 -      are stored is easy both to understand and to edit by hand. (In
  35.171 -      other words, you don't have to use the <command
  35.172 -	role="hg-ext-mq">qguard</command> command if you don't want
  35.173 -      to; it's okay to simply edit the <filename
  35.174 -	role="special">series</filename> file.)</para>
  35.175 -
  35.176 -    &interaction.mq.guards.series;
  35.177 -
  35.178 -  </sect1>
  35.179 -  <sect1>
  35.180 -    <title>Selecting the guards to use</title>
  35.181 -
  35.182 -    <para>The <command role="hg-ext-mq">qselect</command> command
  35.183 -      determines which guards are active at a given time.  The effect
  35.184 -      of this is to determine which patches MQ will apply the next
  35.185 -      time you run <command role="hg-ext-mq">qpush</command>.  It has
  35.186 -      no other effect; in particular, it doesn't do anything to
  35.187 -      patches that are already applied.</para>
  35.188 -
  35.189 -    <para>With no arguments, the <command
  35.190 -	role="hg-ext-mq">qselect</command> command lists the guards
  35.191 -      currently in effect, one per line of output.  Each argument is
  35.192 -      treated as the name of a guard to apply.</para>
  35.193 -
  35.194 -      &interaction.mq.guards.qselect.foo;
  35.195 -
  35.196 -    <para>In case you're interested, the currently selected guards are
  35.197 -      stored in the <filename role="special">guards</filename> file.</para>
  35.198 -
  35.199 -    &interaction.mq.guards.qselect.cat;
  35.200 -
  35.201 -    <para>We can see the effect the selected guards have when we run
  35.202 -      <command role="hg-ext-mq">qpush</command>.</para>
  35.203 -
  35.204 -    &interaction.mq.guards.qselect.qpush;
  35.205 -
  35.206 -    <para>A guard cannot start with a
  35.207 -      <quote><literal>+</literal></quote> or
  35.208 -      <quote><literal>-</literal></quote> character.  The name of a
  35.209 -      guard must not contain white space, but most other characters
  35.210 -      are acceptable.  If you try to use a guard with an invalid name,
  35.211 -      MQ will complain:</para>
  35.212 -
  35.213 -    &interaction.mq.guards.qselect.error;
  35.214 -      
  35.215 -    <para>Changing the selected guards changes the patches that are
  35.216 -      applied.</para>
  35.217 -
  35.218 -    &interaction.mq.guards.qselect.quux;
  35.219 -
  35.220 -    <para>You can see in the example below that negative guards take
  35.221 -      precedence over positive guards.</para>
  35.222 -
  35.223 -    &interaction.mq.guards.qselect.foobar;
  35.224 -
  35.225 -  </sect1>
  35.226 -  <sect1>
  35.227 -    <title>MQ's rules for applying patches</title>
  35.228 -
  35.229 -    <para>The rules that MQ uses when deciding whether to apply a
  35.230 -      patch are as follows.</para>
  35.231 -    <itemizedlist>
  35.232 -      <listitem><para>A patch that has no guards is always
  35.233 -	  applied.</para>
  35.234 -      </listitem>
  35.235 -      <listitem><para>If the patch has any negative guard that matches
  35.236 -	  any currently selected guard, the patch is skipped.</para>
  35.237 -      </listitem>
  35.238 -      <listitem><para>If the patch has any positive guard that matches
  35.239 -	  any currently selected guard, the patch is applied.</para>
  35.240 -      </listitem>
  35.241 -      <listitem><para>If the patch has positive or negative guards,
  35.242 -	  but none matches any currently selected guard, the patch is
  35.243 -	  skipped.</para>
  35.244 -      </listitem></itemizedlist>
  35.245 -
  35.246 -  </sect1>
  35.247 -  <sect1>
  35.248 -    <title>Trimming the work environment</title>
  35.249 -
  35.250 -    <para>In working on the device driver I mentioned earlier, I don't
  35.251 -      apply the patches to a normal Linux kernel tree.  Instead, I use
  35.252 -      a repository that contains only a snapshot of the source files
  35.253 -      and headers that are relevant to Infiniband development.  This
  35.254 -      repository is 1% the size of a kernel repository, so it's easier
  35.255 -      to work with.</para>
  35.256 -
  35.257 -    <para>I then choose a <quote>base</quote> version on top of which
  35.258 -      the patches are applied.  This is a snapshot of the Linux kernel
  35.259 -      tree as of a revision of my choosing.  When I take the snapshot,
  35.260 -      I record the changeset ID from the kernel repository in the
  35.261 -      commit message.  Since the snapshot preserves the
  35.262 -      <quote>shape</quote> and content of the relevant parts of the
  35.263 -      kernel tree, I can apply my patches on top of either my tiny
  35.264 -      repository or a normal kernel tree.</para>
  35.265 -
  35.266 -    <para>Normally, the base tree atop which the patches apply should
  35.267 -      be a snapshot of a very recent upstream tree.  This best
  35.268 -      facilitates the development of patches that can easily be
  35.269 -      submitted upstream with few or no modifications.</para>
  35.270 -
  35.271 -  </sect1>
  35.272 -  <sect1>
  35.273 -    <title>Dividing up the <filename role="special">series</filename>
  35.274 -      file</title>
  35.275 -
  35.276 -    <para>I categorise the patches in the <filename
  35.277 -	role="special">series</filename> file into a number of logical
  35.278 -      groups.  Each section of like patches begins with a block of
  35.279 -      comments that describes the purpose of the patches that
  35.280 -      follow.</para>
  35.281 -
  35.282 -    <para>The sequence of patch groups that I maintain follows.  The
  35.283 -      ordering of these groups is important; I'll describe why after I
  35.284 -      introduce the groups.</para>
  35.285 -    <itemizedlist>
  35.286 -      <listitem><para>The <quote>accepted</quote> group.  Patches that
  35.287 -	  the development team has submitted to the maintainer of the
  35.288 -	  Infiniband subsystem, and which he has accepted, but which
  35.289 -	  are not present in the snapshot that the tiny repository is
  35.290 -	  based on.  These are <quote>read only</quote> patches,
  35.291 -	  present only to transform the tree into a similar state as
  35.292 -	  it is in the upstream maintainer's repository.</para>
  35.293 -      </listitem>
  35.294 -      <listitem><para>The <quote>rework</quote> group.  Patches that I
  35.295 -	  have submitted, but that the upstream maintainer has
  35.296 -	  requested modifications to before he will accept
  35.297 -	  them.</para>
  35.298 -      </listitem>
  35.299 -      <listitem><para>The <quote>pending</quote> group.  Patches that
  35.300 -	  I have not yet submitted to the upstream maintainer, but
  35.301 -	  which we have finished working on. These will be <quote>read
  35.302 -	    only</quote> for a while.  If the upstream maintainer
  35.303 -	  accepts them upon submission, I'll move them to the end of
  35.304 -	  the <quote>accepted</quote> group.  If he requests that I
  35.305 -	  modify any, I'll move them to the beginning of the
  35.306 -	  <quote>rework</quote> group.</para>
  35.307 -      </listitem>
  35.308 -      <listitem><para>The <quote>in progress</quote> group.  Patches
  35.309 -	  that are actively being developed, and should not be
  35.310 -	  submitted anywhere yet.</para>
  35.311 -      </listitem>
  35.312 -      <listitem><para>The <quote>backport</quote> group.  Patches that
  35.313 -	  adapt the source tree to older versions of the kernel
  35.314 -	  tree.</para>
  35.315 -      </listitem>
  35.316 -      <listitem><para>The <quote>do not ship</quote> group.  Patches
  35.317 -	  that for some reason should never be submitted upstream.
  35.318 -	  For example, one such patch might change embedded driver
  35.319 -	  identification strings to make it easier to distinguish, in
  35.320 -	  the field, between an out-of-tree version of the driver and
  35.321 -	  a version shipped by a distribution vendor.</para>
  35.322 -      </listitem></itemizedlist>
  35.323 -
  35.324 -    <para>Now to return to the reasons for ordering groups of patches
  35.325 -      in this way.  We would like the lowest patches in the stack to
  35.326 -      be as stable as possible, so that we will not need to rework
  35.327 -      higher patches due to changes in context.  Putting patches that
  35.328 -      will never be changed first in the <filename
  35.329 -	role="special">series</filename> file serves this
  35.330 -      purpose.</para>
  35.331 -
  35.332 -    <para>We would also like the patches that we know we'll need to
  35.333 -      modify to be applied on top of a source tree that resembles the
  35.334 -      upstream tree as closely as possible.  This is why we keep
  35.335 -      accepted patches around for a while.</para>
  35.336 -
  35.337 -    <para>The <quote>backport</quote> and <quote>do not ship</quote>
  35.338 -      patches float at the end of the <filename
  35.339 -	role="special">series</filename> file.  The backport patches
  35.340 -      must be applied on top of all other patches, and the <quote>do
  35.341 -	not ship</quote> patches might as well stay out of harm's
  35.342 -      way.</para>
  35.343 -
  35.344 -  </sect1>
  35.345 -  <sect1>
  35.346 -    <title>Maintaining the patch series</title>
  35.347 -
  35.348 -    <para>In my work, I use a number of guards to control which
  35.349 -      patches are to be applied.</para>
  35.350 -
  35.351 -    <itemizedlist>
  35.352 -      <listitem><para><quote>Accepted</quote> patches are guarded with
  35.353 -	  <literal>accepted</literal>.  I enable this guard most of
  35.354 -	  the time.  When I'm applying the patches on top of a tree
  35.355 -	  where the patches are already present, I can turn this patch
  35.356 -	  off, and the patches that follow it will apply
  35.357 -	  cleanly.</para>
  35.358 -      </listitem>
  35.359 -      <listitem><para>Patches that are <quote>finished</quote>, but
  35.360 -	  not yet submitted, have no guards.  If I'm applying the
  35.361 -	  patch stack to a copy of the upstream tree, I don't need to
  35.362 -	  enable any guards in order to get a reasonably safe source
  35.363 -	  tree.</para>
  35.364 -      </listitem>
  35.365 -      <listitem><para>Those patches that need reworking before being
  35.366 -	  resubmitted are guarded with
  35.367 -	  <literal>rework</literal>.</para>
  35.368 -      </listitem>
  35.369 -      <listitem><para>For those patches that are still under
  35.370 -	  development, I use <literal>devel</literal>.</para>
  35.371 -      </listitem>
  35.372 -      <listitem><para>A backport patch may have several guards, one
  35.373 -	  for each version of the kernel to which it applies.  For
  35.374 -	  example, a patch that backports a piece of code to 2.6.9
  35.375 -	  will have a <literal>2.6.9</literal> guard.</para>
  35.376 -      </listitem></itemizedlist>
  35.377 -    <para>This variety of guards gives me considerable flexibility in
  35.378 -      determining what kind of source tree I want to end up with.  For
  35.379 -      most situations, the selection of appropriate guards is
  35.380 -      automated during the build process, but I can manually tune the
  35.381 -      guards to use for less common circumstances.</para>
  35.382 -
  35.383 -    <sect2>
  35.384 -      <title>The art of writing backport patches</title>
  35.385 -
  35.386 -      <para>Using MQ, writing a backport patch is a simple process.
  35.387 -	All such a patch has to do is modify a piece of code that uses
  35.388 -	a kernel feature not present in the older version of the
  35.389 -	kernel, so that the driver continues to work correctly under
  35.390 -	that older version.</para>
  35.391 -
  35.392 -      <para>A useful goal when writing a good backport patch is to
  35.393 -	make your code look as if it was written for the older version
  35.394 -	of the kernel you're targeting.  The less obtrusive the patch,
  35.395 -	the easier it will be to understand and maintain.  If you're
  35.396 -	writing a collection of backport patches to avoid the
  35.397 -	<quote>rat's nest</quote> effect of lots of
  35.398 -	<literal>#ifdef</literal>s (hunks of source code that are only
  35.399 -	used conditionally) in your code, don't introduce
  35.400 -	version-dependent <literal>#ifdef</literal>s into the patches.
  35.401 -	Instead, write several patches, each of which makes
  35.402 -	unconditional changes, and control their application using
  35.403 -	guards.</para>
  35.404 -
  35.405 -      <para>There are two reasons to divide backport patches into a
  35.406 -	distinct group, away from the <quote>regular</quote> patches
  35.407 -	whose effects they modify. The first is that intermingling the
  35.408 -	two makes it more difficult to use a tool like the <literal
  35.409 -	  role="hg-ext">patchbomb</literal> extension to automate the
  35.410 -	process of submitting the patches to an upstream maintainer.
  35.411 -	The second is that a backport patch could perturb the context
  35.412 -	in which a subsequent regular patch is applied, making it
  35.413 -	impossible to apply the regular patch cleanly
  35.414 -	<emphasis>without</emphasis> the earlier backport patch
  35.415 -	already being applied.</para>
  35.416 -
  35.417 -    </sect2>
  35.418 -  </sect1>
  35.419 -  <sect1>
  35.420 -    <title>Useful tips for developing with MQ</title>
  35.421 -
  35.422 -    <sect2>
  35.423 -      <title>Organising patches in directories</title>
  35.424 -
  35.425 -      <para>If you're working on a substantial project with MQ, it's
  35.426 -	not difficult to accumulate a large number of patches.  For
  35.427 -	example, I have one patch repository that contains over 250
  35.428 -	patches.</para>
  35.429 -
  35.430 -      <para>If you can group these patches into separate logical
  35.431 -	categories, you can if you like store them in different
  35.432 -	directories; MQ has no problems with patch names that contain
  35.433 -	path separators.</para>
  35.434 -
  35.435 -    </sect2>
  35.436 -    <sect2 id="mq-collab.tips.interdiff">
  35.437 -      <title>Viewing the history of a patch</title>
  35.438 -
  35.439 -      <para>If you're developing a set of patches over a long time,
  35.440 -	it's a good idea to maintain them in a repository, as
  35.441 -	discussed in section <xref linkend="sec.mq.repo"/>.  If you do
  35.442 -	so, you'll quickly
  35.443 -	discover that using the <command role="hg-cmd">hg
  35.444 -	  diff</command> command to look at the history of changes to
  35.445 -	a patch is unworkable.  This is in part because you're looking
  35.446 -	at the second derivative of the real code (a diff of a diff),
  35.447 -	but also because MQ adds noise to the process by modifying
  35.448 -	time stamps and directory names when it updates a
  35.449 -	patch.</para>
  35.450 -
  35.451 -      <para>However, you can use the <literal
  35.452 -	  role="hg-ext">extdiff</literal> extension, which is bundled
  35.453 -	with Mercurial, to turn a diff of two versions of a patch into
  35.454 -	something readable.  To do this, you will need a third-party
  35.455 -	package called <literal role="package">patchutils</literal>
  35.456 -	<citation>web:patchutils</citation>.  This provides a command
  35.457 -	named <command>interdiff</command>, which shows the
  35.458 -	differences between two diffs as a diff.  Used on two versions
  35.459 -	of the same diff, it generates a diff that represents the diff
  35.460 -	from the first to the second version.</para>
  35.461 -
  35.462 -      <para>You can enable the <literal
  35.463 -	  role="hg-ext">extdiff</literal> extension in the usual way,
  35.464 -	by adding a line to the <literal
  35.465 -	  role="rc-extensions">extensions</literal> section of your
  35.466 -	<filename role="special">~/.hgrc</filename>.</para>
  35.467 -      <programlisting>[extensions]
  35.468 -extdiff =</programlisting>
  35.469 -      <para>The <command>interdiff</command> command expects to be
  35.470 -	passed the names of two files, but the <literal
  35.471 -	  role="hg-ext">extdiff</literal> extension passes the program
  35.472 -	it runs a pair of directories, each of which can contain an
  35.473 -	arbitrary number of files.  We thus need a small program that
  35.474 -	will run <command>interdiff</command> on each pair of files in
  35.475 -	these two directories.  This program is available as <filename
  35.476 -	  role="special">hg-interdiff</filename> in the <filename
  35.477 -	  class="directory">examples</filename> directory of the
  35.478 -	source code repository that accompanies this book. <!--
  35.479 -	&example.hg-interdiff; --></para>
  35.480 -
  35.481 -      <para>With the <filename role="special">hg-interdiff</filename>
  35.482 -	program in your shell's search path, you can run it as
  35.483 -	follows, from inside an MQ patch directory:</para>
  35.484 -      <programlisting>hg extdiff -p hg-interdiff -r A:B my-change.patch</programlisting>
  35.485 -      <para>Since you'll probably want to use this long-winded command
  35.486 -	a lot, you can get <literal role="hg-ext">hgext</literal> to
  35.487 -	make it available as a normal Mercurial command, again by
  35.488 -	editing your <filename
  35.489 -	  role="special">~/.hgrc</filename>.</para>
  35.490 -      <programlisting>[extdiff]
  35.491 -cmd.interdiff = hg-interdiff</programlisting>
  35.492 -      <para>This directs <literal role="hg-ext">hgext</literal> to
  35.493 -	make an <literal>interdiff</literal> command available, so you
  35.494 -	can now shorten the previous invocation of <command
  35.495 -	  role="hg-ext-extdiff">extdiff</command> to something a
  35.496 -	little more wieldy.</para>
  35.497 -      <programlisting>hg interdiff -r A:B my-change.patch</programlisting>
  35.498 -
  35.499 -      <note>
  35.500 -	<para>  The <command>interdiff</command> command works well
  35.501 -	  only if the underlying files against which versions of a
  35.502 -	  patch are generated remain the same.  If you create a patch,
  35.503 -	  modify the underlying files, and then regenerate the patch,
  35.504 -	  <command>interdiff</command> may not produce useful
  35.505 -	  output.</para>
  35.506 -      </note>
  35.507 -
  35.508 -      <para>The <literal role="hg-ext">extdiff</literal> extension is
  35.509 -	useful for more than merely improving the presentation of MQ
  35.510 -	patches.  To read more about it, go to section <xref
  35.511 -	  linkend="sec.hgext.extdiff"/>.</para>
  35.512 -
  35.513 -    </sect2>
  35.514 -  </sect1>
  35.515 -</chapter>
  35.516 -
  35.517 -<!--
  35.518 -local variables: 
  35.519 -sgml-parent-document: ("00book.xml" "book" "chapter")
  35.520 -end:
  35.521 --->
    36.1 --- a/en/ch14-hgext.xml	Fri Mar 20 15:40:06 2009 +0800
    36.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.3 @@ -1,554 +0,0 @@
    36.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
    36.5 -
    36.6 -<chapter id="chap.hgext">
    36.7 -  <?dbhtml filename="adding-functionality-with-extensions.html"?>
    36.8 -  <title>Adding functionality with extensions</title>
    36.9 -
   36.10 -  <para>While the core of Mercurial is quite complete from a
   36.11 -    functionality standpoint, it's deliberately shorn of fancy
   36.12 -    features.  This approach of preserving simplicity keeps the
   36.13 -    software easy to deal with for both maintainers and users.</para>
   36.14 -
   36.15 -  <para>However, Mercurial doesn't box you in with an inflexible
   36.16 -    command set: you can add features to it as
   36.17 -    <emphasis>extensions</emphasis> (sometimes known as
   36.18 -    <emphasis>plugins</emphasis>).  We've already discussed a few of
   36.19 -    these extensions in earlier chapters.</para>
   36.20 -  <itemizedlist>
   36.21 -    <listitem><para>Section <xref linkend="sec.tour-merge.fetch"/>
   36.22 -	covers the <literal role="hg-ext">fetch</literal> extension;
   36.23 -	this combines pulling new changes and merging them with local
   36.24 -	changes into a single command, <command
   36.25 -	  role="hg-ext-fetch">fetch</command>.</para>
   36.26 -    </listitem>
   36.27 -    <listitem><para>In chapter <xref linkend="chap.hook"/>, we covered
   36.28 -	several extensions that are useful for hook-related
   36.29 -	functionality: <literal role="hg-ext">acl</literal> adds
   36.30 -	access control lists; <literal
   36.31 -	  role="hg-ext">bugzilla</literal> adds integration with the
   36.32 -	Bugzilla bug tracking system; and <literal
   36.33 -	  role="hg-ext">notify</literal> sends notification emails on
   36.34 -	new changes.</para>
   36.35 -    </listitem>
   36.36 -    <listitem><para>The Mercurial Queues patch management extension is
   36.37 -	so invaluable that it merits two chapters and an appendix all
   36.38 -	to itself. Chapter <xref linkend="chap.mq"/> covers the
   36.39 -	basics; chapter <xref
   36.40 -	  linkend="chap.mq-collab"/> discusses advanced topics;
   36.41 -	and appendix <xref linkend="chap.mqref"/> goes into detail on
   36.42 -	each
   36.43 -	command.</para>
   36.44 -    </listitem></itemizedlist>
   36.45 -
   36.46 -  <para>In this chapter, we'll cover some of the other extensions that
   36.47 -    are available for Mercurial, and briefly touch on some of the
   36.48 -    machinery you'll need to know about if you want to write an
   36.49 -    extension of your own.</para>
   36.50 -  <itemizedlist>
   36.51 -    <listitem><para>In section <xref linkend="sec.hgext.inotify"/>,
   36.52 -	we'll discuss the possibility of <emphasis>huge</emphasis>
   36.53 -	performance improvements using the <literal
   36.54 -	  role="hg-ext">inotify</literal> extension.</para>
   36.55 -    </listitem></itemizedlist>
   36.56 -
   36.57 -  <sect1 id="sec.hgext.inotify">
   36.58 -    <title>Improve performance with the <literal
   36.59 -	role="hg-ext">inotify</literal> extension</title>
   36.60 -
   36.61 -    <para>Are you interested in having some of the most common
   36.62 -      Mercurial operations run as much as a hundred times faster?
   36.63 -      Read on!</para>
   36.64 -
   36.65 -    <para>Mercurial has great performance under normal circumstances.
   36.66 -      For example, when you run the <command role="hg-cmd">hg
   36.67 -	status</command> command, Mercurial has to scan almost every
   36.68 -      directory and file in your repository so that it can display
   36.69 -      file status.  Many other Mercurial commands need to do the same
   36.70 -      work behind the scenes; for example, the <command
   36.71 -	role="hg-cmd">hg diff</command> command uses the status
   36.72 -      machinery to avoid doing an expensive comparison operation on
   36.73 -      files that obviously haven't changed.</para>
   36.74 -
   36.75 -    <para>Because obtaining file status is crucial to good
   36.76 -      performance, the authors of Mercurial have optimised this code
   36.77 -      to within an inch of its life.  However, there's no avoiding the
   36.78 -      fact that when you run <command role="hg-cmd">hg
   36.79 -	status</command>, Mercurial is going to have to perform at
   36.80 -      least one expensive system call for each managed file to
   36.81 -      determine whether it's changed since the last time Mercurial
   36.82 -      checked.  For a sufficiently large repository, this can take a
   36.83 -      long time.</para>
   36.84 -
   36.85 -    <para>To put a number on the magnitude of this effect, I created a
   36.86 -      repository containing 150,000 managed files.  I timed <command
   36.87 -	role="hg-cmd">hg status</command> as taking ten seconds to
   36.88 -      run, even when <emphasis>none</emphasis> of those files had been
   36.89 -      modified.</para>
   36.90 -
   36.91 -    <para>Many modern operating systems contain a file notification
   36.92 -      facility. If a program signs up to an appropriate service, the
   36.93 -      operating system will notify it every time a file of interest is
   36.94 -      created, modified, or deleted.  On Linux systems, the kernel
   36.95 -      component that does this is called
   36.96 -      <literal>inotify</literal>.</para>
   36.97 -
   36.98 -    <para>Mercurial's <literal role="hg-ext">inotify</literal>
   36.99 -      extension talks to the kernel's <literal>inotify</literal>
  36.100 -      component to optimise <command role="hg-cmd">hg status</command>
  36.101 -      commands.  The extension has two components.  A daemon sits in
  36.102 -      the background and receives notifications from the
  36.103 -      <literal>inotify</literal> subsystem.  It also listens for
  36.104 -      connections from a regular Mercurial command.  The extension
  36.105 -      modifies Mercurial's behaviour so that instead of scanning the
  36.106 -      filesystem, it queries the daemon.  Since the daemon has perfect
  36.107 -      information about the state of the repository, it can respond
  36.108 -      with a result instantaneously, avoiding the need to scan every
  36.109 -      directory and file in the repository.</para>
  36.110 -
  36.111 -    <para>Recall the ten seconds that I measured plain Mercurial as
  36.112 -      taking to run <command role="hg-cmd">hg status</command> on a
  36.113 -      150,000 file repository.  With the <literal
  36.114 -	role="hg-ext">inotify</literal> extension enabled, the time
  36.115 -      dropped to 0.1 seconds, a factor of <emphasis>one
  36.116 -	hundred</emphasis> faster.</para>
  36.117 -
  36.118 -    <para>Before we continue, please pay attention to some
  36.119 -      caveats.</para>
  36.120 -    <itemizedlist>
  36.121 -      <listitem><para>The <literal role="hg-ext">inotify</literal>
  36.122 -	  extension is Linux-specific.  Because it interfaces directly
  36.123 -	  to the Linux kernel's <literal>inotify</literal> subsystem,
  36.124 -	  it does not work on other operating systems.</para>
  36.125 -      </listitem>
  36.126 -      <listitem><para>It should work on any Linux distribution that
  36.127 -	  was released after early 2005.  Older distributions are
  36.128 -	  likely to have a kernel that lacks
  36.129 -	  <literal>inotify</literal>, or a version of
  36.130 -	  <literal>glibc</literal> that does not have the necessary
  36.131 -	  interfacing support.</para>
  36.132 -      </listitem>
  36.133 -      <listitem><para>Not all filesystems are suitable for use with
  36.134 -	  the <literal role="hg-ext">inotify</literal> extension.
  36.135 -	  Network filesystems such as NFS are a non-starter, for
  36.136 -	  example, particularly if you're running Mercurial on several
  36.137 -	  systems, all mounting the same network filesystem.  The
  36.138 -	  kernel's <literal>inotify</literal> system has no way of
  36.139 -	  knowing about changes made on another system.  Most local
  36.140 -	  filesystems (e.g. ext3, XFS, ReiserFS) should work
  36.141 -	  fine.</para>
  36.142 -      </listitem></itemizedlist>
  36.143 -
  36.144 -    <para>The <literal role="hg-ext">inotify</literal> extension is
  36.145 -      not yet shipped with Mercurial as of May 2007, so it's a little
  36.146 -      more involved to set up than other extensions.  But the
  36.147 -      performance improvement is worth it!</para>
  36.148 -
  36.149 -    <para>The extension currently comes in two parts: a set of patches
  36.150 -      to the Mercurial source code, and a library of Python bindings
  36.151 -      to the <literal>inotify</literal> subsystem.</para>
  36.152 -    <note>
  36.153 -      <para>  There are <emphasis>two</emphasis> Python
  36.154 -	<literal>inotify</literal> binding libraries.  One of them is
  36.155 -	called <literal>pyinotify</literal>, and is packaged by some
  36.156 -	Linux distributions as <literal>python-inotify</literal>.
  36.157 -	This is <emphasis>not</emphasis> the one you'll need, as it is
  36.158 -	too buggy and inefficient to be practical.</para>
  36.159 -    </note>
  36.160 -    <para>To get going, it's best to already have a functioning copy
  36.161 -      of Mercurial installed.</para>
  36.162 -    <note>
  36.163 -      <para>  If you follow the instructions below, you'll be
  36.164 -	<emphasis>replacing</emphasis> and overwriting any existing
  36.165 -	installation of Mercurial that you might already have, using
  36.166 -	the latest <quote>bleeding edge</quote> Mercurial code. Don't
  36.167 -	say you weren't warned!</para>
  36.168 -    </note>
  36.169 -    <orderedlist>
  36.170 -      <listitem><para>Clone the Python <literal>inotify</literal>
  36.171 -	  binding repository.  Build and install it.</para>
  36.172 -	<programlisting>hg clone http://hg.kublai.com/python/inotify
  36.173 -cd inotify
  36.174 -python setup.py build --force
  36.175 -sudo python setup.py install --skip-build</programlisting>
  36.176 -      </listitem>
  36.177 -      <listitem><para>Clone the <filename
  36.178 -	    class="directory">crew</filename> Mercurial repository.
  36.179 -	  Clone the <literal role="hg-ext">inotify</literal> patch
  36.180 -	  repository so that Mercurial Queues will be able to apply
  36.181 -	  patches to your cope of the <filename
  36.182 -	    class="directory">crew</filename> repository.</para>
  36.183 -	<programlisting>hg clone http://hg.intevation.org/mercurial/crew
  36.184 -hg clone crew inotify
  36.185 -hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches</programlisting>
  36.186 -      </listitem>
  36.187 -      <listitem><para>Make sure that you have the Mercurial Queues
  36.188 -	  extension, <literal role="hg-ext">mq</literal>, enabled.  If
  36.189 -	  you've never used MQ, read section <xref
  36.190 -	    linkend="sec.mq.start"/> to get started
  36.191 -	  quickly.</para>
  36.192 -      </listitem>
  36.193 -      <listitem><para>Go into the <filename
  36.194 -	    class="directory">inotify</filename> repo, and apply all
  36.195 -	  of the <literal role="hg-ext">inotify</literal> patches
  36.196 -	  using the <option role="hg-ext-mq-cmd-qpush-opt">hg
  36.197 -	    -a</option> option to the <command
  36.198 -	    role="hg-ext-mq">qpush</command> command.</para>
  36.199 -	<programlisting>cd inotify
  36.200 -hg qpush -a</programlisting>
  36.201 -      </listitem>
  36.202 -      <listitem><para>  If you get an error message from <command
  36.203 -	    role="hg-ext-mq">qpush</command>, you should not continue.
  36.204 -	  Instead, ask for help.</para>
  36.205 -      </listitem>
  36.206 -      <listitem><para>Build and install the patched version of
  36.207 -	  Mercurial.</para>
  36.208 -	<programlisting>python setup.py build --force
  36.209 -sudo python setup.py install --skip-build</programlisting>
  36.210 -      </listitem>
  36.211 -    </orderedlist>
  36.212 -    <para>Once you've build a suitably patched version of Mercurial,
  36.213 -      all you need to do to enable the <literal
  36.214 -	role="hg-ext">inotify</literal> extension is add an entry to
  36.215 -      your <filename role="special">~/.hgrc</filename>.</para>
  36.216 -    <programlisting>[extensions] inotify =</programlisting>
  36.217 -    <para>When the <literal role="hg-ext">inotify</literal> extension
  36.218 -      is enabled, Mercurial will automatically and transparently start
  36.219 -      the status daemon the first time you run a command that needs
  36.220 -      status in a repository.  It runs one status daemon per
  36.221 -      repository.</para>
  36.222 -
  36.223 -    <para>The status daemon is started silently, and runs in the
  36.224 -      background.  If you look at a list of running processes after
  36.225 -      you've enabled the <literal role="hg-ext">inotify</literal>
  36.226 -      extension and run a few commands in different repositories,
  36.227 -      you'll thus see a few <literal>hg</literal> processes sitting
  36.228 -      around, waiting for updates from the kernel and queries from
  36.229 -      Mercurial.</para>
  36.230 -
  36.231 -    <para>The first time you run a Mercurial command in a repository
  36.232 -      when you have the <literal role="hg-ext">inotify</literal>
  36.233 -      extension enabled, it will run with about the same performance
  36.234 -      as a normal Mercurial command.  This is because the status
  36.235 -      daemon needs to perform a normal status scan so that it has a
  36.236 -      baseline against which to apply later updates from the kernel.
  36.237 -      However, <emphasis>every</emphasis> subsequent command that does
  36.238 -      any kind of status check should be noticeably faster on
  36.239 -      repositories of even fairly modest size.  Better yet, the bigger
  36.240 -      your repository is, the greater a performance advantage you'll
  36.241 -      see.  The <literal role="hg-ext">inotify</literal> daemon makes
  36.242 -      status operations almost instantaneous on repositories of all
  36.243 -      sizes!</para>
  36.244 -
  36.245 -    <para>If you like, you can manually start a status daemon using
  36.246 -      the <command role="hg-ext-inotify">inserve</command> command.
  36.247 -      This gives you slightly finer control over how the daemon ought
  36.248 -      to run.  This command will of course only be available when the
  36.249 -      <literal role="hg-ext">inotify</literal> extension is
  36.250 -      enabled.</para>
  36.251 -
  36.252 -    <para>When you're using the <literal
  36.253 -	role="hg-ext">inotify</literal> extension, you should notice
  36.254 -      <emphasis>no difference at all</emphasis> in Mercurial's
  36.255 -      behaviour, with the sole exception of status-related commands
  36.256 -      running a whole lot faster than they used to.  You should
  36.257 -      specifically expect that commands will not print different
  36.258 -      output; neither should they give different results. If either of
  36.259 -      these situations occurs, please report a bug.</para>
  36.260 -
  36.261 -  </sect1>
  36.262 -  <sect1 id="sec.hgext.extdiff">
  36.263 -    <title>Flexible diff support with the <literal
  36.264 -	role="hg-ext">extdiff</literal> extension</title>
  36.265 -
  36.266 -    <para>Mercurial's built-in <command role="hg-cmd">hg
  36.267 -	diff</command> command outputs plaintext unified diffs.</para>
  36.268 -
  36.269 -    &interaction.extdiff.diff;
  36.270 -
  36.271 -    <para>If you would like to use an external tool to display
  36.272 -      modifications, you'll want to use the <literal
  36.273 -	role="hg-ext">extdiff</literal> extension.  This will let you
  36.274 -      use, for example, a graphical diff tool.</para>
  36.275 -
  36.276 -    <para>The <literal role="hg-ext">extdiff</literal> extension is
  36.277 -      bundled with Mercurial, so it's easy to set up.  In the <literal
  36.278 -	role="rc-extensions">extensions</literal> section of your
  36.279 -      <filename role="special">~/.hgrc</filename>, simply add a
  36.280 -      one-line entry to enable the extension.</para>
  36.281 -    <programlisting>[extensions]
  36.282 -extdiff =</programlisting>
  36.283 -    <para>This introduces a command named <command
  36.284 -	role="hg-ext-extdiff">extdiff</command>, which by default uses
  36.285 -      your system's <command>diff</command> command to generate a
  36.286 -      unified diff in the same form as the built-in <command
  36.287 -	role="hg-cmd">hg diff</command> command.</para>
  36.288 -    
  36.289 -    &interaction.extdiff.extdiff;
  36.290 -
  36.291 -    <para>The result won't be exactly the same as with the built-in
  36.292 -      <command role="hg-cmd">hg diff</command> variations, because the
  36.293 -      output of <command>diff</command> varies from one system to
  36.294 -      another, even when passed the same options.</para>
  36.295 -
  36.296 -    <para>As the <quote><literal>making snapshot</literal></quote>
  36.297 -      lines of output above imply, the <command
  36.298 -	role="hg-ext-extdiff">extdiff</command> command works by
  36.299 -      creating two snapshots of your source tree.  The first snapshot
  36.300 -      is of the source revision; the second, of the target revision or
  36.301 -      working directory.  The <command
  36.302 -	role="hg-ext-extdiff">extdiff</command> command generates
  36.303 -      these snapshots in a temporary directory, passes the name of
  36.304 -      each directory to an external diff viewer, then deletes the
  36.305 -      temporary directory.  For efficiency, it only snapshots the
  36.306 -      directories and files that have changed between the two
  36.307 -      revisions.</para>
  36.308 -
  36.309 -    <para>Snapshot directory names have the same base name as your
  36.310 -      repository. If your repository path is <filename
  36.311 -	class="directory">/quux/bar/foo</filename>, then <filename
  36.312 -	class="directory">foo</filename> will be the name of each
  36.313 -      snapshot directory.  Each snapshot directory name has its
  36.314 -      changeset ID appended, if appropriate.  If a snapshot is of
  36.315 -      revision <literal>a631aca1083f</literal>, the directory will be
  36.316 -      named <filename class="directory">foo.a631aca1083f</filename>.
  36.317 -      A snapshot of the working directory won't have a changeset ID
  36.318 -      appended, so it would just be <filename
  36.319 -	class="directory">foo</filename> in this example.  To see what
  36.320 -      this looks like in practice, look again at the <command
  36.321 -	role="hg-ext-extdiff">extdiff</command> example above.  Notice
  36.322 -      that the diff has the snapshot directory names embedded in its
  36.323 -      header.</para>
  36.324 -
  36.325 -    <para>The <command role="hg-ext-extdiff">extdiff</command> command
  36.326 -      accepts two important options. The <option
  36.327 -	role="hg-ext-extdiff-cmd-extdiff-opt">hg -p</option> option
  36.328 -      lets you choose a program to view differences with, instead of
  36.329 -      <command>diff</command>.  With the <option
  36.330 -	role="hg-ext-extdiff-cmd-extdiff-opt">hg -o</option> option,
  36.331 -      you can change the options that <command
  36.332 -	role="hg-ext-extdiff">extdiff</command> passes to the program
  36.333 -      (by default, these options are
  36.334 -      <quote><literal>-Npru</literal></quote>, which only make sense
  36.335 -      if you're running <command>diff</command>).  In other respects,
  36.336 -      the <command role="hg-ext-extdiff">extdiff</command> command
  36.337 -      acts similarly to the built-in <command role="hg-cmd">hg
  36.338 -	diff</command> command: you use the same option names, syntax,
  36.339 -      and arguments to specify the revisions you want, the files you
  36.340 -      want, and so on.</para>
  36.341 -
  36.342 -    <para>As an example, here's how to run the normal system
  36.343 -      <command>diff</command> command, getting it to generate context
  36.344 -      diffs (using the <option role="cmd-opt-diff">-c</option> option)
  36.345 -      instead of unified diffs, and five lines of context instead of
  36.346 -      the default three (passing <literal>5</literal> as the argument
  36.347 -      to the <option role="cmd-opt-diff">-C</option> option).</para>
  36.348 -
  36.349 -      &interaction.extdiff.extdiff-ctx;
  36.350 -
  36.351 -    <para>Launching a visual diff tool is just as easy.  Here's how to
  36.352 -      launch the <command>kdiff3</command> viewer.</para>
  36.353 -    <programlisting>hg extdiff -p kdiff3 -o</programlisting>
  36.354 -
  36.355 -    <para>If your diff viewing command can't deal with directories,
  36.356 -      you can easily work around this with a little scripting.  For an
  36.357 -      example of such scripting in action with the <literal
  36.358 -	role="hg-ext">mq</literal> extension and the
  36.359 -      <command>interdiff</command> command, see section <xref
  36.360 -	linkend="mq-collab.tips.interdiff"/>.</para>
  36.361 -
  36.362 -    <sect2>
  36.363 -      <title>Defining command aliases</title>
  36.364 -
  36.365 -      <para>It can be cumbersome to remember the options to both the
  36.366 -	<command role="hg-ext-extdiff">extdiff</command> command and
  36.367 -	the diff viewer you want to use, so the <literal
  36.368 -	  role="hg-ext">extdiff</literal> extension lets you define
  36.369 -	<emphasis>new</emphasis> commands that will invoke your diff
  36.370 -	viewer with exactly the right options.</para>
  36.371 -
  36.372 -      <para>All you need to do is edit your <filename
  36.373 -	  role="special">~/.hgrc</filename>, and add a section named
  36.374 -	<literal role="rc-extdiff">extdiff</literal>.  Inside this
  36.375 -	section, you can define multiple commands.  Here's how to add
  36.376 -	a <literal>kdiff3</literal> command.  Once you've defined
  36.377 -	this, you can type <quote><literal>hg kdiff3</literal></quote>
  36.378 -	and the <literal role="hg-ext">extdiff</literal> extension
  36.379 -	will run <command>kdiff3</command> for you.</para>
  36.380 -      <programlisting>[extdiff]
  36.381 -cmd.kdiff3 =</programlisting>
  36.382 -      <para>If you leave the right hand side of the definition empty,
  36.383 -	as above, the <literal role="hg-ext">extdiff</literal>
  36.384 -	extension uses the name of the command you defined as the name
  36.385 -	of the external program to run.  But these names don't have to
  36.386 -	be the same.  Here, we define a command named
  36.387 -	<quote><literal>hg wibble</literal></quote>, which runs
  36.388 -	<command>kdiff3</command>.</para>
  36.389 -      <programlisting>[extdiff]
  36.390 - cmd.wibble = kdiff3</programlisting>
  36.391 -
  36.392 -      <para>You can also specify the default options that you want to
  36.393 -	invoke your diff viewing program with.  The prefix to use is
  36.394 -	<quote><literal>opts.</literal></quote>, followed by the name
  36.395 -	of the command to which the options apply.  This example
  36.396 -	defines a <quote><literal>hg vimdiff</literal></quote> command
  36.397 -	that runs the <command>vim</command> editor's
  36.398 -	<literal>DirDiff</literal> extension.</para>
  36.399 -      <programlisting>[extdiff]
  36.400 - cmd.vimdiff = vim
  36.401 -opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)'</programlisting>
  36.402 -
  36.403 -    </sect2>
  36.404 -  </sect1>
  36.405 -  <sect1 id="sec.hgext.transplant">
  36.406 -    <title>Cherrypicking changes with the <literal
  36.407 -	role="hg-ext">transplant</literal> extension</title>
  36.408 -
  36.409 -    <para>Need to have a long chat with Brendan about this.</para>
  36.410 -
  36.411 -  </sect1>
  36.412 -  <sect1 id="sec.hgext.patchbomb">
  36.413 -    <title>Send changes via email with the <literal
  36.414 -	role="hg-ext">patchbomb</literal> extension</title>
  36.415 -
  36.416 -    <para>Many projects have a culture of <quote>change
  36.417 -	review</quote>, in which people send their modifications to a
  36.418 -      mailing list for others to read and comment on before they
  36.419 -      commit the final version to a shared repository.  Some projects
  36.420 -      have people who act as gatekeepers; they apply changes from
  36.421 -      other people to a repository to which those others don't have
  36.422 -      access.</para>
  36.423 -
  36.424 -    <para>Mercurial makes it easy to send changes over email for
  36.425 -      review or application, via its <literal
  36.426 -	role="hg-ext">patchbomb</literal> extension.  The extension is
  36.427 -      so named because changes are formatted as patches, and it's usual
  36.428 -      to send one changeset per email message.  Sending a long series
  36.429 -      of changes by email is thus much like <quote>bombing</quote> the
  36.430 -      recipient's inbox, hence <quote>patchbomb</quote>.</para>
  36.431 -
  36.432 -    <para>As usual, the basic configuration of the <literal
  36.433 -	role="hg-ext">patchbomb</literal> extension takes just one or
  36.434 -      two lines in your <filename role="special">
  36.435 -	/.hgrc</filename>.</para>
  36.436 -    <programlisting>[extensions]
  36.437 -patchbomb =</programlisting>
  36.438 -    <para>Once you've enabled the extension, you will have a new
  36.439 -      command available, named <command
  36.440 -	role="hg-ext-patchbomb">email</command>.</para>
  36.441 -
  36.442 -    <para>The safest and best way to invoke the <command
  36.443 -	role="hg-ext-patchbomb">email</command> command is to
  36.444 -      <emphasis>always</emphasis> run it first with the <option
  36.445 -	role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option.
  36.446 -      This will show you what the command <emphasis>would</emphasis>
  36.447 -      send, without actually sending anything.  Once you've had a
  36.448 -      quick glance over the changes and verified that you are sending
  36.449 -      the right ones, you can rerun the same command, with the <option
  36.450 -	role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option
  36.451 -      removed.</para>
  36.452 -
  36.453 -    <para>The <command role="hg-ext-patchbomb">email</command> command
  36.454 -      accepts the same kind of revision syntax as every other
  36.455 -      Mercurial command.  For example, this command will send every
  36.456 -      revision between 7 and <literal>tip</literal>, inclusive.</para>
  36.457 -    <programlisting>hg email -n 7:tip</programlisting>
  36.458 -    <para>You can also specify a <emphasis>repository</emphasis> to
  36.459 -      compare with.  If you provide a repository but no revisions, the
  36.460 -      <command role="hg-ext-patchbomb">email</command> command will
  36.461 -      send all revisions in the local repository that are not present
  36.462 -      in the remote repository.  If you additionally specify revisions
  36.463 -      or a branch name (the latter using the <option
  36.464 -	role="hg-ext-patchbomb-cmd-email-opt">hg -b</option> option),
  36.465 -      this will constrain the revisions sent.</para>
  36.466 -
  36.467 -    <para>It's perfectly safe to run the <command
  36.468 -	role="hg-ext-patchbomb">email</command> command without the
  36.469 -      names of the people you want to send to: if you do this, it will
  36.470 -      just prompt you for those values interactively.  (If you're
  36.471 -      using a Linux or Unix-like system, you should have enhanced
  36.472 -      <literal>readline</literal>-style editing capabilities when
  36.473 -      entering those headers, too, which is useful.)</para>
  36.474 -
  36.475 -    <para>When you are sending just one revision, the <command
  36.476 -	role="hg-ext-patchbomb">email</command> command will by
  36.477 -      default use the first line of the changeset description as the
  36.478 -      subject of the single email message it sends.</para>
  36.479 -
  36.480 -    <para>If you send multiple revisions, the <command
  36.481 -	role="hg-ext-patchbomb">email</command> command will usually
  36.482 -      send one message per changeset.  It will preface the series with
  36.483 -      an introductory message, in which you should describe the
  36.484 -      purpose of the series of changes you're sending.</para>
  36.485 -
  36.486 -    <sect2>
  36.487 -      <title>Changing the behaviour of patchbombs</title>
  36.488 -
  36.489 -      <para>Not every project has exactly the same conventions for
  36.490 -	sending changes in email; the <literal
  36.491 -	  role="hg-ext">patchbomb</literal> extension tries to
  36.492 -	accommodate a number of variations through command line
  36.493 -	options.</para>
  36.494 -      <itemizedlist>
  36.495 -	<listitem><para>You can write a subject for the introductory
  36.496 -	    message on the command line using the <option
  36.497 -	      role="hg-ext-patchbomb-cmd-email-opt">hg -s</option>
  36.498 -	    option.  This takes one argument, the text of the subject
  36.499 -	    to use.</para>
  36.500 -	</listitem>
  36.501 -	<listitem><para>To change the email address from which the
  36.502 -	    messages originate, use the <option
  36.503 -	      role="hg-ext-patchbomb-cmd-email-opt">hg -f</option>
  36.504 -	    option.  This takes one argument, the email address to
  36.505 -	    use.</para>
  36.506 -	</listitem>
  36.507 -	<listitem><para>The default behaviour is to send unified diffs
  36.508 -	    (see section <xref linkend="sec.mq.patch"/> for a
  36.509 -	    description of the
  36.510 -	    format), one per message.  You can send a binary bundle
  36.511 -	    instead with the <option
  36.512 -	      role="hg-ext-patchbomb-cmd-email-opt">hg -b</option>
  36.513 -	    option.</para>
  36.514 -	</listitem>
  36.515 -	<listitem><para>Unified diffs are normally prefaced with a
  36.516 -	    metadata header.  You can omit this, and send unadorned
  36.517 -	    diffs, with the <option
  36.518 -	      role="hg-ext-patchbomb-cmd-email-opt">hg
  36.519 -	      --plain</option> option.</para>
  36.520 -	</listitem>
  36.521 -	<listitem><para>Diffs are normally sent <quote>inline</quote>,
  36.522 -	    in the same body part as the description of a patch.  This
  36.523 -	    makes it easiest for the largest number of readers to
  36.524 -	    quote and respond to parts of a diff, as some mail clients
  36.525 -	    will only quote the first MIME body part in a message. If
  36.526 -	    you'd prefer to send the description and the diff in
  36.527 -	    separate body parts, use the <option
  36.528 -	      role="hg-ext-patchbomb-cmd-email-opt">hg -a</option>
  36.529 -	    option.</para>
  36.530 -	</listitem>
  36.531 -	<listitem><para>Instead of sending mail messages, you can
  36.532 -	    write them to an <literal>mbox</literal>-format mail
  36.533 -	    folder using the <option
  36.534 -	      role="hg-ext-patchbomb-cmd-email-opt">hg -m</option>
  36.535 -	    option.  That option takes one argument, the name of the
  36.536 -	    file to write to.</para>
  36.537 -	</listitem>
  36.538 -	<listitem><para>If you would like to add a
  36.539 -	    <command>diffstat</command>-format summary to each patch,
  36.540 -	    and one to the introductory message, use the <option
  36.541 -	      role="hg-ext-patchbomb-cmd-email-opt">hg -d</option>
  36.542 -	    option.  The <command>diffstat</command> command displays
  36.543 -	    a table containing the name of each file patched, the
  36.544 -	    number of lines affected, and a histogram showing how much
  36.545 -	    each file is modified.  This gives readers a qualitative
  36.546 -	    glance at how complex a patch is.</para>
  36.547 -	</listitem></itemizedlist>
  36.548 -
  36.549 -    </sect2>
  36.550 -  </sect1>
  36.551 -</chapter>
  36.552 -
  36.553 -<!--
  36.554 -local variables: 
  36.555 -sgml-parent-document: ("00book.xml" "book" "chapter")
  36.556 -end:
  36.557 --->
    37.1 --- a/po/zh.po	Fri Mar 20 15:40:06 2009 +0800
    37.2 +++ b/po/zh.po	Fri Mar 20 16:43:35 2009 +0800
    37.3 @@ -41,7 +41,7 @@
    37.4  msgid ""
    37.5  msgstr ""
    37.6  "Project-Id-Version: hgbook 1.2\n"
    37.7 -"POT-Creation-Date: 2009-03-18 19:48+0800\n"
    37.8 +"POT-Creation-Date: 2009-03-20 15:47+0800\n"
    37.9  "PO-Revision-Date: 2009-03-18 19:50+0800\n"
   37.10  "Last-Translator: \n"
   37.11  "Language-Team: Simplified Chinese <i18n-zh@googlegroups.com >\n"
   37.12 @@ -475,15 +475,16 @@
   37.13  "patches</command>."
   37.14  msgstr ""
   37.15  
   37.16 +#. type: Content of: <book><appendix><sect1><sect2><title>
   37.17 +#: ../en/appB-mq-ref.xml:43
   37.18 +#, fuzzy
   37.19 +msgid ""
   37.20 +"<command role=\"hg-ext-mq\">qdelete</command>&emdash;delete a patch from the "
   37.21 +"<filename role=\"special\">series</filename> file}"
   37.22 +msgstr "<command role=\"hg-ext-mq\">qseries</command>&emdash;显示补丁序列"
   37.23 +
   37.24  #. type: Content of: <book><appendix><sect1><sect2><para>
   37.25 -#: ../en/appB-mq-ref.xml:42
   37.26 -msgid ""
   37.27 -"\\subsection{<command role=\"hg-ext-mq\">qdelete</command>&emdash;delete a "
   37.28 -"patch from the <filename role=\"special\">series</filename> file}"
   37.29 -msgstr ""
   37.30 -
   37.31 -#. type: Content of: <book><appendix><sect1><sect2><para>
   37.32 -#: ../en/appB-mq-ref.xml:47
   37.33 +#: ../en/appB-mq-ref.xml:48
   37.34  msgid ""
   37.35  "The <command role=\"hg-ext-mq\">qdelete</command> command removes the entry "
   37.36  "for a patch from the <filename role=\"special\">series</filename> file in the "
   37.37 @@ -494,21 +495,21 @@
   37.38  msgstr ""
   37.39  
   37.40  #. type: Content of: <book><appendix><sect1><sect2><para>
   37.41 -#: ../en/appB-mq-ref.xml:56 ../en/appB-mq-ref.xml:98 ../en/appB-mq-ref.xml:156
   37.42 -#: ../en/appB-mq-ref.xml:196 ../en/appB-mq-ref.xml:263
   37.43 -#: ../en/appB-mq-ref.xml:334 ../en/appB-mq-ref.xml:403
   37.44 -#: ../en/appB-mq-ref.xml:496
   37.45 +#: ../en/appB-mq-ref.xml:57 ../en/appB-mq-ref.xml:99 ../en/appB-mq-ref.xml:157
   37.46 +#: ../en/appB-mq-ref.xml:197 ../en/appB-mq-ref.xml:264
   37.47 +#: ../en/appB-mq-ref.xml:335 ../en/appB-mq-ref.xml:404
   37.48 +#: ../en/appB-mq-ref.xml:497
   37.49  msgid "Options:"
   37.50  msgstr ""
   37.51  
   37.52  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
   37.53 -#: ../en/appB-mq-ref.xml:58
   37.54 +#: ../en/appB-mq-ref.xml:59
   37.55  msgid ""
   37.56  "<option role=\"hg-ext-mq-cmd-qdel-opt\">-f</option>: Delete the patch file."
   37.57  msgstr ""
   37.58  
   37.59  #. type: Content of: <book><appendix><sect1><sect2><title>
   37.60 -#: ../en/appB-mq-ref.xml:65
   37.61 +#: ../en/appB-mq-ref.xml:66
   37.62  msgid ""
   37.63  "<command role=\"hg-ext-mq\">qdiff</command>&emdash;print a diff of the "
   37.64  "topmost applied patch"
   37.65 @@ -516,7 +517,7 @@
   37.66  "<command role=\"hg-ext-mq\">qdiff</command>&emdash;显示最新应用补丁的差异"
   37.67  
   37.68  #. type: Content of: <book><appendix><sect1><sect2><para>
   37.69 -#: ../en/appB-mq-ref.xml:68
   37.70 +#: ../en/appB-mq-ref.xml:69
   37.71  msgid ""
   37.72  "The <command role=\"hg-ext-mq\">qdiff</command> command prints a diff of the "
   37.73  "topmost applied patch. It is equivalent to <command role=\"hg-cmd\">hg diff -"
   37.74 @@ -524,7 +525,7 @@
   37.75  msgstr ""
   37.76  
   37.77  #. type: Content of: <book><appendix><sect1><sect2><title>
   37.78 -#: ../en/appB-mq-ref.xml:74
   37.79 +#: ../en/appB-mq-ref.xml:75
   37.80  msgid ""
   37.81  "<command role=\"hg-ext-mq\">qfold</command>&emdash;merge (<quote>fold</"
   37.82  "quote>) several patches into one"
   37.83 @@ -533,7 +534,7 @@
   37.84  "</quote>)成一个"
   37.85  
   37.86  #. type: Content of: <book><appendix><sect1><sect2><para>
   37.87 -#: ../en/appB-mq-ref.xml:77
   37.88 +#: ../en/appB-mq-ref.xml:78
   37.89  msgid ""
   37.90  "The <command role=\"hg-ext-mq\">qfold</command> command merges multiple "
   37.91  "patches into the topmost applied patch, so that the topmost applied patch "
   37.92 @@ -541,7 +542,7 @@
   37.93  msgstr ""
   37.94  
   37.95  #. type: Content of: <book><appendix><sect1><sect2><para>
   37.96 -#: ../en/appB-mq-ref.xml:82
   37.97 +#: ../en/appB-mq-ref.xml:83
   37.98  msgid ""
   37.99  "The patches to fold must not be applied; <command role=\"hg-ext-mq\">qfold</"
  37.100  "command> will exit with an error if any is.  The order in which patches are "
  37.101 @@ -551,7 +552,7 @@
  37.102  msgstr ""
  37.103  
  37.104  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.105 -#: ../en/appB-mq-ref.xml:90
  37.106 +#: ../en/appB-mq-ref.xml:91
  37.107  msgid ""
  37.108  "The comments from the folded patches are appended to the comments of the "
  37.109  "destination patch, with each block of comments separated by three asterisk "
  37.110 @@ -561,14 +562,14 @@
  37.111  msgstr ""
  37.112  
  37.113  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.114 -#: ../en/appB-mq-ref.xml:100
  37.115 +#: ../en/appB-mq-ref.xml:101
  37.116  msgid ""
  37.117  "<option role=\"hg-ext-mq-cmd-qfold-opt\">-e</option>: Edit the commit message "
  37.118  "and patch description for the newly folded patch."
  37.119  msgstr ""
  37.120  
  37.121  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.122 -#: ../en/appB-mq-ref.xml:105
  37.123 +#: ../en/appB-mq-ref.xml:106
  37.124  msgid ""
  37.125  "<option role=\"hg-ext-mq-cmd-qfold-opt\">-l</option>: Use the contents of the "
  37.126  "given file as the new commit message and patch description for the folded "
  37.127 @@ -576,21 +577,21 @@
  37.128  msgstr ""
  37.129  
  37.130  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.131 -#: ../en/appB-mq-ref.xml:110
  37.132 +#: ../en/appB-mq-ref.xml:111
  37.133  msgid ""
  37.134  "<option role=\"hg-ext-mq-cmd-qfold-opt\">-m</option>: Use the given text as "
  37.135  "the new commit message and patch description for the folded patch."
  37.136  msgstr ""
  37.137  
  37.138  #. type: Content of: <book><appendix><sect1><sect2><title>
  37.139 -#: ../en/appB-mq-ref.xml:118
  37.140 +#: ../en/appB-mq-ref.xml:119
  37.141  msgid ""
  37.142  "<command role=\"hg-ext-mq\">qheader</command>&emdash;display the header/"
  37.143  "description of a patch"
  37.144  msgstr "<command role=\"hg-ext-mq\">qheader</command>&emdash;显示补丁头部描述"
  37.145  
  37.146  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.147 -#: ../en/appB-mq-ref.xml:122
  37.148 +#: ../en/appB-mq-ref.xml:123
  37.149  msgid ""
  37.150  "The <command role=\"hg-ext-mq\">qheader</command> command prints the header, "
  37.151  "or description, of a patch.  By default, it prints the header of the topmost "
  37.152 @@ -598,7 +599,7 @@
  37.153  msgstr ""
  37.154  
  37.155  #. type: Content of: <book><appendix><sect1><sect2><title>
  37.156 -#: ../en/appB-mq-ref.xml:129
  37.157 +#: ../en/appB-mq-ref.xml:130
  37.158  msgid ""
  37.159  "<command role=\"hg-ext-mq\">qimport</command>&emdash;import a third-party "
  37.160  "patch into the queue"
  37.161 @@ -606,7 +607,7 @@
  37.162  "<command role=\"hg-ext-mq\">qimport</command>&emdash;将第三方补丁导入队列"
  37.163  
  37.164  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.165 -#: ../en/appB-mq-ref.xml:132
  37.166 +#: ../en/appB-mq-ref.xml:133
  37.167  msgid ""
  37.168  "The <command role=\"hg-ext-mq\">qimport</command> command adds an entry for "
  37.169  "an external patch to the <filename role=\"special\">series</filename> file, "
  37.170 @@ -616,7 +617,7 @@
  37.171  msgstr ""
  37.172  
  37.173  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.174 -#: ../en/appB-mq-ref.xml:140
  37.175 +#: ../en/appB-mq-ref.xml:141
  37.176  msgid ""
  37.177  "If the <filename role=\"special\" class=\"directory\">.hg/patches</filename> "
  37.178  "directory is a repository, <command role=\"hg-ext-mq\">qimport</command> "
  37.179 @@ -625,14 +626,14 @@
  37.180  msgstr ""
  37.181  
  37.182  #. type: Content of: <book><appendix><sect1><sect2><title>
  37.183 -#: ../en/appB-mq-ref.xml:148
  37.184 +#: ../en/appB-mq-ref.xml:149
  37.185  msgid ""
  37.186  "<command role=\"hg-ext-mq\">qinit</command>&emdash;prepare a repository to "
  37.187  "work with MQ"
  37.188  msgstr "<command role=\"hg-ext-mq\">qinit</command>&emdash;为使用 MQ 配置版本库"
  37.189  
  37.190  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.191 -#: ../en/appB-mq-ref.xml:151
  37.192 +#: ../en/appB-mq-ref.xml:152
  37.193  msgid ""
  37.194  "The <command role=\"hg-ext-mq\">qinit</command> command prepares a repository "
  37.195  "to work with MQ.  It creates a directory called <filename role=\"special\" "
  37.196 @@ -640,7 +641,7 @@
  37.197  msgstr ""
  37.198  
  37.199  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.200 -#: ../en/appB-mq-ref.xml:158
  37.201 +#: ../en/appB-mq-ref.xml:159
  37.202  msgid ""
  37.203  "<option role=\"hg-ext-mq-cmd-qinit-opt\">-c</option>: Create <filename role="
  37.204  "\"special\" class=\"directory\">.hg/patches</filename> as a repository in its "
  37.205 @@ -649,7 +650,7 @@
  37.206  msgstr ""
  37.207  
  37.208  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.209 -#: ../en/appB-mq-ref.xml:168
  37.210 +#: ../en/appB-mq-ref.xml:169
  37.211  msgid ""
  37.212  "When the <filename role=\"special\" class=\"directory\">.hg/patches</"
  37.213  "filename> directory is a repository, the <command role=\"hg-ext-mq\">qimport</"
  37.214 @@ -658,12 +659,12 @@
  37.215  msgstr ""
  37.216  
  37.217  #. type: Content of: <book><appendix><sect1><sect2><title>
  37.218 -#: ../en/appB-mq-ref.xml:177
  37.219 +#: ../en/appB-mq-ref.xml:178
  37.220  msgid "<command role=\"hg-ext-mq\">qnew</command>&emdash;create a new patch"
  37.221  msgstr "<command role=\"hg-ext-mq\">qnew</command>&emdash;创建新补丁"
  37.222  
  37.223  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.224 -#: ../en/appB-mq-ref.xml:180
  37.225 +#: ../en/appB-mq-ref.xml:181
  37.226  msgid ""
  37.227  "The <command role=\"hg-ext-mq\">qnew</command> command creates a new patch.  "
  37.228  "It takes one mandatory argument, the name to use for the patch file.  The "
  37.229 @@ -673,7 +674,7 @@
  37.230  msgstr ""
  37.231  
  37.232  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.233 -#: ../en/appB-mq-ref.xml:188
  37.234 +#: ../en/appB-mq-ref.xml:189
  37.235  msgid ""
  37.236  "If <command role=\"hg-ext-mq\">qnew</command> finds modified files in the "
  37.237  "working directory, it will refuse to create a new patch unless the <option "
  37.238 @@ -683,7 +684,7 @@
  37.239  msgstr ""
  37.240  
  37.241  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.242 -#: ../en/appB-mq-ref.xml:198
  37.243 +#: ../en/appB-mq-ref.xml:199
  37.244  msgid ""
  37.245  "<option role=\"hg-ext-mq-cmd-qnew-opt\">-f</option>: Create a new patch if "
  37.246  "the contents of the working directory are modified.  Any outstanding "
  37.247 @@ -692,7 +693,7 @@
  37.248  msgstr ""
  37.249  
  37.250  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.251 -#: ../en/appB-mq-ref.xml:205
  37.252 +#: ../en/appB-mq-ref.xml:206
  37.253  msgid ""
  37.254  "<option role=\"hg-ext-mq-cmd-qnew-opt\">-m</option>: Use the given text as "
  37.255  "the commit message. This text will be stored at the beginning of the patch "
  37.256 @@ -700,14 +701,14 @@
  37.257  msgstr ""
  37.258  
  37.259  #. type: Content of: <book><appendix><sect1><sect2><title>
  37.260 -#: ../en/appB-mq-ref.xml:214
  37.261 +#: ../en/appB-mq-ref.xml:215
  37.262  msgid ""
  37.263  "<command role=\"hg-ext-mq\">qnext</command>&emdash;print the name of the next "
  37.264  "patch"
  37.265  msgstr "<command role=\"hg-ext-mq\">qnext</command>&emdash;显示下个补丁的名称"
  37.266  
  37.267  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.268 -#: ../en/appB-mq-ref.xml:217
  37.269 +#: ../en/appB-mq-ref.xml:218
  37.270  msgid ""
  37.271  "The <command role=\"hg-ext-mq\">qnext</command> command prints the name name "
  37.272  "of the next patch in the <filename role=\"special\">series</filename> file "
  37.273 @@ -716,13 +717,13 @@
  37.274  msgstr ""
  37.275  
  37.276  #. type: Content of: <book><appendix><sect1><sect2><title>
  37.277 -#: ../en/appB-mq-ref.xml:226
  37.278 +#: ../en/appB-mq-ref.xml:227
  37.279  msgid ""
  37.280  "<command role=\"hg-ext-mq\">qpop</command>&emdash;pop patches off the stack"
  37.281  msgstr "<command role=\"hg-ext-mq\">qpop</command>&emdash;删除堆栈顶部的补丁"
  37.282  
  37.283  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.284 -#: ../en/appB-mq-ref.xml:229
  37.285 +#: ../en/appB-mq-ref.xml:230
  37.286  msgid ""
  37.287  "The <command role=\"hg-ext-mq\">qpop</command> command removes applied "
  37.288  "patches from the top of the stack of applied patches.  By default, it removes "
  37.289 @@ -730,7 +731,7 @@
  37.290  msgstr ""
  37.291  
  37.292  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.293 -#: ../en/appB-mq-ref.xml:233
  37.294 +#: ../en/appB-mq-ref.xml:234
  37.295  msgid ""
  37.296  "This command removes the changesets that represent the popped patches from "
  37.297  "the repository, and updates the working directory to undo the effects of the "
  37.298 @@ -738,7 +739,7 @@
  37.299  msgstr ""
  37.300  
  37.301  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.302 -#: ../en/appB-mq-ref.xml:237
  37.303 +#: ../en/appB-mq-ref.xml:238
  37.304  msgid ""
  37.305  "This command takes an optional argument, which it uses as the name or index "
  37.306  "of the patch to pop to.  If given a name, it will pop patches until the named "
  37.307 @@ -750,7 +751,7 @@
  37.308  msgstr ""
  37.309  
  37.310  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.311 -#: ../en/appB-mq-ref.xml:247
  37.312 +#: ../en/appB-mq-ref.xml:248
  37.313  msgid ""
  37.314  "The <command role=\"hg-ext-mq\">qpop</command> command does not read or write "
  37.315  "patches or the <filename role=\"special\">series</filename> file.  It is thus "
  37.316 @@ -761,7 +762,7 @@
  37.317  msgstr ""
  37.318  
  37.319  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.320 -#: ../en/appB-mq-ref.xml:256
  37.321 +#: ../en/appB-mq-ref.xml:257
  37.322  msgid ""
  37.323  "By default, the <command role=\"hg-ext-mq\">qpop</command> command will not "
  37.324  "pop any patches if the working directory has been modified.  You can override "
  37.325 @@ -770,7 +771,7 @@
  37.326  msgstr ""
  37.327  
  37.328  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.329 -#: ../en/appB-mq-ref.xml:265
  37.330 +#: ../en/appB-mq-ref.xml:266
  37.331  msgid ""
  37.332  "<option role=\"hg-ext-mq-cmd-qpop-opt\">-a</option>: Pop all applied "
  37.333  "patches.  This returns the repository to its state before you applied any "
  37.334 @@ -778,21 +779,21 @@
  37.335  msgstr ""
  37.336  
  37.337  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.338 -#: ../en/appB-mq-ref.xml:270
  37.339 +#: ../en/appB-mq-ref.xml:271
  37.340  msgid ""
  37.341  "<option role=\"hg-ext-mq-cmd-qpop-opt\">-f</option>: Forcibly revert any "
  37.342  "modifications to the working directory when popping."
  37.343  msgstr ""
  37.344  
  37.345  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.346 -#: ../en/appB-mq-ref.xml:275
  37.347 +#: ../en/appB-mq-ref.xml:276
  37.348  msgid ""
  37.349  "<option role=\"hg-ext-mq-cmd-qpop-opt\">-n</option>: Pop a patch from the "
  37.350  "named queue."
  37.351  msgstr ""
  37.352  
  37.353  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.354 -#: ../en/appB-mq-ref.xml:280
  37.355 +#: ../en/appB-mq-ref.xml:281
  37.356  msgid ""
  37.357  "The <command role=\"hg-ext-mq\">qpop</command> command removes one line from "
  37.358  "the end of the <filename role=\"special\">status</filename> file for each "
  37.359 @@ -800,14 +801,14 @@
  37.360  msgstr ""
  37.361  
  37.362  #. type: Content of: <book><appendix><sect1><sect2><title>
  37.363 -#: ../en/appB-mq-ref.xml:287
  37.364 +#: ../en/appB-mq-ref.xml:288
  37.365  msgid ""
  37.366  "<command role=\"hg-ext-mq\">qprev</command>&emdash;print the name of the "
  37.367  "previous patch"
  37.368  msgstr "<command role=\"hg-ext-mq\">qprev</command>&emdash;显示上个补丁的名称"
  37.369  
  37.370  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.371 -#: ../en/appB-mq-ref.xml:290
  37.372 +#: ../en/appB-mq-ref.xml:291
  37.373  msgid ""
  37.374  "The <command role=\"hg-ext-mq\">qprev</command> command prints the name of "
  37.375  "the patch in the <filename role=\"special\">series</filename> file that comes "
  37.376 @@ -816,32 +817,32 @@
  37.377  msgstr ""
  37.378  
  37.379  #. type: Content of: <book><appendix><sect1><sect2><title>
  37.380 -#: ../en/appB-mq-ref.xml:299
  37.381 +#: ../en/appB-mq-ref.xml:300
  37.382  msgid ""
  37.383  "<command role=\"hg-ext-mq\">qpush</command>&emdash;push patches onto the stack"
  37.384  msgstr "<command role=\"hg-ext-mq\">qpush</command>&emdash;增加补丁到堆栈"
  37.385  
  37.386  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.387 -#: ../en/appB-mq-ref.xml:302
  37.388 +#: ../en/appB-mq-ref.xml:303
  37.389  msgid ""
  37.390  "The <command role=\"hg-ext-mq\">qpush</command> command adds patches onto the "
  37.391  "applied stack.  By default, it adds only one patch."
  37.392  msgstr ""
  37.393  
  37.394  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.395 -#: ../en/appB-mq-ref.xml:306
  37.396 +#: ../en/appB-mq-ref.xml:307
  37.397  msgid ""
  37.398  "This command creates a new changeset to represent each applied patch, and "
  37.399  "updates the working directory to apply the effects of the patches."
  37.400  msgstr ""
  37.401  
  37.402  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.403 -#: ../en/appB-mq-ref.xml:310
  37.404 +#: ../en/appB-mq-ref.xml:311
  37.405  msgid "The default data used when creating a changeset are as follows:"
  37.406  msgstr ""
  37.407  
  37.408  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.409 -#: ../en/appB-mq-ref.xml:313
  37.410 +#: ../en/appB-mq-ref.xml:314
  37.411  msgid ""
  37.412  "The commit date and time zone are the current date and time zone.  Because "
  37.413  "these data are used to compute the identity of a changeset, this means that "
  37.414 @@ -851,14 +852,14 @@
  37.415  msgstr ""
  37.416  
  37.417  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.418 -#: ../en/appB-mq-ref.xml:321
  37.419 +#: ../en/appB-mq-ref.xml:322
  37.420  msgid ""
  37.421  "The author is the same as the default used by the <command role=\"hg-cmd\">hg "
  37.422  "commit</command> command."
  37.423  msgstr ""
  37.424  
  37.425  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.426 -#: ../en/appB-mq-ref.xml:325
  37.427 +#: ../en/appB-mq-ref.xml:326
  37.428  msgid ""
  37.429  "The commit message is any text from the patch file that comes before the "
  37.430  "first diff header.  If there is no such text, a default commit message is "
  37.431 @@ -866,14 +867,14 @@
  37.432  msgstr ""
  37.433  
  37.434  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.435 -#: ../en/appB-mq-ref.xml:330
  37.436 +#: ../en/appB-mq-ref.xml:331
  37.437  msgid ""
  37.438  "If a patch contains a Mercurial patch header (XXX add link), the information "
  37.439  "in the patch header overrides these defaults."
  37.440  msgstr ""
  37.441  
  37.442  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.443 -#: ../en/appB-mq-ref.xml:336
  37.444 +#: ../en/appB-mq-ref.xml:337
  37.445  msgid ""
  37.446  "<option role=\"hg-ext-mq-cmd-qpush-opt\">-a</option>: Push all unapplied "
  37.447  "patches from the <filename role=\"special\">series</filename> file until "
  37.448 @@ -881,14 +882,14 @@
  37.449  msgstr ""
  37.450  
  37.451  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.452 -#: ../en/appB-mq-ref.xml:342
  37.453 +#: ../en/appB-mq-ref.xml:343
  37.454  msgid ""
  37.455  "<option role=\"hg-ext-mq-cmd-qpush-opt\">-l</option>: Add the name of the "
  37.456  "patch to the end of the commit message."
  37.457  msgstr ""
  37.458  
  37.459  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.460 -#: ../en/appB-mq-ref.xml:346
  37.461 +#: ../en/appB-mq-ref.xml:347
  37.462  msgid ""
  37.463  "<option role=\"hg-ext-mq-cmd-qpush-opt\">-m</option>: If a patch fails to "
  37.464  "apply cleanly, use the entry for the patch in another saved queue to compute "
  37.465 @@ -898,14 +899,14 @@
  37.466  msgstr ""
  37.467  
  37.468  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.469 -#: ../en/appB-mq-ref.xml:354
  37.470 +#: ../en/appB-mq-ref.xml:355
  37.471  msgid ""
  37.472  "<option role=\"hg-ext-mq-cmd-qpush-opt\">-n</option>: Use the named queue if "
  37.473  "merging while pushing."
  37.474  msgstr ""
  37.475  
  37.476  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.477 -#: ../en/appB-mq-ref.xml:359
  37.478 +#: ../en/appB-mq-ref.xml:360
  37.479  msgid ""
  37.480  "The <command role=\"hg-ext-mq\">qpush</command> command reads, but does not "
  37.481  "modify, the <filename role=\"special\">series</filename> file.  It appends "
  37.482 @@ -914,14 +915,14 @@
  37.483  msgstr ""
  37.484  
  37.485  #. type: Content of: <book><appendix><sect1><sect2><title>
  37.486 -#: ../en/appB-mq-ref.xml:367
  37.487 +#: ../en/appB-mq-ref.xml:368
  37.488  msgid ""
  37.489  "<command role=\"hg-ext-mq\">qrefresh</command>&emdash;update the topmost "
  37.490  "applied patch"
  37.491  msgstr "<command role=\"hg-ext-mq\">qrefresh</command>&emdash;更新最新的补丁"
  37.492  
  37.493  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.494 -#: ../en/appB-mq-ref.xml:371
  37.495 +#: ../en/appB-mq-ref.xml:372
  37.496  msgid ""
  37.497  "The <command role=\"hg-ext-mq\">qrefresh</command> command updates the "
  37.498  "topmost applied patch.  It modifies the patch, removes the old changeset that "
  37.499 @@ -930,28 +931,28 @@
  37.500  msgstr ""
  37.501  
  37.502  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.503 -#: ../en/appB-mq-ref.xml:377
  37.504 +#: ../en/appB-mq-ref.xml:378
  37.505  msgid ""
  37.506  "The <command role=\"hg-ext-mq\">qrefresh</command> command looks for the "
  37.507  "following modifications:"
  37.508  msgstr ""
  37.509  
  37.510  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.511 -#: ../en/appB-mq-ref.xml:380
  37.512 +#: ../en/appB-mq-ref.xml:381
  37.513  msgid ""
  37.514  "Changes to the commit message, i.e. the text before the first diff header in "
  37.515  "the patch file, are reflected in the new changeset that represents the patch."
  37.516  msgstr ""
  37.517  
  37.518  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.519 -#: ../en/appB-mq-ref.xml:385
  37.520 +#: ../en/appB-mq-ref.xml:386
  37.521  msgid ""
  37.522  "Modifications to tracked files in the working directory are added to the "
  37.523  "patch."
  37.524  msgstr ""
  37.525  
  37.526  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.527 -#: ../en/appB-mq-ref.xml:388
  37.528 +#: ../en/appB-mq-ref.xml:389
  37.529  msgid ""
  37.530  "Changes to the files tracked using <command role=\"hg-cmd\">hg add</command>, "
  37.531  "<command role=\"hg-cmd\">hg copy</command>, <command role=\"hg-cmd\">hg "
  37.532 @@ -961,7 +962,7 @@
  37.533  msgstr ""
  37.534  
  37.535  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.536 -#: ../en/appB-mq-ref.xml:397
  37.537 +#: ../en/appB-mq-ref.xml:398
  37.538  msgid ""
  37.539  "Even if <command role=\"hg-ext-mq\">qrefresh</command> detects no changes, it "
  37.540  "still recreates the changeset that represents the patch.  This causes the "
  37.541 @@ -970,33 +971,33 @@
  37.542  msgstr ""
  37.543  
  37.544  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.545 -#: ../en/appB-mq-ref.xml:405
  37.546 +#: ../en/appB-mq-ref.xml:406
  37.547  msgid ""
  37.548  "<option role=\"hg-ext-mq-cmd-qrefresh-opt\">-e</option>: Modify the commit "
  37.549  "and patch description, using the preferred text editor."
  37.550  msgstr ""
  37.551  
  37.552  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.553 -#: ../en/appB-mq-ref.xml:410
  37.554 +#: ../en/appB-mq-ref.xml:411
  37.555  msgid ""
  37.556  "<option role=\"hg-ext-mq-cmd-qrefresh-opt\">-m</option>: Modify the commit "
  37.557  "message and patch description, using the given text."
  37.558  msgstr ""
  37.559  
  37.560  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.561 -#: ../en/appB-mq-ref.xml:415
  37.562 +#: ../en/appB-mq-ref.xml:416
  37.563  msgid ""
  37.564  "<option role=\"hg-ext-mq-cmd-qrefresh-opt\">-l</option>: Modify the commit "
  37.565  "message and patch description, using text from the given file."
  37.566  msgstr ""
  37.567  
  37.568  #. type: Content of: <book><appendix><sect1><sect2><title>
  37.569 -#: ../en/appB-mq-ref.xml:423
  37.570 +#: ../en/appB-mq-ref.xml:424
  37.571  msgid "<command role=\"hg-ext-mq\">qrename</command>&emdash;rename a patch"
  37.572  msgstr "<command role=\"hg-ext-mq\">qrename</command>&emdash;改名补丁"
  37.573  
  37.574  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.575 -#: ../en/appB-mq-ref.xml:426
  37.576 +#: ../en/appB-mq-ref.xml:427
  37.577  msgid ""
  37.578  "The <command role=\"hg-ext-mq\">qrename</command> command renames a patch, "
  37.579  "and changes the entry for the patch in the <filename role=\"special\">series</"
  37.580 @@ -1004,7 +1005,7 @@
  37.581  msgstr ""
  37.582  
  37.583  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.584 -#: ../en/appB-mq-ref.xml:430
  37.585 +#: ../en/appB-mq-ref.xml:431
  37.586  msgid ""
  37.587  "With a single argument, <command role=\"hg-ext-mq\">qrename</command> renames "
  37.588  "the topmost applied patch.  With two arguments, it renames its first argument "
  37.589 @@ -1012,37 +1013,37 @@
  37.590  msgstr ""
  37.591  
  37.592  #. type: Content of: <book><appendix><sect1><sect2><title>
  37.593 -#: ../en/appB-mq-ref.xml:437
  37.594 +#: ../en/appB-mq-ref.xml:438
  37.595  msgid ""
  37.596  "<command role=\"hg-ext-mq\">qrestore</command>&emdash;restore saved queue "
  37.597  "state"
  37.598  msgstr "<command role=\"hg-ext-mq\">qrestore</command>&emdash;恢复保存的队列"
  37.599  
  37.600  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.601 -#: ../en/appB-mq-ref.xml:441
  37.602 +#: ../en/appB-mq-ref.xml:442
  37.603  msgid "XXX No idea what this does."
  37.604  msgstr ""
  37.605  
  37.606  #. type: Content of: <book><appendix><sect1><sect2><title>
  37.607 -#: ../en/appB-mq-ref.xml:445
  37.608 +#: ../en/appB-mq-ref.xml:446
  37.609  msgid ""
  37.610  "<command role=\"hg-ext-mq\">qsave</command>&emdash;save current queue state"
  37.611  msgstr "<command role=\"hg-ext-mq\">qsave</command>&emdash;保存当前的队列状态"
  37.612  
  37.613  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.614 -#: ../en/appB-mq-ref.xml:448
  37.615 +#: ../en/appB-mq-ref.xml:449
  37.616  msgid "XXX Likewise."
  37.617  msgstr ""
  37.618  
  37.619  #. type: Content of: <book><appendix><sect1><sect2><title>
  37.620 -#: ../en/appB-mq-ref.xml:452
  37.621 +#: ../en/appB-mq-ref.xml:453
  37.622  msgid ""
  37.623  "<command role=\"hg-ext-mq\">qseries</command>&emdash;print the entire patch "
  37.624  "series"
  37.625  msgstr "<command role=\"hg-ext-mq\">qseries</command>&emdash;显示补丁序列"
  37.626  
  37.627  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.628 -#: ../en/appB-mq-ref.xml:455
  37.629 +#: ../en/appB-mq-ref.xml:456
  37.630  msgid ""
  37.631  "The <command role=\"hg-ext-mq\">qseries</command> command prints the entire "
  37.632  "patch series from the <filename role=\"special\">series</filename> file.  It "
  37.633 @@ -1051,21 +1052,21 @@
  37.634  msgstr ""
  37.635  
  37.636  #. type: Content of: <book><appendix><sect1><sect2><title>
  37.637 -#: ../en/appB-mq-ref.xml:463
  37.638 +#: ../en/appB-mq-ref.xml:464
  37.639  msgid ""
  37.640  "<command role=\"hg-ext-mq\">qtop</command>&emdash;print the name of the "
  37.641  "current patch"
  37.642  msgstr "<command role=\"hg-ext-mq\">qtop</command>&emdash;显示当前补丁的名称"
  37.643  
  37.644  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.645 -#: ../en/appB-mq-ref.xml:466
  37.646 +#: ../en/appB-mq-ref.xml:467
  37.647  msgid ""
  37.648  "The <command role=\"hg-ext-mq\">qtop</command> prints the name of the topmost "
  37.649  "currently applied patch."
  37.650  msgstr ""
  37.651  
  37.652  #. type: Content of: <book><appendix><sect1><sect2><title>
  37.653 -#: ../en/appB-mq-ref.xml:471
  37.654 +#: ../en/appB-mq-ref.xml:472
  37.655  msgid ""
  37.656  "<command role=\"hg-ext-mq\">qunapplied</command>&emdash;print patches not yet "
  37.657  "applied"
  37.658 @@ -1073,7 +1074,7 @@
  37.659  "<command role=\"hg-ext-mq\">qunapplied</command>&emdash;显示尚未应用的补丁"
  37.660  
  37.661  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.662 -#: ../en/appB-mq-ref.xml:475
  37.663 +#: ../en/appB-mq-ref.xml:476
  37.664  msgid ""
  37.665  "The <command role=\"hg-ext-mq\">qunapplied</command> command prints the names "
  37.666  "of patches from the <filename role=\"special\">series</filename> file that "
  37.667 @@ -1082,14 +1083,14 @@
  37.668  msgstr ""
  37.669  
  37.670  #. type: Content of: <book><appendix><sect1><sect2><title>
  37.671 -#: ../en/appB-mq-ref.xml:483
  37.672 +#: ../en/appB-mq-ref.xml:484
  37.673  msgid ""
  37.674  "<command role=\"hg-cmd\">hg strip</command>&emdash;remove a revision and "
  37.675  "descendants"
  37.676  msgstr "<command role=\"hg-cmd\">hg strip</command>&emdash;删除一个版本及其后继"
  37.677  
  37.678  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.679 -#: ../en/appB-mq-ref.xml:486
  37.680 +#: ../en/appB-mq-ref.xml:487
  37.681  msgid ""
  37.682  "The <command role=\"hg-cmd\">hg strip</command> command removes a revision, "
  37.683  "and all of its descendants, from the repository.  It undoes the effects of "
  37.684 @@ -1098,7 +1099,7 @@
  37.685  msgstr ""
  37.686  
  37.687  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.688 -#: ../en/appB-mq-ref.xml:492
  37.689 +#: ../en/appB-mq-ref.xml:493
  37.690  msgid ""
  37.691  "The <command role=\"hg-cmd\">hg strip</command> command saves a backup of the "
  37.692  "removed changesets in a bundle, so that they can be reapplied if removed in "
  37.693 @@ -1106,14 +1107,14 @@
  37.694  msgstr ""
  37.695  
  37.696  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.697 -#: ../en/appB-mq-ref.xml:498
  37.698 +#: ../en/appB-mq-ref.xml:499
  37.699  msgid ""
  37.700  "<option role=\"hg-opt-strip\">-b</option>: Save unrelated changesets that are "
  37.701  "intermixed with the stripped changesets in the backup bundle."
  37.702  msgstr ""
  37.703  
  37.704  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.705 -#: ../en/appB-mq-ref.xml:502
  37.706 +#: ../en/appB-mq-ref.xml:503
  37.707  msgid ""
  37.708  "<option role=\"hg-opt-strip\">-f</option>: If a branch has multiple heads, "
  37.709  "remove all heads. XXX This should be renamed, and use <literal>-f</literal> "
  37.710 @@ -1121,22 +1122,22 @@
  37.711  msgstr ""
  37.712  
  37.713  #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
  37.714 -#: ../en/appB-mq-ref.xml:507
  37.715 +#: ../en/appB-mq-ref.xml:508
  37.716  msgid "<option role=\"hg-opt-strip\">-n</option>: Do not save a backup bundle."
  37.717  msgstr ""
  37.718  
  37.719  #. type: Content of: <book><appendix><sect1><title>
  37.720 -#: ../en/appB-mq-ref.xml:514
  37.721 +#: ../en/appB-mq-ref.xml:515
  37.722  msgid "MQ file reference"
  37.723  msgstr "MQ 文件参考"
  37.724  
  37.725  #. type: Content of: <book><appendix><sect1><sect2><title>
  37.726 -#: ../en/appB-mq-ref.xml:517
  37.727 +#: ../en/appB-mq-ref.xml:518
  37.728  msgid "The <filename role=\"special\">series</filename> file"
  37.729  msgstr "<filename role=\"special\">序列</filename>文件"
  37.730  
  37.731  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.732 -#: ../en/appB-mq-ref.xml:520
  37.733 +#: ../en/appB-mq-ref.xml:521
  37.734  msgid ""
  37.735  "The <filename role=\"special\">series</filename> file contains a list of the "
  37.736  "names of all patches that MQ can apply.  It is represented as a list of "
  37.737 @@ -1145,7 +1146,7 @@
  37.738  msgstr ""
  37.739  
  37.740  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.741 -#: ../en/appB-mq-ref.xml:526
  37.742 +#: ../en/appB-mq-ref.xml:527
  37.743  msgid ""
  37.744  "Lines may contain comments.  A comment begins with the <quote><literal>#</"
  37.745  "literal></quote> character, and extends to the end of the line.  Empty lines, "
  37.746 @@ -1153,7 +1154,7 @@
  37.747  msgstr ""
  37.748  
  37.749  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.750 -#: ../en/appB-mq-ref.xml:531
  37.751 +#: ../en/appB-mq-ref.xml:532
  37.752  msgid ""
  37.753  "You will often need to edit the <filename role=\"special\">series</filename> "
  37.754  "file by hand, hence the support for comments and empty lines noted above.  "
  37.755 @@ -1164,7 +1165,7 @@
  37.756  msgstr ""
  37.757  
  37.758  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.759 -#: ../en/appB-mq-ref.xml:540
  37.760 +#: ../en/appB-mq-ref.xml:541
  37.761  msgid ""
  37.762  "Placing the <filename role=\"special\">series</filename> file under revision "
  37.763  "control is also supported; it is a good idea to place all of the patches that "
  37.764 @@ -1175,12 +1176,12 @@
  37.765  msgstr ""
  37.766  
  37.767  #. type: Content of: <book><appendix><sect1><sect2><title>
  37.768 -#: ../en/appB-mq-ref.xml:550
  37.769 +#: ../en/appB-mq-ref.xml:551
  37.770  msgid "The <filename role=\"special\">status</filename> file"
  37.771  msgstr "<filename role=\"special\">状态</filename>文件"
  37.772  
  37.773  #. type: Content of: <book><appendix><sect1><sect2><para>
  37.774 -#: ../en/appB-mq-ref.xml:553
  37.775 +#: ../en/appB-mq-ref.xml:554
  37.776  msgid ""
  37.777  "The <filename role=\"special\">status</filename> file contains the names and "
  37.778  "changeset hashes of all patches that MQ currently has applied.  Unlike the "
  37.779 @@ -1519,941 +1520,17 @@
  37.780  msgstr ""
  37.781  
  37.782  #. type: Content of: <book><chapter><title>
  37.783 -#: ../en/ch01-intro.xml:5
  37.784 -msgid "Introduction"
  37.785 -msgstr "简介"
  37.786 -
  37.787 -#. type: Content of: <book><chapter><sect1><title>
  37.788 -#: ../en/ch01-intro.xml:8
  37.789 -msgid "About revision control"
  37.790 -msgstr "关于版本控制"
  37.791 -
  37.792 -#. type: Content of: <book><chapter><sect1><para>
  37.793 -#: ../en/ch01-intro.xml:10
  37.794 -msgid ""
  37.795 -"Revision control is the process of managing multiple versions of a piece of "
  37.796 -"information.  In its simplest form, this is something that many people do by "
  37.797 -"hand: every time you modify a file, save it under a new name that contains a "
  37.798 -"number, each one higher than the number of the preceding version."
  37.799 -msgstr ""
  37.800 -
  37.801 -#. type: Content of: <book><chapter><sect1><para>
  37.802 -#: ../en/ch01-intro.xml:16
  37.803 -msgid ""
  37.804 -"Manually managing multiple versions of even a single file is an error-prone "
  37.805 -"task, though, so software tools to help automate this process have long been "
  37.806 -"available.  The earliest automated revision control tools were intended to "
  37.807 -"help a single user to manage revisions of a single file.  Over the past few "
  37.808 -"decades, the scope of revision control tools has expanded greatly; they now "
  37.809 -"manage multiple files, and help multiple people to work together.  The best "
  37.810 -"modern revision control tools have no problem coping with thousands of people "
  37.811 -"working together on projects that consist of hundreds of thousands of files."
  37.812 -msgstr ""
  37.813 -
  37.814 -#. type: Content of: <book><chapter><sect1><sect2><title>
  37.815 -#: ../en/ch01-intro.xml:28
  37.816 -msgid "Why use revision control?"
  37.817 -msgstr "为什么使用版本控制?"
  37.818 -
  37.819 -#. type: Content of: <book><chapter><sect1><sect2><para>
  37.820 -#: ../en/ch01-intro.xml:30
  37.821 -msgid ""
  37.822 -"There are a number of reasons why you or your team might want to use an "
  37.823 -"automated revision control tool for a project."
  37.824 -msgstr ""
  37.825 -
  37.826 -#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
  37.827 -#: ../en/ch01-intro.xml:34
  37.828 -msgid ""
  37.829 -"It will track the history and evolution of your project, so you don't have "
  37.830 -"to.  For every change, you'll have a log of <emphasis>who</emphasis> made it; "
  37.831 -"<emphasis>why</emphasis> they made it; <emphasis>when</emphasis> they made "
  37.832 -"it; and <emphasis>what</emphasis> the change was."
  37.833 -msgstr ""
  37.834 -
  37.835 -#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
  37.836 -#: ../en/ch01-intro.xml:41
  37.837 -msgid ""
  37.838 -"When you're working with other people, revision control software makes it "
  37.839 -"easier for you to collaborate.  For example, when people more or less "
  37.840 -"simultaneously make potentially incompatible changes, the software will help "
  37.841 -"you to identify and resolve those conflicts."
  37.842 -msgstr ""
  37.843 -
  37.844 -#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
  37.845 -#: ../en/ch01-intro.xml:47
  37.846 -msgid ""
  37.847 -"It can help you to recover from mistakes.  If you make a change that later "
  37.848 -"turns out to be in error, you can revert to an earlier version of one or more "
  37.849 -"files.  In fact, a <emphasis>really</emphasis> good revision control tool "
  37.850 -"will even help you to efficiently figure out exactly when a problem was "
  37.851 -"introduced (see section <xref linkend=\"sec.undo.bisect\"/> for details)."
  37.852 -msgstr ""
  37.853 -
  37.854 -#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
  37.855 -#: ../en/ch01-intro.xml:54
  37.856 -msgid ""
  37.857 -"It will help you to work simultaneously on, and manage the drift between, "
  37.858 -"multiple versions of your project."
  37.859 -msgstr ""
  37.860 -
  37.861 -#. type: Content of: <book><chapter><sect1><sect2><para>
  37.862 -#: ../en/ch01-intro.xml:57
  37.863 -msgid ""
  37.864 -"Most of these reasons are equally valid---at least in theory---whether you're "
  37.865 -"working on a project by yourself, or with a hundred other people."
  37.866 -msgstr ""
  37.867 -
  37.868 -#. type: Content of: <book><chapter><sect1><sect2><para>
  37.869 -#: ../en/ch01-intro.xml:61
  37.870 -msgid ""
  37.871 -"A key question about the practicality of revision control at these two "
  37.872 -"different scales (<quote>lone hacker</quote> and <quote>huge team</quote>) is "
  37.873 -"how its <emphasis>benefits</emphasis> compare to its <emphasis>costs</"
  37.874 -"emphasis>.  A revision control tool that's difficult to understand or use is "
  37.875 -"going to impose a high cost."
  37.876 -msgstr ""
  37.877 -
  37.878 -#. type: Content of: <book><chapter><sect1><sect2><para>
  37.879 -#: ../en/ch01-intro.xml:69
  37.880 -msgid ""
  37.881 -"A five-hundred-person project is likely to collapse under its own weight "
  37.882 -"almost immediately without a revision control tool and process. In this case, "
  37.883 -"the cost of using revision control might hardly seem worth considering, since "
  37.884 -"<emphasis>without</emphasis> it, failure is almost guaranteed."
  37.885 -msgstr ""
  37.886 -
  37.887 -#. type: Content of: <book><chapter><sect1><sect2><para>
  37.888 -#: ../en/ch01-intro.xml:76
  37.889 -msgid ""
  37.890 -"On the other hand, a one-person <quote>quick hack</quote> might seem like a "
  37.891 -"poor place to use a revision control tool, because surely the cost of using "
  37.892 -"one must be close to the overall cost of the project.  Right?"
  37.893 -msgstr ""
  37.894 -
  37.895 -#. type: Content of: <book><chapter><sect1><sect2><para>
  37.896 -#: ../en/ch01-intro.xml:81
  37.897 -msgid ""
  37.898 -"Mercurial uniquely supports <emphasis>both</emphasis> of these scales of "
  37.899 -"development.  You can learn the basics in just a few minutes, and due to its "
  37.900 -"low overhead, you can apply revision control to the smallest of projects with "
  37.901 -"ease.  Its simplicity means you won't have a lot of abstruse concepts or "
  37.902 -"command sequences competing for mental space with whatever you're "
  37.903 -"<emphasis>really</emphasis> trying to do.  At the same time, Mercurial's high "
  37.904 -"performance and peer-to-peer nature let you scale painlessly to handle large "
  37.905 -"projects."
  37.906 -msgstr ""
  37.907 -
  37.908 -#. type: Content of: <book><chapter><sect1><sect2><para>
  37.909 -#: ../en/ch01-intro.xml:91
  37.910 -msgid ""
  37.911 -"No revision control tool can rescue a poorly run project, but a good choice "
  37.912 -"of tools can make a huge difference to the fluidity with which you can work "
  37.913 -"on a project."
  37.914 -msgstr ""
  37.915 -
  37.916 -#. type: Content of: <book><chapter><sect1><sect2><title>
  37.917 -#: ../en/ch01-intro.xml:97
  37.918 -msgid "The many names of revision control"
  37.919 -msgstr "版本控制的别名"
  37.920 -
  37.921 -#. type: Content of: <book><chapter><sect1><sect2><para>
  37.922 -#: ../en/ch01-intro.xml:99
  37.923 -msgid ""
  37.924 -"Revision control is a diverse field, so much so that it doesn't actually have "
  37.925 -"a single name or acronym.  Here are a few of the more common names and "
  37.926 -"acronyms you'll encounter:"
  37.927 -msgstr ""
  37.928 -
  37.929 -#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
  37.930 -#: ../en/ch01-intro.xml:104
  37.931 -msgid "Revision control (RCS)"
  37.932 -msgstr "版本控制(RCS)"
  37.933 -
  37.934 -#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
  37.935 -#: ../en/ch01-intro.xml:105
  37.936 -msgid "Software configuration management (SCM), or configuration management"
  37.937 -msgstr "软件配置管理(SCM),或配置管理"
  37.938 -
  37.939 -#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
  37.940 -#: ../en/ch01-intro.xml:107
  37.941 -msgid "Source code management"
  37.942 -msgstr "源代码管理"
  37.943 -
  37.944 -#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
  37.945 -#: ../en/ch01-intro.xml:108
  37.946 -msgid "Source code control, or source control"
  37.947 -msgstr "源代码控制,或源控制"
  37.948 -
  37.949 -#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
  37.950 -#: ../en/ch01-intro.xml:110
  37.951 -msgid "Version control (VCS)"
  37.952 -msgstr "版本控制(VCS)"
  37.953 -
  37.954 -#. type: Content of: <book><chapter><sect1><sect2><para>
  37.955 -#: ../en/ch01-intro.xml:112
  37.956 -msgid ""
  37.957 -"Some people claim that these terms actually have different meanings, but in "
  37.958 -"practice they overlap so much that there's no agreed or even useful way to "
  37.959 -"tease them apart."
  37.960 -msgstr ""
  37.961 -
  37.962 -#. type: Content of: <book><chapter><sect1><title>
  37.963 -#: ../en/ch01-intro.xml:119
  37.964 -msgid "A short history of revision control"
  37.965 -msgstr "版本控制简史"
  37.966 -
  37.967 -#. type: Content of: <book><chapter><sect1><para>
  37.968 -#: ../en/ch01-intro.xml:121
  37.969 -msgid ""
  37.970 -"The best known of the old-time revision control tools is SCCS (Source Code "
  37.971 -"Control System), which Marc Rochkind wrote at Bell Labs, in the early 1970s.  "
  37.972 -"SCCS operated on individual files, and required every person working on a "
  37.973 -"project to have access to a shared workspace on a single system.  Only one "
  37.974 -"person could modify a file at any time; arbitration for access to files was "
  37.975 -"via locks.  It was common for people to lock files, and later forget to "
  37.976 -"unlock them, preventing anyone else from modifying those files without the "
  37.977 -"help of an administrator."
  37.978 -msgstr ""
  37.979 -
  37.980 -#. type: Content of: <book><chapter><sect1><para>
  37.981 -#: ../en/ch01-intro.xml:132
  37.982 -msgid ""
  37.983 -"Walter Tichy developed a free alternative to SCCS in the early 1980s; he "
  37.984 -"called his program RCS (Revision Control System).  Like SCCS, RCS required "
  37.985 -"developers to work in a single shared workspace, and to lock files to prevent "
  37.986 -"multiple people from modifying them simultaneously."
  37.987 -msgstr ""
  37.988 -
  37.989 -#. type: Content of: <book><chapter><sect1><para>
  37.990 -#: ../en/ch01-intro.xml:138
  37.991 -msgid ""
  37.992 -"Later in the 1980s, Dick Grune used RCS as a building block for a set of "
  37.993 -"shell scripts he initially called cmt, but then renamed to CVS (Concurrent "
  37.994 -"Versions System).  The big innovation of CVS was that it let developers work "
  37.995 -"simultaneously and somewhat independently in their own personal workspaces.  "
  37.996 -"The personal workspaces prevented developers from stepping on each other's "
  37.997 -"toes all the time, as was common with SCCS and RCS. Each developer had a copy "
  37.998 -"of every project file, and could modify their copies independently.  They had "
  37.999 -"to merge their edits prior to committing changes to the central repository."
 37.1000 -msgstr ""
 37.1001 -
 37.1002 -#. type: Content of: <book><chapter><sect1><para>
 37.1003 -#: ../en/ch01-intro.xml:149
 37.1004 -msgid ""
 37.1005 -"Brian Berliner took Grune's original scripts and rewrote them in C, releasing "
 37.1006 -"in 1989 the code that has since developed into the modern version of CVS.  "
 37.1007 -"CVS subsequently acquired the ability to operate over a network connection, "
 37.1008 -"giving it a client/server architecture.  CVS's architecture is centralised; "
 37.1009 -"only the server has a copy of the history of the project. Client workspaces "
 37.1010 -"just contain copies of recent versions of the project's files, and a little "
 37.1011 -"metadata to tell them where the server is.  CVS has been enormously "
 37.1012 -"successful; it is probably the world's most widely used revision control "
 37.1013 -"system."
 37.1014 -msgstr ""
 37.1015 -
 37.1016 -#. type: Content of: <book><chapter><sect1><para>
 37.1017 -#: ../en/ch01-intro.xml:160
 37.1018 -msgid ""
 37.1019 -"In the early 1990s, Sun Microsystems developed an early distributed revision "
 37.1020 -"control system, called TeamWare.  A TeamWare workspace contains a complete "
 37.1021 -"copy of the project's history.  TeamWare has no notion of a central "
 37.1022 -"repository.  (CVS relied upon RCS for its history storage; TeamWare used "
 37.1023 -"SCCS.)"
 37.1024 -msgstr ""
 37.1025 -
 37.1026 -#. type: Content of: <book><chapter><sect1><para>
 37.1027 -#: ../en/ch01-intro.xml:167
 37.1028 -msgid ""
 37.1029 -"As the 1990s progressed, awareness grew of a number of problems with CVS.  It "
 37.1030 -"records simultaneous changes to multiple files individually, instead of "
 37.1031 -"grouping them together as a single logically atomic operation.  It does not "
 37.1032 -"manage its file hierarchy well; it is easy to make a mess of a repository by "
 37.1033 -"renaming files and directories.  Worse, its source code is difficult to read "
 37.1034 -"and maintain, which made the <quote>pain level</quote> of fixing these "
 37.1035 -"architectural problems prohibitive."
 37.1036 -msgstr ""
 37.1037 -
 37.1038 -#. type: Content of: <book><chapter><sect1><para>
 37.1039 -#: ../en/ch01-intro.xml:177
 37.1040 -msgid ""
 37.1041 -"In 2001, Jim Blandy and Karl Fogel, two developers who had worked on CVS, "
 37.1042 -"started a project to replace it with a tool that would have a better "
 37.1043 -"architecture and cleaner code.  The result, Subversion, does not stray from "
 37.1044 -"CVS's centralised client/server model, but it adds multi-file atomic commits, "
 37.1045 -"better namespace management, and a number of other features that make it a "
 37.1046 -"generally better tool than CVS. Since its initial release, it has rapidly "
 37.1047 -"grown in popularity."
 37.1048 -msgstr ""
 37.1049 -
 37.1050 -#. type: Content of: <book><chapter><sect1><para>
 37.1051 -#: ../en/ch01-intro.xml:186
 37.1052 -msgid ""
 37.1053 -"More or less simultaneously, Graydon Hoare began working on an ambitious "
 37.1054 -"distributed revision control system that he named Monotone. While Monotone "
 37.1055 -"addresses many of CVS's design flaws and has a peer-to-peer architecture, it "
 37.1056 -"goes beyond earlier (and subsequent) revision control tools in a number of "
 37.1057 -"innovative ways.  It uses cryptographic hashes as identifiers, and has an "
 37.1058 -"integral notion of <quote>trust</quote> for code from different sources."
 37.1059 -msgstr ""
 37.1060 -
 37.1061 -#. type: Content of: <book><chapter><sect1><para>
 37.1062 -#: ../en/ch01-intro.xml:195
 37.1063 -msgid ""
 37.1064 -"Mercurial began life in 2005.  While a few aspects of its design are "
 37.1065 -"influenced by Monotone, Mercurial focuses on ease of use, high performance, "
 37.1066 -"and scalability to very large projects."
 37.1067 -msgstr ""
 37.1068 -
 37.1069 -#. type: Content of: <book><chapter><sect1><title>
 37.1070 -#: ../en/ch01-intro.xml:202
 37.1071 -msgid "Trends in revision control"
 37.1072 -msgstr "版本控制的发展趋势"
 37.1073 -
 37.1074 -#. type: Content of: <book><chapter><sect1><para>
 37.1075 -#: ../en/ch01-intro.xml:204
 37.1076 -msgid ""
 37.1077 -"There has been an unmistakable trend in the development and use of revision "
 37.1078 -"control tools over the past four decades, as people have become familiar with "
 37.1079 -"the capabilities of their tools and constrained by their limitations."
 37.1080 -msgstr ""
 37.1081 -
 37.1082 -#. type: Content of: <book><chapter><sect1><para>
 37.1083 -#: ../en/ch01-intro.xml:209
 37.1084 -msgid ""
 37.1085 -"The first generation began by managing single files on individual computers.  "
 37.1086 -"Although these tools represented a huge advance over ad-hoc manual revision "
 37.1087 -"control, their locking model and reliance on a single computer limited them "
 37.1088 -"to small, tightly-knit teams."
 37.1089 -msgstr ""
 37.1090 -
 37.1091 -#. type: Content of: <book><chapter><sect1><para>
 37.1092 -#: ../en/ch01-intro.xml:215
 37.1093 -msgid ""
 37.1094 -"The second generation loosened these constraints by moving to network-"
 37.1095 -"centered architectures, and managing entire projects at a time.  As projects "
 37.1096 -"grew larger, they ran into new problems.  With clients needing to talk to "
 37.1097 -"servers very frequently, server scaling became an issue for large projects.  "
 37.1098 -"An unreliable network connection could prevent remote users from being able "
 37.1099 -"to talk to the server at all.  As open source projects started making read-"
 37.1100 -"only access available anonymously to anyone, people without commit privileges "
 37.1101 -"found that they could not use the tools to interact with a project in a "
 37.1102 -"natural way, as they could not record their changes."
 37.1103 -msgstr ""
 37.1104 -
 37.1105 -#. type: Content of: <book><chapter><sect1><para>
 37.1106 -#: ../en/ch01-intro.xml:227
 37.1107 -msgid ""
 37.1108 -"The current generation of revision control tools is peer-to-peer in nature.  "
 37.1109 -"All of these systems have dropped the dependency on a single central server, "
 37.1110 -"and allow people to distribute their revision control data to where it's "
 37.1111 -"actually needed.  Collaboration over the Internet has moved from constrained "
 37.1112 -"by technology to a matter of choice and consensus.  Modern tools can operate "
 37.1113 -"offline indefinitely and autonomously, with a network connection only needed "
 37.1114 -"when syncing changes with another repository."
 37.1115 -msgstr ""
 37.1116 -
 37.1117 -#. type: Content of: <book><chapter><sect1><title>
 37.1118 -#: ../en/ch01-intro.xml:239
 37.1119 -msgid "A few of the advantages of distributed revision control"
 37.1120 -msgstr "分布版本控制的优点"
 37.1121 -
 37.1122 -#. type: Content of: <book><chapter><sect1><para>
 37.1123 -#: ../en/ch01-intro.xml:242
 37.1124 -msgid ""
 37.1125 -"Even though distributed revision control tools have for several years been as "
 37.1126 -"robust and usable as their previous-generation counterparts, people using "
 37.1127 -"older tools have not yet necessarily woken up to their advantages.  There are "
 37.1128 -"a number of ways in which distributed tools shine relative to centralised "
 37.1129 -"ones."
 37.1130 -msgstr ""
 37.1131 -
 37.1132 -#. type: Content of: <book><chapter><sect1><para>
 37.1133 -#: ../en/ch01-intro.xml:249
 37.1134 -msgid ""
 37.1135 -"For an individual developer, distributed tools are almost always much faster "
 37.1136 -"than centralised tools.  This is for a simple reason: a centralised tool "
 37.1137 -"needs to talk over the network for many common operations, because most "
 37.1138 -"metadata is stored in a single copy on the central server.  A distributed "
 37.1139 -"tool stores all of its metadata locally.  All else being equal, talking over "
 37.1140 -"the network adds overhead to a centralised tool.  Don't underestimate the "
 37.1141 -"value of a snappy, responsive tool: you're going to spend a lot of time "
 37.1142 -"interacting with your revision control software."
 37.1143 -msgstr ""
 37.1144 -
 37.1145 -#. type: Content of: <book><chapter><sect1><para>
 37.1146 -#: ../en/ch01-intro.xml:260
 37.1147 -msgid ""
 37.1148 -"Distributed tools are indifferent to the vagaries of your server "
 37.1149 -"infrastructure, again because they replicate metadata to so many locations.  "
 37.1150 -"If you use a centralised system and your server catches fire, you'd better "
 37.1151 -"hope that your backup media are reliable, and that your last backup was "
 37.1152 -"recent and actually worked.  With a distributed tool, you have many backups "
 37.1153 -"available on every contributor's computer."
 37.1154 -msgstr ""
 37.1155 -
 37.1156 -#. type: Content of: <book><chapter><sect1><para>
 37.1157 -#: ../en/ch01-intro.xml:268
 37.1158 -msgid ""
 37.1159 -"The reliability of your network will affect distributed tools far less than "
 37.1160 -"it will centralised tools.  You can't even use a centralised tool without a "
 37.1161 -"network connection, except for a few highly constrained commands.  With a "
 37.1162 -"distributed tool, if your network connection goes down while you're working, "
 37.1163 -"you may not even notice.  The only thing you won't be able to do is talk to "
 37.1164 -"repositories on other computers, something that is relatively rare compared "
 37.1165 -"with local operations.  If you have a far-flung team of collaborators, this "
 37.1166 -"may be significant."
 37.1167 -msgstr ""
 37.1168 -
 37.1169 -#. type: Content of: <book><chapter><sect1><sect2><title>
 37.1170 -#: ../en/ch01-intro.xml:279
 37.1171 -msgid "Advantages for open source projects"
 37.1172 -msgstr "开源项目的优点"
 37.1173 -
 37.1174 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1175 -#: ../en/ch01-intro.xml:281
 37.1176 -msgid ""
 37.1177 -"If you take a shine to an open source project and decide that you would like "
 37.1178 -"to start hacking on it, and that project uses a distributed revision control "
 37.1179 -"tool, you are at once a peer with the people who consider themselves the "
 37.1180 -"<quote>core</quote> of that project.  If they publish their repositories, you "
 37.1181 -"can immediately copy their project history, start making changes, and record "
 37.1182 -"your work, using the same tools in the same ways as insiders.  By contrast, "
 37.1183 -"with a centralised tool, you must use the software in a <quote>read only</"
 37.1184 -"quote> mode unless someone grants you permission to commit changes to their "
 37.1185 -"central server.  Until then, you won't be able to record changes, and your "
 37.1186 -"local modifications will be at risk of corruption any time you try to update "
 37.1187 -"your client's view of the repository."
 37.1188 -msgstr ""
 37.1189 -
 37.1190 -#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
 37.1191 -#: ../en/ch01-intro.xml:297
 37.1192 -msgid "The forking non-problem"
 37.1193 -msgstr ""
 37.1194 -
 37.1195 -#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.1196 -#: ../en/ch01-intro.xml:299
 37.1197 -msgid ""
 37.1198 -"It has been suggested that distributed revision control tools pose some sort "
 37.1199 -"of risk to open source projects because they make it easy to <quote>fork</"
 37.1200 -"quote> the development of a project.  A fork happens when there are "
 37.1201 -"differences in opinion or attitude between groups of developers that cause "
 37.1202 -"them to decide that they can't work together any longer.  Each side takes a "
 37.1203 -"more or less complete copy of the project's source code, and goes off in its "
 37.1204 -"own direction."
 37.1205 -msgstr ""
 37.1206 -
 37.1207 -#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.1208 -#: ../en/ch01-intro.xml:309
 37.1209 -msgid ""
 37.1210 -"Sometimes the camps in a fork decide to reconcile their differences. With a "
 37.1211 -"centralised revision control system, the <emphasis>technical</emphasis> "
 37.1212 -"process of reconciliation is painful, and has to be performed largely by "
 37.1213 -"hand.  You have to decide whose revision history is going to <quote>win</"
 37.1214 -"quote>, and graft the other team's changes into the tree somehow. This "
 37.1215 -"usually loses some or all of one side's revision history."
 37.1216 -msgstr ""
 37.1217 -
 37.1218 -#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.1219 -#: ../en/ch01-intro.xml:318
 37.1220 -msgid ""
 37.1221 -"What distributed tools do with respect to forking is they make forking the "
 37.1222 -"<emphasis>only</emphasis> way to develop a project.  Every single change that "
 37.1223 -"you make is potentially a fork point.  The great strength of this approach is "
 37.1224 -"that a distributed revision control tool has to be really good at "
 37.1225 -"<emphasis>merging</emphasis> forks, because forks are absolutely fundamental: "
 37.1226 -"they happen all the time."
 37.1227 -msgstr ""
 37.1228 -
 37.1229 -#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.1230 -#: ../en/ch01-intro.xml:327
 37.1231 -msgid ""
 37.1232 -"If every piece of work that everybody does, all the time, is framed in terms "
 37.1233 -"of forking and merging, then what the open source world refers to as a "
 37.1234 -"<quote>fork</quote> becomes <emphasis>purely</emphasis> a social issue.  If "
 37.1235 -"anything, distributed tools <emphasis>lower</emphasis> the likelihood of a "
 37.1236 -"fork:"
 37.1237 -msgstr ""
 37.1238 -
 37.1239 -#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
 37.1240 -#: ../en/ch01-intro.xml:334
 37.1241 -msgid ""
 37.1242 -"They eliminate the social distinction that centralised tools impose: that "
 37.1243 -"between insiders (people with commit access) and outsiders (people without)."
 37.1244 -msgstr ""
 37.1245 -
 37.1246 -#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
 37.1247 -#: ../en/ch01-intro.xml:338
 37.1248 -msgid ""
 37.1249 -"They make it easier to reconcile after a social fork, because all that's "
 37.1250 -"involved from the perspective of the revision control software is just "
 37.1251 -"another merge."
 37.1252 -msgstr ""
 37.1253 -
 37.1254 -#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.1255 -#: ../en/ch01-intro.xml:343
 37.1256 -msgid ""
 37.1257 -"Some people resist distributed tools because they want to retain tight "
 37.1258 -"control over their projects, and they believe that centralised tools give "
 37.1259 -"them this control.  However, if you're of this belief, and you publish your "
 37.1260 -"CVS or Subversion repositories publicly, there are plenty of tools available "
 37.1261 -"that can pull out your entire project's history (albeit slowly) and recreate "
 37.1262 -"it somewhere that you don't control.  So while your control in this case is "
 37.1263 -"illusory, you are forgoing the ability to fluidly collaborate with whatever "
 37.1264 -"people feel compelled to mirror and fork your history."
 37.1265 -msgstr ""
 37.1266 -
 37.1267 -#. type: Content of: <book><chapter><sect1><sect2><title>
 37.1268 -#: ../en/ch01-intro.xml:358
 37.1269 -msgid "Advantages for commercial projects"
 37.1270 -msgstr "商业项目的优点"
 37.1271 -
 37.1272 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1273 -#: ../en/ch01-intro.xml:360
 37.1274 -msgid ""
 37.1275 -"Many commercial projects are undertaken by teams that are scattered across "
 37.1276 -"the globe.  Contributors who are far from a central server will see slower "
 37.1277 -"command execution and perhaps less reliability.  Commercial revision control "
 37.1278 -"systems attempt to ameliorate these problems with remote-site replication add-"
 37.1279 -"ons that are typically expensive to buy and cantankerous to administer.  A "
 37.1280 -"distributed system doesn't suffer from these problems in the first place.  "
 37.1281 -"Better yet, you can easily set up multiple authoritative servers, say one per "
 37.1282 -"site, so that there's no redundant communication between repositories over "
 37.1283 -"expensive long-haul network links."
 37.1284 -msgstr ""
 37.1285 -
 37.1286 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1287 -#: ../en/ch01-intro.xml:372
 37.1288 -msgid ""
 37.1289 -"Centralised revision control systems tend to have relatively low "
 37.1290 -"scalability.  It's not unusual for an expensive centralised system to fall "
 37.1291 -"over under the combined load of just a few dozen concurrent users.  Once "
 37.1292 -"again, the typical response tends to be an expensive and clunky replication "
 37.1293 -"facility.  Since the load on a central server---if you have one at all---is "
 37.1294 -"many times lower with a distributed tool (because all of the data is "
 37.1295 -"replicated everywhere), a single cheap server can handle the needs of a much "
 37.1296 -"larger team, and replication to balance load becomes a simple matter of "
 37.1297 -"scripting."
 37.1298 -msgstr ""
 37.1299 -
 37.1300 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1301 -#: ../en/ch01-intro.xml:384
 37.1302 -msgid ""
 37.1303 -"If you have an employee in the field, troubleshooting a problem at a "
 37.1304 -"customer's site, they'll benefit from distributed revision control. The tool "
 37.1305 -"will let them generate custom builds, try different fixes in isolation from "
 37.1306 -"each other, and search efficiently through history for the sources of bugs "
 37.1307 -"and regressions in the customer's environment, all without needing to connect "
 37.1308 -"to your company's network."
 37.1309 -msgstr ""
 37.1310 -
 37.1311 -#. type: Content of: <book><chapter><sect1><title>
 37.1312 -#: ../en/ch01-intro.xml:395
 37.1313 -msgid "Why choose Mercurial?"
 37.1314 -msgstr "为什么选择 Mercurial?"
 37.1315 -
 37.1316 -#. type: Content of: <book><chapter><sect1><para>
 37.1317 -#: ../en/ch01-intro.xml:397
 37.1318 -msgid ""
 37.1319 -"Mercurial has a unique set of properties that make it a particularly good "
 37.1320 -"choice as a revision control system."
 37.1321 -msgstr ""
 37.1322 -
 37.1323 -#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.1324 -#: ../en/ch01-intro.xml:400
 37.1325 -msgid "It is easy to learn and use."
 37.1326 -msgstr ""
 37.1327 -
 37.1328 -#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.1329 -#: ../en/ch01-intro.xml:401
 37.1330 -msgid "It is lightweight."
 37.1331 -msgstr ""
 37.1332 -
 37.1333 -#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.1334 -#: ../en/ch01-intro.xml:402
 37.1335 -msgid "It scales excellently."
 37.1336 -msgstr ""
 37.1337 -
 37.1338 -#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.1339 -#: ../en/ch01-intro.xml:403
 37.1340 -msgid "It is easy to customise."
 37.1341 -msgstr ""
 37.1342 -
 37.1343 -#. type: Content of: <book><chapter><sect1><para>
 37.1344 -#: ../en/ch01-intro.xml:406
 37.1345 -msgid ""
 37.1346 -"If you are at all familiar with revision control systems, you should be able "
 37.1347 -"to get up and running with Mercurial in less than five minutes.  Even if not, "
 37.1348 -"it will take no more than a few minutes longer.  Mercurial's command and "
 37.1349 -"feature sets are generally uniform and consistent, so you can keep track of a "
 37.1350 -"few general rules instead of a host of exceptions."
 37.1351 -msgstr ""
 37.1352 -
 37.1353 -#. type: Content of: <book><chapter><sect1><para>
 37.1354 -#: ../en/ch01-intro.xml:413
 37.1355 -msgid ""
 37.1356 -"On a small project, you can start working with Mercurial in moments. Creating "
 37.1357 -"new changes and branches; transferring changes around (whether locally or "
 37.1358 -"over a network); and history and status operations are all fast.  Mercurial "
 37.1359 -"attempts to stay nimble and largely out of your way by combining low "
 37.1360 -"cognitive overhead with blazingly fast operations."
 37.1361 -msgstr ""
 37.1362 -
 37.1363 -#. type: Content of: <book><chapter><sect1><para>
 37.1364 -#: ../en/ch01-intro.xml:420
 37.1365 -msgid ""
 37.1366 -"The usefulness of Mercurial is not limited to small projects: it is used by "
 37.1367 -"projects with hundreds to thousands of contributors, each containing tens of "
 37.1368 -"thousands of files and hundreds of megabytes of source code."
 37.1369 -msgstr ""
 37.1370 -
 37.1371 -#. type: Content of: <book><chapter><sect1><para>
 37.1372 -#: ../en/ch01-intro.xml:425
 37.1373 -msgid ""
 37.1374 -"If the core functionality of Mercurial is not enough for you, it's easy to "
 37.1375 -"build on.  Mercurial is well suited to scripting tasks, and its clean "
 37.1376 -"internals and implementation in Python make it easy to add features in the "
 37.1377 -"form of extensions.  There are a number of popular and useful extensions "
 37.1378 -"already available, ranging from helping to identify bugs to improving "
 37.1379 -"performance."
 37.1380 -msgstr ""
 37.1381 -
 37.1382 -#. type: Content of: <book><chapter><sect1><title>
 37.1383 -#: ../en/ch01-intro.xml:435
 37.1384 -msgid "Mercurial compared with other tools"
 37.1385 -msgstr "Mercurial 与其它工具的比较"
 37.1386 -
 37.1387 -#. type: Content of: <book><chapter><sect1><para>
 37.1388 -#: ../en/ch01-intro.xml:437
 37.1389 -msgid ""
 37.1390 -"Before you read on, please understand that this section necessarily reflects "
 37.1391 -"my own experiences, interests, and (dare I say it) biases.  I have used every "
 37.1392 -"one of the revision control tools listed below, in most cases for several "
 37.1393 -"years at a time."
 37.1394 -msgstr ""
 37.1395 -
 37.1396 -#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.1397 -#: ../en/ch01-intro.xml:445 ../en/ch01-intro.xml:656
 37.1398 -msgid "Subversion"
 37.1399 -msgstr ""
 37.1400 -
 37.1401 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1402 -#: ../en/ch01-intro.xml:447
 37.1403 -msgid ""
 37.1404 -"Subversion is a popular revision control tool, developed to replace CVS.  It "
 37.1405 -"has a centralised client/server architecture."
 37.1406 -msgstr ""
 37.1407 -
 37.1408 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1409 -#: ../en/ch01-intro.xml:451
 37.1410 -msgid ""
 37.1411 -"Subversion and Mercurial have similarly named commands for performing the "
 37.1412 -"same operations, so if you're familiar with one, it is easy to learn to use "
 37.1413 -"the other.  Both tools are portable to all popular operating systems."
 37.1414 -msgstr ""
 37.1415 -
 37.1416 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1417 -#: ../en/ch01-intro.xml:456
 37.1418 -msgid ""
 37.1419 -"Prior to version 1.5, Subversion had no useful support for merges. At the "
 37.1420 -"time of writing, its merge tracking capability is new, and known to be <ulink "
 37.1421 -"url=\"http://svnbook.red-bean.com/nightly/en/svn.branchmerge.advanced."
 37.1422 -"html#svn.branchmerge.advanced.finalword\">complicated and buggy</ulink>."
 37.1423 -msgstr ""
 37.1424 -
 37.1425 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1426 -#: ../en/ch01-intro.xml:462
 37.1427 -msgid ""
 37.1428 -"Mercurial has a substantial performance advantage over Subversion on every "
 37.1429 -"revision control operation I have benchmarked.  I have measured its advantage "
 37.1430 -"as ranging from a factor of two to a factor of six when compared with "
 37.1431 -"Subversion 1.4.3's <emphasis>ra_local</emphasis> file store, which is the "
 37.1432 -"fastest access method available.  In more realistic deployments involving a "
 37.1433 -"network-based store, Subversion will be at a substantially larger "
 37.1434 -"disadvantage.  Because many Subversion commands must talk to the server and "
 37.1435 -"Subversion does not have useful replication facilities, server capacity and "
 37.1436 -"network bandwidth become bottlenecks for modestly large projects."
 37.1437 -msgstr ""
 37.1438 -
 37.1439 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1440 -#: ../en/ch01-intro.xml:475
 37.1441 -msgid ""
 37.1442 -"Additionally, Subversion incurs substantial storage overhead to avoid network "
 37.1443 -"transactions for a few common operations, such as finding modified files "
 37.1444 -"(<literal>status</literal>) and displaying modifications against the current "
 37.1445 -"revision (<literal>diff</literal>).  As a result, a Subversion working copy "
 37.1446 -"is often the same size as, or larger than, a Mercurial repository and working "
 37.1447 -"directory, even though the Mercurial repository contains a complete history "
 37.1448 -"of the project."
 37.1449 -msgstr ""
 37.1450 -
 37.1451 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1452 -#: ../en/ch01-intro.xml:485
 37.1453 -msgid ""
 37.1454 -"Subversion is widely supported by third party tools.  Mercurial currently "
 37.1455 -"lags considerably in this area.  This gap is closing, however, and indeed "
 37.1456 -"some of Mercurial's GUI tools now outshine their Subversion equivalents.  "
 37.1457 -"Like Mercurial, Subversion has an excellent user manual."
 37.1458 -msgstr ""
 37.1459 -
 37.1460 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1461 -#: ../en/ch01-intro.xml:491
 37.1462 -msgid ""
 37.1463 -"Because Subversion doesn't store revision history on the client, it is well "
 37.1464 -"suited to managing projects that deal with lots of large, opaque binary "
 37.1465 -"files.  If you check in fifty revisions to an incompressible 10MB file, "
 37.1466 -"Subversion's client-side space usage stays constant The space used by any "
 37.1467 -"distributed SCM will grow rapidly in proportion to the number of revisions, "
 37.1468 -"because the differences between each revision are large."
 37.1469 -msgstr ""
 37.1470 -
 37.1471 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1472 -#: ../en/ch01-intro.xml:500
 37.1473 -msgid ""
 37.1474 -"In addition, it's often difficult or, more usually, impossible to merge "
 37.1475 -"different versions of a binary file.  Subversion's ability to let a user lock "
 37.1476 -"a file, so that they temporarily have the exclusive right to commit changes "
 37.1477 -"to it, can be a significant advantage to a project where binary files are "
 37.1478 -"widely used."
 37.1479 -msgstr ""
 37.1480 -
 37.1481 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1482 -#: ../en/ch01-intro.xml:507
 37.1483 -msgid ""
 37.1484 -"Mercurial can import revision history from a Subversion repository. It can "
 37.1485 -"also export revision history to a Subversion repository.  This makes it easy "
 37.1486 -"to <quote>test the waters</quote> and use Mercurial and Subversion in "
 37.1487 -"parallel before deciding to switch.  History conversion is incremental, so "
 37.1488 -"you can perform an initial conversion, then small additional conversions "
 37.1489 -"afterwards to bring in new changes."
 37.1490 -msgstr ""
 37.1491 -
 37.1492 -#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.1493 -#: ../en/ch01-intro.xml:519 ../en/ch01-intro.xml:658
 37.1494 -msgid "Git"
 37.1495 -msgstr ""
 37.1496 -
 37.1497 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1498 -#: ../en/ch01-intro.xml:521
 37.1499 -msgid ""
 37.1500 -"Git is a distributed revision control tool that was developed for managing "
 37.1501 -"the Linux kernel source tree.  Like Mercurial, its early design was somewhat "
 37.1502 -"influenced by Monotone."
 37.1503 -msgstr ""
 37.1504 -
 37.1505 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1506 -#: ../en/ch01-intro.xml:526
 37.1507 -msgid ""
 37.1508 -"Git has a very large command set, with version 1.5.0 providing 139 individual "
 37.1509 -"commands.  It has something of a reputation for being difficult to learn.  "
 37.1510 -"Compared to Git, Mercurial has a strong focus on simplicity."
 37.1511 -msgstr ""
 37.1512 -
 37.1513 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1514 -#: ../en/ch01-intro.xml:531
 37.1515 -msgid ""
 37.1516 -"In terms of performance, Git is extremely fast.  In several cases, it is "
 37.1517 -"faster than Mercurial, at least on Linux, while Mercurial performs better on "
 37.1518 -"other operations.  However, on Windows, the performance and general level of "
 37.1519 -"support that Git provides is, at the time of writing, far behind that of "
 37.1520 -"Mercurial."
 37.1521 -msgstr ""
 37.1522 -
 37.1523 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1524 -#: ../en/ch01-intro.xml:538
 37.1525 -msgid ""
 37.1526 -"While a Mercurial repository needs no maintenance, a Git repository requires "
 37.1527 -"frequent manual <quote>repacks</quote> of its metadata.  Without these, "
 37.1528 -"performance degrades, while space usage grows rapidly.  A server that "
 37.1529 -"contains many Git repositories that are not rigorously and frequently "
 37.1530 -"repacked will become heavily disk-bound during backups, and there have been "
 37.1531 -"instances of daily backups taking far longer than 24 hours as a result.  A "
 37.1532 -"freshly packed Git repository is slightly smaller than a Mercurial "
 37.1533 -"repository, but an unpacked repository is several orders of magnitude larger."
 37.1534 -msgstr ""
 37.1535 -
 37.1536 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1537 -#: ../en/ch01-intro.xml:549
 37.1538 -msgid ""
 37.1539 -"The core of Git is written in C.  Many Git commands are implemented as shell "
 37.1540 -"or Perl scripts, and the quality of these scripts varies widely. I have "
 37.1541 -"encountered several instances where scripts charged along blindly in the "
 37.1542 -"presence of errors that should have been fatal."
 37.1543 -msgstr ""
 37.1544 -
 37.1545 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1546 -#: ../en/ch01-intro.xml:555
 37.1547 -msgid "Mercurial can import revision history from a Git repository."
 37.1548 -msgstr ""
 37.1549 -
 37.1550 -#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.1551 -#: ../en/ch01-intro.xml:561 ../en/ch01-intro.xml:657
 37.1552 -msgid "CVS"
 37.1553 -msgstr ""
 37.1554 -
 37.1555 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1556 -#: ../en/ch01-intro.xml:563
 37.1557 -msgid ""
 37.1558 -"CVS is probably the most widely used revision control tool in the world.  Due "
 37.1559 -"to its age and internal untidiness, it has been only lightly maintained for "
 37.1560 -"many years."
 37.1561 -msgstr ""
 37.1562 -
 37.1563 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1564 -#: ../en/ch01-intro.xml:567
 37.1565 -msgid ""
 37.1566 -"It has a centralised client/server architecture.  It does not group related "
 37.1567 -"file changes into atomic commits, making it easy for people to <quote>break "
 37.1568 -"the build</quote>: one person can successfully commit part of a change and "
 37.1569 -"then be blocked by the need for a merge, causing other people to see only a "
 37.1570 -"portion of the work they intended to do.  This also affects how you work with "
 37.1571 -"project history.  If you want to see all of the modifications someone made as "
 37.1572 -"part of a task, you will need to manually inspect the descriptions and "
 37.1573 -"timestamps of the changes made to each file involved (if you even know what "
 37.1574 -"those files were)."
 37.1575 -msgstr ""
 37.1576 -
 37.1577 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1578 -#: ../en/ch01-intro.xml:579
 37.1579 -msgid ""
 37.1580 -"CVS has a muddled notion of tags and branches that I will not attempt to even "
 37.1581 -"describe.  It does not support renaming of files or directories well, making "
 37.1582 -"it easy to corrupt a repository.  It has almost no internal consistency "
 37.1583 -"checking capabilities, so it is usually not even possible to tell whether or "
 37.1584 -"how a repository is corrupt.  I would not recommend CVS for any project, "
 37.1585 -"existing or new."
 37.1586 -msgstr ""
 37.1587 -
 37.1588 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1589 -#: ../en/ch01-intro.xml:587
 37.1590 -msgid ""
 37.1591 -"Mercurial can import CVS revision history.  However, there are a few caveats "
 37.1592 -"that apply; these are true of every other revision control tool's CVS "
 37.1593 -"importer, too.  Due to CVS's lack of atomic changes and unversioned "
 37.1594 -"filesystem hierarchy, it is not possible to reconstruct CVS history "
 37.1595 -"completely accurately; some guesswork is involved, and renames will usually "
 37.1596 -"not show up.  Because a lot of advanced CVS administration has to be done by "
 37.1597 -"hand and is hence error-prone, it's common for CVS importers to run into "
 37.1598 -"multiple problems with corrupted repositories (completely bogus revision "
 37.1599 -"timestamps and files that have remained locked for over a decade are just two "
 37.1600 -"of the less interesting problems I can recall from personal experience)."
 37.1601 -msgstr ""
 37.1602 -
 37.1603 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1604 -#: ../en/ch01-intro.xml:601
 37.1605 -msgid "Mercurial can import revision history from a CVS repository."
 37.1606 -msgstr ""
 37.1607 -
 37.1608 -#. type: Content of: <book><chapter><sect1><sect2><title>
 37.1609 -#: ../en/ch01-intro.xml:607
 37.1610 -msgid "Commercial tools"
 37.1611 -msgstr "商业工具"
 37.1612 -
 37.1613 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1614 -#: ../en/ch01-intro.xml:609
 37.1615 -msgid ""
 37.1616 -"Perforce has a centralised client/server architecture, with no client-side "
 37.1617 -"caching of any data.  Unlike modern revision control tools, Perforce requires "
 37.1618 -"that a user run a command to inform the server about every file they intend "
 37.1619 -"to edit."
 37.1620 -msgstr ""
 37.1621 -
 37.1622 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1623 -#: ../en/ch01-intro.xml:615
 37.1624 -msgid ""
 37.1625 -"The performance of Perforce is quite good for small teams, but it falls off "
 37.1626 -"rapidly as the number of users grows beyond a few dozen. Modestly large "
 37.1627 -"Perforce installations require the deployment of proxies to cope with the "
 37.1628 -"load their users generate."
 37.1629 -msgstr ""
 37.1630 -
 37.1631 -#. type: Content of: <book><chapter><sect1><sect2><title>
 37.1632 -#: ../en/ch01-intro.xml:624
 37.1633 -msgid "Choosing a revision control tool"
 37.1634 -msgstr "选择版本控制工具"
 37.1635 -
 37.1636 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1637 -#: ../en/ch01-intro.xml:626
 37.1638 -msgid ""
 37.1639 -"With the exception of CVS, all of the tools listed above have unique "
 37.1640 -"strengths that suit them to particular styles of work.  There is no single "
 37.1641 -"revision control tool that is best in all situations."
 37.1642 -msgstr ""
 37.1643 -
 37.1644 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1645 -#: ../en/ch01-intro.xml:631
 37.1646 -msgid ""
 37.1647 -"As an example, Subversion is a good choice for working with frequently edited "
 37.1648 -"binary files, due to its centralised nature and support for file locking."
 37.1649 -msgstr ""
 37.1650 -
 37.1651 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.1652 -#: ../en/ch01-intro.xml:635
 37.1653 -msgid ""
 37.1654 -"I personally find Mercurial's properties of simplicity, performance, and good "
 37.1655 -"merge support to be a compelling combination that has served me well for "
 37.1656 -"several years."
 37.1657 -msgstr ""
 37.1658 -
 37.1659 -#. type: Content of: <book><chapter><sect1><title>
 37.1660 -#: ../en/ch01-intro.xml:643
 37.1661 -msgid "Switching from another tool to Mercurial"
 37.1662 -msgstr "从其它工具切换到 Mercurial"
 37.1663 -
 37.1664 -#. type: Content of: <book><chapter><sect1><para>
 37.1665 -#: ../en/ch01-intro.xml:645
 37.1666 -msgid ""
 37.1667 -"Mercurial is bundled with an extension named <literal role=\"hg-ext"
 37.1668 -"\">convert</literal>, which can incrementally import revision history from "
 37.1669 -"several other revision control tools.  By <quote>incremental</quote>, I mean "
 37.1670 -"that you can convert all of a project's history to date in one go, then rerun "
 37.1671 -"the conversion later to obtain new changes that happened after the initial "
 37.1672 -"conversion."
 37.1673 -msgstr ""
 37.1674 -
 37.1675 -#. type: Content of: <book><chapter><sect1><para>
 37.1676 -#: ../en/ch01-intro.xml:653
 37.1677 -msgid ""
 37.1678 -"The revision control tools supported by <literal role=\"hg-ext\">convert</"
 37.1679 -"literal> are as follows:"
 37.1680 -msgstr ""
 37.1681 -
 37.1682 -#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.1683 -#: ../en/ch01-intro.xml:659
 37.1684 -msgid "Darcs"
 37.1685 -msgstr ""
 37.1686 -
 37.1687 -#. type: Content of: <book><chapter><sect1><para>
 37.1688 -#: ../en/ch01-intro.xml:661
 37.1689 -msgid ""
 37.1690 -"In addition, <literal role=\"hg-ext\">convert</literal> can export changes "
 37.1691 -"from Mercurial to Subversion.  This makes it possible to try Subversion and "
 37.1692 -"Mercurial in parallel before committing to a switchover, without risking the "
 37.1693 -"loss of any work."
 37.1694 -msgstr ""
 37.1695 -
 37.1696 -#. type: Content of: <book><chapter><sect1><para>
 37.1697 -#: ../en/ch01-intro.xml:667
 37.1698 -msgid ""
 37.1699 -"The <command role=\"hg-ext-conver\">convert</command> command is easy to "
 37.1700 -"use.  Simply point it at the path or URL of the source repository, optionally "
 37.1701 -"give it the name of the destination repository, and it will start working.  "
 37.1702 -"After the initial conversion, just run the same command again to import new "
 37.1703 -"changes."
 37.1704 -msgstr ""
 37.1705 -
 37.1706 -#. type: Content of: <book><chapter><title>
 37.1707 -#: ../en/ch02-tour-basic.xml:5
 37.1708 +#: ../en/ch01-tour-basic.xml:5
 37.1709  msgid "A tour of Mercurial: the basics"
 37.1710  msgstr "Mercurial 教程: 基础知识"
 37.1711  
 37.1712  #. type: Content of: <book><chapter><sect1><title>
 37.1713 -#: ../en/ch02-tour-basic.xml:8
 37.1714 +#: ../en/ch01-tour-basic.xml:8
 37.1715  msgid "Installing Mercurial on your system"
 37.1716  msgstr "安装 Mercurial"
 37.1717  
 37.1718  #. type: Content of: <book><chapter><sect1><para>
 37.1719 -#: ../en/ch02-tour-basic.xml:10
 37.1720 +#: ../en/ch01-tour-basic.xml:10
 37.1721  msgid ""
 37.1722  "Prebuilt binary packages of Mercurial are available for every popular "
 37.1723  "operating system.  These make it easy to start using Mercurial on your "
 37.1724 @@ -2463,12 +1540,12 @@
 37.1725  "用 Mercurial 变得很容易。"
 37.1726  
 37.1727  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.1728 -#: ../en/ch02-tour-basic.xml:15
 37.1729 +#: ../en/ch01-tour-basic.xml:15
 37.1730  msgid "Linux"
 37.1731  msgstr "Linux"
 37.1732  
 37.1733  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.1734 -#: ../en/ch02-tour-basic.xml:17
 37.1735 +#: ../en/ch01-tour-basic.xml:17
 37.1736  msgid ""
 37.1737  "Because each Linux distribution has its own packaging tools, policies, and "
 37.1738  "rate of development, it's difficult to give a comprehensive set of "
 37.1739 @@ -2481,7 +1558,7 @@
 37.1740  "使用的发行版的 Mercurial 维护者的活跃程度。"
 37.1741  
 37.1742  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.1743 -#: ../en/ch02-tour-basic.xml:24
 37.1744 +#: ../en/ch01-tour-basic.xml:24
 37.1745  msgid ""
 37.1746  "To keep things simple, I will focus on installing Mercurial from the command "
 37.1747  "line under the most popular Linux distributions.  Most of these distributions "
 37.1748 @@ -2493,39 +1570,39 @@
 37.1749  "Mercurial;寻找的包名称是 <literal>mercurial</literal>。"
 37.1750  
 37.1751  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.1752 -#: ../en/ch02-tour-basic.xml:32
 37.1753 +#: ../en/ch01-tour-basic.xml:32
 37.1754  msgid "Debian:"
 37.1755  msgstr "Debian:"
 37.1756  
 37.1757  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.1758 -#: ../en/ch02-tour-basic.xml:34
 37.1759 +#: ../en/ch01-tour-basic.xml:34
 37.1760  msgid "Fedora Core:"
 37.1761  msgstr "Fedora Core:"
 37.1762  
 37.1763  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.1764 -#: ../en/ch02-tour-basic.xml:36
 37.1765 +#: ../en/ch01-tour-basic.xml:36
 37.1766  msgid "Gentoo:"
 37.1767  msgstr "Gentoo:"
 37.1768  
 37.1769  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.1770 -#: ../en/ch02-tour-basic.xml:38
 37.1771 +#: ../en/ch01-tour-basic.xml:38
 37.1772  msgid "OpenSUSE:"
 37.1773  msgstr "OpenSUSE:"
 37.1774  
 37.1775  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.1776 -#: ../en/ch02-tour-basic.xml:40
 37.1777 +#: ../en/ch01-tour-basic.xml:40
 37.1778  msgid ""
 37.1779  "Ubuntu: Ubuntu's Mercurial package is based on Debian's.  To install it, run "
 37.1780  "the following command."
 37.1781  msgstr "Ubuntu: Ubuntu 的 Mercurial 包基于 Debian。安装时,使用如下命令:"
 37.1782  
 37.1783  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.1784 -#: ../en/ch02-tour-basic.xml:48
 37.1785 +#: ../en/ch01-tour-basic.xml:48
 37.1786  msgid "Solaris"
 37.1787  msgstr "Solaris"
 37.1788  
 37.1789  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.1790 -#: ../en/ch02-tour-basic.xml:50
 37.1791 +#: ../en/ch01-tour-basic.xml:50
 37.1792  msgid ""
 37.1793  "SunFreeWare, at <ulink url=\"http://www.sunfreeware.com\">http://www."
 37.1794  "sunfreeware.com</ulink>, is a good source for a large number of pre-built "
 37.1795 @@ -2537,12 +1614,12 @@
 37.1796  "和 64 位包,包含 Mercurial 的当前版本。"
 37.1797  
 37.1798  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.1799 -#: ../en/ch02-tour-basic.xml:58
 37.1800 +#: ../en/ch01-tour-basic.xml:58
 37.1801  msgid "Mac OS X"
 37.1802  msgstr "Mac OS X"
 37.1803  
 37.1804  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.1805 -#: ../en/ch02-tour-basic.xml:60
 37.1806 +#: ../en/ch01-tour-basic.xml:60
 37.1807  msgid ""
 37.1808  "Lee Cantey publishes an installer of Mercurial for Mac OS X at <ulink url="
 37.1809  "\"http://mercurial.berkwood.com\">http://mercurial.berkwood.com</ulink>.  "
 37.1810 @@ -2553,7 +1630,7 @@
 37.1811  msgstr ""
 37.1812  
 37.1813  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.1814 -#: ../en/ch02-tour-basic.xml:69
 37.1815 +#: ../en/ch01-tour-basic.xml:69
 37.1816  msgid ""
 37.1817  "It's also possible to install Mercurial using Fink or MacPorts, two popular "
 37.1818  "free package managers for Mac OS X.  If you have Fink, use <command>sudo apt-"
 37.1819 @@ -2562,12 +1639,12 @@
 37.1820  msgstr ""
 37.1821  
 37.1822  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.1823 -#: ../en/ch02-tour-basic.xml:77
 37.1824 +#: ../en/ch01-tour-basic.xml:77
 37.1825  msgid "Windows"
 37.1826  msgstr ""
 37.1827  
 37.1828  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.1829 -#: ../en/ch02-tour-basic.xml:79
 37.1830 +#: ../en/ch01-tour-basic.xml:79
 37.1831  msgid ""
 37.1832  "Lee Cantey publishes an installer of Mercurial for Windows at <ulink url="
 37.1833  "\"http://mercurial.berkwood.com\">http://mercurial.berkwood.com</ulink>.  "
 37.1834 @@ -2575,7 +1652,7 @@
 37.1835  msgstr ""
 37.1836  
 37.1837  #. type: Content of: <book><chapter><sect1><sect2><note><para>
 37.1838 -#: ../en/ch02-tour-basic.xml:86
 37.1839 +#: ../en/ch01-tour-basic.xml:86
 37.1840  msgid ""
 37.1841  "The Windows version of Mercurial does not automatically convert line endings "
 37.1842  "between Windows and Unix styles.  If you want to share work with Unix users, "
 37.1843 @@ -2583,12 +1660,12 @@
 37.1844  msgstr ""
 37.1845  
 37.1846  #. type: Content of: <book><chapter><sect1><title>
 37.1847 -#: ../en/ch02-tour-basic.xml:96
 37.1848 +#: ../en/ch01-tour-basic.xml:96
 37.1849  msgid "Getting started"
 37.1850  msgstr "开始"
 37.1851  
 37.1852  #. type: Content of: <book><chapter><sect1><para>
 37.1853 -#: ../en/ch02-tour-basic.xml:98
 37.1854 +#: ../en/ch01-tour-basic.xml:98
 37.1855  msgid ""
 37.1856  "To begin, we'll use the <command role=\"hg-cmd\">hg version</command> command "
 37.1857  "to find out whether Mercurial is actually installed properly.  The actual "
 37.1858 @@ -2597,12 +1674,12 @@
 37.1859  msgstr ""
 37.1860  
 37.1861  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.1862 -#: ../en/ch02-tour-basic.xml:107
 37.1863 +#: ../en/ch01-tour-basic.xml:107
 37.1864  msgid "Built-in help"
 37.1865  msgstr "内置帮助"
 37.1866  
 37.1867  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.1868 -#: ../en/ch02-tour-basic.xml:109
 37.1869 +#: ../en/ch01-tour-basic.xml:109
 37.1870  msgid ""
 37.1871  "Mercurial provides a built-in help system.  This is invaluable for those "
 37.1872  "times when you find yourself stuck trying to remember how to run a command.  "
 37.1873 @@ -2613,7 +1690,7 @@
 37.1874  msgstr ""
 37.1875  
 37.1876  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.1877 -#: ../en/ch02-tour-basic.xml:120
 37.1878 +#: ../en/ch01-tour-basic.xml:120
 37.1879  msgid ""
 37.1880  "For a more impressive level of detail (which you won't usually need) run "
 37.1881  "<command role=\"hg-cmd\">hg help <option role=\"hg-opt-global\">-v</option></"
 37.1882 @@ -2623,12 +1700,12 @@
 37.1883  msgstr ""
 37.1884  
 37.1885  #. type: Content of: <book><chapter><sect1><title>
 37.1886 -#: ../en/ch02-tour-basic.xml:131
 37.1887 +#: ../en/ch01-tour-basic.xml:131
 37.1888  msgid "Working with a repository"
 37.1889  msgstr "使用版本库"
 37.1890  
 37.1891  #. type: Content of: <book><chapter><sect1><para>
 37.1892 -#: ../en/ch02-tour-basic.xml:133
 37.1893 +#: ../en/ch01-tour-basic.xml:133
 37.1894  msgid ""
 37.1895  "In Mercurial, everything happens inside a <emphasis>repository</emphasis>.  "
 37.1896  "The repository for a project contains all of the files that <quote>belong to</"
 37.1897 @@ -2636,7 +1713,7 @@
 37.1898  msgstr ""
 37.1899  
 37.1900  #. type: Content of: <book><chapter><sect1><para>
 37.1901 -#: ../en/ch02-tour-basic.xml:139
 37.1902 +#: ../en/ch01-tour-basic.xml:139
 37.1903  msgid ""
 37.1904  "There's nothing particularly magical about a repository; it is simply a "
 37.1905  "directory tree in your filesystem that Mercurial treats as special. You can "
 37.1906 @@ -2645,12 +1722,12 @@
 37.1907  msgstr ""
 37.1908  
 37.1909  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.1910 -#: ../en/ch02-tour-basic.xml:146
 37.1911 +#: ../en/ch01-tour-basic.xml:146
 37.1912  msgid "Making a local copy of a repository"
 37.1913  msgstr "创建版本库的工作副本"
 37.1914  
 37.1915  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.1916 -#: ../en/ch02-tour-basic.xml:148
 37.1917 +#: ../en/ch01-tour-basic.xml:148
 37.1918  msgid ""
 37.1919  "<emphasis>Copying</emphasis> a repository is just a little bit special.  "
 37.1920  "While you could use a normal file copying command to make a copy of a "
 37.1921 @@ -2660,21 +1737,21 @@
 37.1922  msgstr ""
 37.1923  
 37.1924  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.1925 -#: ../en/ch02-tour-basic.xml:157
 37.1926 +#: ../en/ch01-tour-basic.xml:157
 37.1927  msgid ""
 37.1928  "If our clone succeeded, we should now have a local directory called <filename "
 37.1929  "class=\"directory\">hello</filename>.  This directory will contain some files."
 37.1930  msgstr ""
 37.1931  
 37.1932  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.1933 -#: ../en/ch02-tour-basic.xml:163
 37.1934 +#: ../en/ch01-tour-basic.xml:163
 37.1935  msgid ""
 37.1936  "These files have the same contents and history in our repository as they do "
 37.1937  "in the repository we cloned."
 37.1938  msgstr ""
 37.1939  
 37.1940  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.1941 -#: ../en/ch02-tour-basic.xml:166
 37.1942 +#: ../en/ch01-tour-basic.xml:166
 37.1943  msgid ""
 37.1944  "Every Mercurial repository is complete, self-contained, and independent.  It "
 37.1945  "contains its own private copy of a project's files and history.  A cloned "
 37.1946 @@ -2684,7 +1761,7 @@
 37.1947  msgstr ""
 37.1948  
 37.1949  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.1950 -#: ../en/ch02-tour-basic.xml:173
 37.1951 +#: ../en/ch01-tour-basic.xml:173
 37.1952  msgid ""
 37.1953  "What this means for now is that we're free to experiment with our repository, "
 37.1954  "safe in the knowledge that it's a private <quote>sandbox</quote> that won't "
 37.1955 @@ -2692,12 +1769,12 @@
 37.1956  msgstr ""
 37.1957  
 37.1958  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.1959 -#: ../en/ch02-tour-basic.xml:179
 37.1960 +#: ../en/ch01-tour-basic.xml:179
 37.1961  msgid "What's in a repository?"
 37.1962  msgstr "什么是版本库?"
 37.1963  
 37.1964  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.1965 -#: ../en/ch02-tour-basic.xml:181
 37.1966 +#: ../en/ch01-tour-basic.xml:181
 37.1967  msgid ""
 37.1968  "When we take a more detailed look inside a repository, we can see that it "
 37.1969  "contains a directory named <filename class=\"directory\">.hg</filename>.  "
 37.1970 @@ -2705,7 +1782,7 @@
 37.1971  msgstr ""
 37.1972  
 37.1973  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.1974 -#: ../en/ch02-tour-basic.xml:188
 37.1975 +#: ../en/ch01-tour-basic.xml:188
 37.1976  msgid ""
 37.1977  "The contents of the <filename class=\"directory\">.hg</filename> directory "
 37.1978  "and its subdirectories are private to Mercurial.  Every other file and "
 37.1979 @@ -2713,7 +1790,7 @@
 37.1980  msgstr ""
 37.1981  
 37.1982  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.1983 -#: ../en/ch02-tour-basic.xml:194
 37.1984 +#: ../en/ch01-tour-basic.xml:194
 37.1985  msgid ""
 37.1986  "To introduce a little terminology, the <filename class=\"directory\">.hg</"
 37.1987  "filename> directory is the <quote>real</quote> repository, and all of the "
 37.1988 @@ -2726,12 +1803,12 @@
 37.1989  msgstr ""
 37.1990  
 37.1991  #. type: Content of: <book><chapter><sect1><title>
 37.1992 -#: ../en/ch02-tour-basic.xml:209
 37.1993 +#: ../en/ch01-tour-basic.xml:209
 37.1994  msgid "A tour through history"
 37.1995  msgstr "回溯历史"
 37.1996  
 37.1997  #. type: Content of: <book><chapter><sect1><para>
 37.1998 -#: ../en/ch02-tour-basic.xml:211
 37.1999 +#: ../en/ch01-tour-basic.xml:211
 37.2000  msgid ""
 37.2001  "One of the first things we might want to do with a new, unfamiliar repository "
 37.2002  "is understand its history.  The <command role=\"hg-cmd\">hg log</command> "
 37.2003 @@ -2739,7 +1816,7 @@
 37.2004  msgstr ""
 37.2005  
 37.2006  #. type: Content of: <book><chapter><sect1><para>
 37.2007 -#: ../en/ch02-tour-basic.xml:218
 37.2008 +#: ../en/ch01-tour-basic.xml:218
 37.2009  msgid ""
 37.2010  "By default, this command prints a brief paragraph of output for each change "
 37.2011  "to the project that was recorded.  In Mercurial terminology, we call each of "
 37.2012 @@ -2748,14 +1825,14 @@
 37.2013  msgstr ""
 37.2014  
 37.2015  #. type: Content of: <book><chapter><sect1><para>
 37.2016 -#: ../en/ch02-tour-basic.xml:224
 37.2017 +#: ../en/ch01-tour-basic.xml:224
 37.2018  msgid ""
 37.2019  "The fields in a record of output from <command role=\"hg-cmd\">hg log</"
 37.2020  "command> are as follows."
 37.2021  msgstr ""
 37.2022  
 37.2023  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.2024 -#: ../en/ch02-tour-basic.xml:227
 37.2025 +#: ../en/ch01-tour-basic.xml:227
 37.2026  msgid ""
 37.2027  "<literal>changeset</literal>: This field has the format of a number, followed "
 37.2028  "by a colon, followed by a hexadecimal string.  These are "
 37.2029 @@ -2765,7 +1842,7 @@
 37.2030  msgstr ""
 37.2031  
 37.2032  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.2033 -#: ../en/ch02-tour-basic.xml:233
 37.2034 +#: ../en/ch01-tour-basic.xml:233
 37.2035  msgid ""
 37.2036  "<literal>user</literal>: The identity of the person who created the "
 37.2037  "changeset.  This is a free-form field, but it most often contains a person's "
 37.2038 @@ -2773,7 +1850,7 @@
 37.2039  msgstr ""
 37.2040  
 37.2041  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.2042 -#: ../en/ch02-tour-basic.xml:237
 37.2043 +#: ../en/ch01-tour-basic.xml:237
 37.2044  msgid ""
 37.2045  "<literal>date</literal>: The date and time on which the changeset was "
 37.2046  "created, and the timezone in which it was created.  (The date and time are "
 37.2047 @@ -2782,21 +1859,21 @@
 37.2048  msgstr ""
 37.2049  
 37.2050  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.2051 -#: ../en/ch02-tour-basic.xml:242
 37.2052 +#: ../en/ch01-tour-basic.xml:242
 37.2053  msgid ""
 37.2054  "<literal>summary</literal>: The first line of the text message that the "
 37.2055  "creator of the changeset entered to describe the changeset."
 37.2056  msgstr ""
 37.2057  
 37.2058  #. type: Content of: <book><chapter><sect1><para>
 37.2059 -#: ../en/ch02-tour-basic.xml:245
 37.2060 +#: ../en/ch01-tour-basic.xml:245
 37.2061  msgid ""
 37.2062  "The default output printed by <command role=\"hg-cmd\">hg log</command> is "
 37.2063  "purely a summary; it is missing a lot of detail."
 37.2064  msgstr ""
 37.2065  
 37.2066  #. type: Content of: <book><chapter><sect1><para>
 37.2067 -#: ../en/ch02-tour-basic.xml:249
 37.2068 +#: ../en/ch01-tour-basic.xml:249
 37.2069  msgid ""
 37.2070  "Figure <xref endterm=\"fig.tour-basic.history.caption\" linkend=\"fig.tour-"
 37.2071  "basic.history\"/> provides a graphical representation of the history of the "
 37.2072 @@ -2807,39 +1884,39 @@
 37.2073  msgstr ""
 37.2074  
 37.2075  #. type: Content of: <book><chapter><sect1><informalfigure><mediaobject>
 37.2076 -#: ../en/ch02-tour-basic.xml:260
 37.2077 +#: ../en/ch01-tour-basic.xml:260
 37.2078  msgid ""
 37.2079  "<imageobject><imagedata fileref=\"images/tour-history.png\"/></imageobject>"
 37.2080  msgstr ""
 37.2081  
 37.2082  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><textobject><phrase>
 37.2083 -#: ../en/ch02-tour-basic.xml:261 ../en/ch03-tour-merge.xml:48
 37.2084 -#: ../en/ch03-tour-merge.xml:78 ../en/ch03-tour-merge.xml:126
 37.2085 -#: ../en/ch03-tour-merge.xml:182 ../en/ch03-tour-merge.xml:254
 37.2086 -#: ../en/ch04-concepts.xml:56 ../en/ch04-concepts.xml:108
 37.2087 -#: ../en/ch04-concepts.xml:194 ../en/ch04-concepts.xml:301
 37.2088 -#: ../en/ch04-concepts.xml:353 ../en/ch04-concepts.xml:370
 37.2089 -#: ../en/ch04-concepts.xml:414 ../en/ch04-concepts.xml:436
 37.2090 -#: ../en/ch04-concepts.xml:480 ../en/ch06-collab.xml:277
 37.2091 -#: ../en/ch09-undo.xml:366 ../en/ch09-undo.xml:417 ../en/ch09-undo.xml:485
 37.2092 -#: ../en/ch09-undo.xml:527 ../en/ch12-mq.xml:409
 37.2093 +#: ../en/ch01-tour-basic.xml:261 ../en/ch02-tour-merge.xml:48
 37.2094 +#: ../en/ch02-tour-merge.xml:78 ../en/ch02-tour-merge.xml:126
 37.2095 +#: ../en/ch02-tour-merge.xml:182 ../en/ch02-tour-merge.xml:254
 37.2096 +#: ../en/ch03-concepts.xml:56 ../en/ch03-concepts.xml:108
 37.2097 +#: ../en/ch03-concepts.xml:194 ../en/ch03-concepts.xml:301
 37.2098 +#: ../en/ch03-concepts.xml:353 ../en/ch03-concepts.xml:370
 37.2099 +#: ../en/ch03-concepts.xml:414 ../en/ch03-concepts.xml:436
 37.2100 +#: ../en/ch03-concepts.xml:480 ../en/ch05-collab.xml:277
 37.2101 +#: ../en/ch08-undo.xml:366 ../en/ch08-undo.xml:417 ../en/ch08-undo.xml:485
 37.2102 +#: ../en/ch08-undo.xml:527 ../en/ch11-mq.xml:410
 37.2103  msgid "XXX add text"
 37.2104  msgstr ""
 37.2105  
 37.2106  #. type: Content of: <book><chapter><sect1><informalfigure><mediaobject><caption><para>
 37.2107 -#: ../en/ch02-tour-basic.xml:262
 37.2108 +#: ../en/ch01-tour-basic.xml:262
 37.2109  msgid ""
 37.2110  "Graphical history of the <filename class=\"directory\">hello</filename> "
 37.2111  "repository"
 37.2112  msgstr ""
 37.2113  
 37.2114  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.2115 -#: ../en/ch02-tour-basic.xml:269
 37.2116 +#: ../en/ch01-tour-basic.xml:269
 37.2117  msgid "Changesets, revisions, and talking to other people"
 37.2118  msgstr "改变集,版本,与其它用户交互"
 37.2119  
 37.2120  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2121 -#: ../en/ch02-tour-basic.xml:272
 37.2122 +#: ../en/ch01-tour-basic.xml:272
 37.2123  msgid ""
 37.2124  "As English is a notoriously sloppy language, and computer science has a "
 37.2125  "hallowed history of terminological confusion (why use one term when four will "
 37.2126 @@ -2851,7 +1928,7 @@
 37.2127  msgstr ""
 37.2128  
 37.2129  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2130 -#: ../en/ch02-tour-basic.xml:282
 37.2131 +#: ../en/ch01-tour-basic.xml:282
 37.2132  msgid ""
 37.2133  "While it doesn't matter what <emphasis>word</emphasis> you use to refer to "
 37.2134  "the concept of <quote>a changeset</quote>, the <emphasis>identifier</"
 37.2135 @@ -2862,13 +1939,13 @@
 37.2136  msgstr ""
 37.2137  
 37.2138  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.2139 -#: ../en/ch02-tour-basic.xml:291
 37.2140 +#: ../en/ch01-tour-basic.xml:291
 37.2141  msgid ""
 37.2142  "The revision number is <emphasis>only valid in that repository</emphasis>,"
 37.2143  msgstr ""
 37.2144  
 37.2145  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.2146 -#: ../en/ch02-tour-basic.xml:293
 37.2147 +#: ../en/ch01-tour-basic.xml:293
 37.2148  msgid ""
 37.2149  "while the hex string is the <emphasis>permanent, unchanging identifier</"
 37.2150  "emphasis> that will always identify that exact changeset in <emphasis>every</"
 37.2151 @@ -2876,7 +1953,7 @@
 37.2152  msgstr ""
 37.2153  
 37.2154  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2155 -#: ../en/ch02-tour-basic.xml:298
 37.2156 +#: ../en/ch01-tour-basic.xml:298
 37.2157  msgid ""
 37.2158  "This distinction is important.  If you send someone an email talking about "
 37.2159  "<quote>revision 33</quote>, there's a high likelihood that their revision 33 "
 37.2160 @@ -2888,7 +1965,7 @@
 37.2161  msgstr ""
 37.2162  
 37.2163  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2164 -#: ../en/ch02-tour-basic.xml:308
 37.2165 +#: ../en/ch01-tour-basic.xml:308
 37.2166  msgid ""
 37.2167  "Mercurial uses revision numbers purely as a convenient shorthand.  If you "
 37.2168  "need to discuss a changeset with someone, or make a record of a changeset for "
 37.2169 @@ -2897,12 +1974,12 @@
 37.2170  msgstr ""
 37.2171  
 37.2172  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.2173 -#: ../en/ch02-tour-basic.xml:316
 37.2174 +#: ../en/ch01-tour-basic.xml:316
 37.2175  msgid "Viewing specific revisions"
 37.2176  msgstr "察看指定版本"
 37.2177  
 37.2178  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2179 -#: ../en/ch02-tour-basic.xml:318
 37.2180 +#: ../en/ch01-tour-basic.xml:318
 37.2181  msgid ""
 37.2182  "To narrow the output of <command role=\"hg-cmd\">hg log</command> down to a "
 37.2183  "single revision, use the <option role=\"hg-opt-log\">-r</option> (or <option "
 37.2184 @@ -2912,7 +1989,7 @@
 37.2185  msgstr ""
 37.2186  
 37.2187  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2188 -#: ../en/ch02-tour-basic.xml:327
 37.2189 +#: ../en/ch01-tour-basic.xml:327
 37.2190  msgid ""
 37.2191  "If you want to see the history of several revisions without having to list "
 37.2192  "each one, you can use <emphasis>range notation</emphasis>; this lets you "
 37.2193 @@ -2921,7 +1998,7 @@
 37.2194  msgstr ""
 37.2195  
 37.2196  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2197 -#: ../en/ch02-tour-basic.xml:335
 37.2198 +#: ../en/ch01-tour-basic.xml:335
 37.2199  msgid ""
 37.2200  "Mercurial also honours the order in which you specify revisions, so <command "
 37.2201  "role=\"hg-cmd\">hg log -r 2:4</command> prints 2, 3, and 4. while <command "
 37.2202 @@ -2929,12 +2006,12 @@
 37.2203  msgstr ""
 37.2204  
 37.2205  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.2206 -#: ../en/ch02-tour-basic.xml:342
 37.2207 +#: ../en/ch01-tour-basic.xml:342
 37.2208  msgid "More detailed information"
 37.2209  msgstr "更详细的信息"
 37.2210  
 37.2211  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2212 -#: ../en/ch02-tour-basic.xml:344
 37.2213 +#: ../en/ch01-tour-basic.xml:344
 37.2214  msgid ""
 37.2215  "While the summary information printed by <command role=\"hg-cmd\">hg log</"
 37.2216  "command> is useful if you already know what you're looking for, you may need "
 37.2217 @@ -2946,7 +2023,7 @@
 37.2218  msgstr ""
 37.2219  
 37.2220  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2221 -#: ../en/ch02-tour-basic.xml:356
 37.2222 +#: ../en/ch01-tour-basic.xml:356
 37.2223  msgid ""
 37.2224  "If you want to see both the description and content of a change, add the "
 37.2225  "<option role=\"hg-opt-log\">-p</option> (or <option role=\"hg-opt-log\">--"
 37.2226 @@ -2956,12 +2033,12 @@
 37.2227  msgstr ""
 37.2228  
 37.2229  #. type: Content of: <book><chapter><sect1><title>
 37.2230 -#: ../en/ch02-tour-basic.xml:369
 37.2231 +#: ../en/ch01-tour-basic.xml:369
 37.2232  msgid "All about command options"
 37.2233  msgstr "命令选项"
 37.2234  
 37.2235  #. type: Content of: <book><chapter><sect1><para>
 37.2236 -#: ../en/ch02-tour-basic.xml:371
 37.2237 +#: ../en/ch01-tour-basic.xml:371
 37.2238  msgid ""
 37.2239  "Let's take a brief break from exploring Mercurial commands to discuss a "
 37.2240  "pattern in the way that they work; you may find this useful to keep in mind "
 37.2241 @@ -2969,7 +2046,7 @@
 37.2242  msgstr ""
 37.2243  
 37.2244  #. type: Content of: <book><chapter><sect1><para>
 37.2245 -#: ../en/ch02-tour-basic.xml:375
 37.2246 +#: ../en/ch01-tour-basic.xml:375
 37.2247  msgid ""
 37.2248  "Mercurial has a consistent and straightforward approach to dealing with the "
 37.2249  "options that you can pass to commands.  It follows the conventions for "
 37.2250 @@ -2977,7 +2054,7 @@
 37.2251  msgstr ""
 37.2252  
 37.2253  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.2254 -#: ../en/ch02-tour-basic.xml:380
 37.2255 +#: ../en/ch01-tour-basic.xml:380
 37.2256  msgid ""
 37.2257  "Every option has a long name.  For example, as we've already seen, the "
 37.2258  "<command role=\"hg-cmd\">hg log</command> command accepts a <option role=\"hg-"
 37.2259 @@ -2985,7 +2062,7 @@
 37.2260  msgstr ""
 37.2261  
 37.2262  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.2263 -#: ../en/ch02-tour-basic.xml:384
 37.2264 +#: ../en/ch01-tour-basic.xml:384
 37.2265  msgid ""
 37.2266  "Most options have short names, too.  Instead of <option role=\"hg-opt-log\">--"
 37.2267  "rev</option>, we can use <option role=\"hg-opt-log\">-r</option>.  (The "
 37.2268 @@ -2994,7 +2071,7 @@
 37.2269  msgstr ""
 37.2270  
 37.2271  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.2272 -#: ../en/ch02-tour-basic.xml:389
 37.2273 +#: ../en/ch01-tour-basic.xml:389
 37.2274  msgid ""
 37.2275  "Long options start with two dashes (e.g. <option role=\"hg-opt-log\">--rev</"
 37.2276  "option>), while short options start with one (e.g. <option role=\"hg-opt-log"
 37.2277 @@ -3002,7 +2079,7 @@
 37.2278  msgstr ""
 37.2279  
 37.2280  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.2281 -#: ../en/ch02-tour-basic.xml:393
 37.2282 +#: ../en/ch01-tour-basic.xml:393
 37.2283  msgid ""
 37.2284  "Option naming and usage is consistent across commands.  For example, every "
 37.2285  "command that lets you specify a changeset ID or revision number accepts both "
 37.2286 @@ -3011,7 +2088,7 @@
 37.2287  msgstr ""
 37.2288  
 37.2289  #. type: Content of: <book><chapter><sect1><para>
 37.2290 -#: ../en/ch02-tour-basic.xml:399
 37.2291 +#: ../en/ch01-tour-basic.xml:399
 37.2292  msgid ""
 37.2293  "In the examples throughout this book, I use short options instead of long.  "
 37.2294  "This just reflects my own preference, so don't read anything significant into "
 37.2295 @@ -3019,7 +2096,7 @@
 37.2296  msgstr ""
 37.2297  
 37.2298  #. type: Content of: <book><chapter><sect1><para>
 37.2299 -#: ../en/ch02-tour-basic.xml:403
 37.2300 +#: ../en/ch01-tour-basic.xml:403
 37.2301  msgid ""
 37.2302  "Most commands that print output of some kind will print more output when "
 37.2303  "passed a <option role=\"hg-opt-global\">-v</option> (or <option role=\"hg-opt-"
 37.2304 @@ -3028,19 +2105,19 @@
 37.2305  msgstr ""
 37.2306  
 37.2307  #. type: Content of: <book><chapter><sect1><title>
 37.2308 -#: ../en/ch02-tour-basic.xml:411
 37.2309 +#: ../en/ch01-tour-basic.xml:411
 37.2310  msgid "Making and reviewing changes"
 37.2311  msgstr "创建和复审修改"
 37.2312  
 37.2313  #. type: Content of: <book><chapter><sect1><para>
 37.2314 -#: ../en/ch02-tour-basic.xml:413
 37.2315 +#: ../en/ch01-tour-basic.xml:413
 37.2316  msgid ""
 37.2317  "Now that we have a grasp of viewing history in Mercurial, let's take a look "
 37.2318  "at making some changes and examining them."
 37.2319  msgstr ""
 37.2320  
 37.2321  #. type: Content of: <book><chapter><sect1><para>
 37.2322 -#: ../en/ch02-tour-basic.xml:417
 37.2323 +#: ../en/ch01-tour-basic.xml:417
 37.2324  msgid ""
 37.2325  "The first thing we'll do is isolate our experiment in a repository of its "
 37.2326  "own.  We use the <command role=\"hg-cmd\">hg clone</command> command, but we "
 37.2327 @@ -3051,7 +2128,7 @@
 37.2328  msgstr ""
 37.2329  
 37.2330  #. type: Content of: <book><chapter><sect1><para>
 37.2331 -#: ../en/ch02-tour-basic.xml:427
 37.2332 +#: ../en/ch01-tour-basic.xml:427
 37.2333  msgid ""
 37.2334  "As an aside, it's often good practice to keep a <quote>pristine</quote> copy "
 37.2335  "of a remote repository around, which you can then make temporary clones of to "
 37.2336 @@ -3063,7 +2140,7 @@
 37.2337  msgstr ""
 37.2338  
 37.2339  #. type: Content of: <book><chapter><sect1><para>
 37.2340 -#: ../en/ch02-tour-basic.xml:436
 37.2341 +#: ../en/ch01-tour-basic.xml:436
 37.2342  msgid ""
 37.2343  "In our <filename class=\"directory\">my-hello</filename> repository, we have "
 37.2344  "a file <filename>hello.c</filename> that contains the classic <quote>hello, "
 37.2345 @@ -3076,14 +2153,14 @@
 37.2346  msgstr ""
 37.2347  
 37.2348  #. type: Content of: <book><chapter><sect1><para>
 37.2349 -#: ../en/ch02-tour-basic.xml:449
 37.2350 +#: ../en/ch01-tour-basic.xml:449
 37.2351  msgid ""
 37.2352  "Mercurial's <command role=\"hg-cmd\">hg status</command> command will tell us "
 37.2353  "what Mercurial knows about the files in the repository."
 37.2354  msgstr ""
 37.2355  
 37.2356  #. type: Content of: <book><chapter><sect1><para>
 37.2357 -#: ../en/ch02-tour-basic.xml:455
 37.2358 +#: ../en/ch01-tour-basic.xml:455
 37.2359  msgid ""
 37.2360  "The <command role=\"hg-cmd\">hg status</command> command prints no output for "
 37.2361  "some files, but a line starting with <quote><literal>M</literal></quote> for "
 37.2362 @@ -3093,7 +2170,7 @@
 37.2363  msgstr ""
 37.2364  
 37.2365  #. type: Content of: <book><chapter><sect1><para>
 37.2366 -#: ../en/ch02-tour-basic.xml:462
 37.2367 +#: ../en/ch01-tour-basic.xml:462
 37.2368  msgid ""
 37.2369  "The <quote><literal>M</literal></quote> indicates that Mercurial has noticed "
 37.2370  "that we modified <filename>hello.c</filename>.  We didn't need to "
 37.2371 @@ -3103,7 +2180,7 @@
 37.2372  msgstr ""
 37.2373  
 37.2374  #. type: Content of: <book><chapter><sect1><para>
 37.2375 -#: ../en/ch02-tour-basic.xml:470
 37.2376 +#: ../en/ch01-tour-basic.xml:470
 37.2377  msgid ""
 37.2378  "It's a little bit helpful to know that we've modified <filename>hello.c</"
 37.2379  "filename>, but we might prefer to know exactly <emphasis>what</emphasis> "
 37.2380 @@ -3112,12 +2189,12 @@
 37.2381  msgstr ""
 37.2382  
 37.2383  #. type: Content of: <book><chapter><sect1><title>
 37.2384 -#: ../en/ch02-tour-basic.xml:480
 37.2385 +#: ../en/ch01-tour-basic.xml:480
 37.2386  msgid "Recording changes in a new changeset"
 37.2387  msgstr "在新修改集中记录修改"
 37.2388  
 37.2389  #. type: Content of: <book><chapter><sect1><para>
 37.2390 -#: ../en/ch02-tour-basic.xml:482
 37.2391 +#: ../en/ch01-tour-basic.xml:482
 37.2392  msgid ""
 37.2393  "We can modify files, build and test our changes, and use <command role=\"hg-"
 37.2394  "cmd\">hg status</command> and <command role=\"hg-cmd\">hg diff</command> to "
 37.2395 @@ -3126,7 +2203,7 @@
 37.2396  msgstr ""
 37.2397  
 37.2398  #. type: Content of: <book><chapter><sect1><para>
 37.2399 -#: ../en/ch02-tour-basic.xml:489
 37.2400 +#: ../en/ch01-tour-basic.xml:489
 37.2401  msgid ""
 37.2402  "The <command role=\"hg-cmd\">hg commit</command> command lets us create a new "
 37.2403  "changeset; we'll usually refer to this as <quote>making a commit</quote> or "
 37.2404 @@ -3134,12 +2211,12 @@
 37.2405  msgstr ""
 37.2406  
 37.2407  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.2408 -#: ../en/ch02-tour-basic.xml:495
 37.2409 +#: ../en/ch01-tour-basic.xml:495
 37.2410  msgid "Setting up a username"
 37.2411  msgstr "配置用户名称"
 37.2412  
 37.2413  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2414 -#: ../en/ch02-tour-basic.xml:497
 37.2415 +#: ../en/ch01-tour-basic.xml:497
 37.2416  msgid ""
 37.2417  "When you try to run <command role=\"hg-cmd\">hg commit</command> for the "
 37.2418  "first time, it is not guaranteed to succeed.  Mercurial records your name and "
 37.2419 @@ -3150,7 +2227,7 @@
 37.2420  msgstr ""
 37.2421  
 37.2422  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.2423 -#: ../en/ch02-tour-basic.xml:506
 37.2424 +#: ../en/ch01-tour-basic.xml:506
 37.2425  msgid ""
 37.2426  "If you specify a <option role=\"hg-opt-commit\">-u</option> option to the "
 37.2427  "<command role=\"hg-cmd\">hg commit</command> command on the command line, "
 37.2428 @@ -3158,14 +2235,14 @@
 37.2429  msgstr ""
 37.2430  
 37.2431  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.2432 -#: ../en/ch02-tour-basic.xml:511
 37.2433 +#: ../en/ch01-tour-basic.xml:511
 37.2434  msgid ""
 37.2435  "If you have set the <envar>HGUSER</envar> environment variable, this is "
 37.2436  "checked next."
 37.2437  msgstr ""
 37.2438  
 37.2439  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.2440 -#: ../en/ch02-tour-basic.xml:514
 37.2441 +#: ../en/ch01-tour-basic.xml:514
 37.2442  msgid ""
 37.2443  "If you create a file in your home directory called <filename role=\"special"
 37.2444  "\">.hgrc</filename>, with a <envar role=\"rc-item-ui\">username</envar> "
 37.2445 @@ -3174,14 +2251,14 @@
 37.2446  msgstr ""
 37.2447  
 37.2448  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.2449 -#: ../en/ch02-tour-basic.xml:521
 37.2450 +#: ../en/ch01-tour-basic.xml:521
 37.2451  msgid ""
 37.2452  "If you have set the <envar>EMAIL</envar> environment variable, this will be "
 37.2453  "used next."
 37.2454  msgstr ""
 37.2455  
 37.2456  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.2457 -#: ../en/ch02-tour-basic.xml:524
 37.2458 +#: ../en/ch01-tour-basic.xml:524
 37.2459  msgid ""
 37.2460  "Mercurial will query your system to find out your local user name and host "
 37.2461  "name, and construct a username from these components. Since this often "
 37.2462 @@ -3190,7 +2267,7 @@
 37.2463  msgstr ""
 37.2464  
 37.2465  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2466 -#: ../en/ch02-tour-basic.xml:531
 37.2467 +#: ../en/ch01-tour-basic.xml:531
 37.2468  msgid ""
 37.2469  "If all of these mechanisms fail, Mercurial will fail, printing an error "
 37.2470  "message.  In this case, it will not let you commit until you set up a "
 37.2471 @@ -3198,7 +2275,7 @@
 37.2472  msgstr ""
 37.2473  
 37.2474  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2475 -#: ../en/ch02-tour-basic.xml:535
 37.2476 +#: ../en/ch01-tour-basic.xml:535
 37.2477  msgid ""
 37.2478  "You should think of the <envar>HGUSER</envar> environment variable and the "
 37.2479  "<option role=\"hg-opt-commit\">-u</option> option to the <command role=\"hg-"
 37.2480 @@ -3209,12 +2286,12 @@
 37.2481  msgstr ""
 37.2482  
 37.2483  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
 37.2484 -#: ../en/ch02-tour-basic.xml:544
 37.2485 +#: ../en/ch01-tour-basic.xml:544
 37.2486  msgid "Creating a Mercurial configuration file"
 37.2487  msgstr "创建 Mercurial 的配置文件"
 37.2488  
 37.2489  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.2490 -#: ../en/ch02-tour-basic.xml:546
 37.2491 +#: ../en/ch01-tour-basic.xml:546
 37.2492  msgid ""
 37.2493  "To set a user name, use your favourite editor to create a file called "
 37.2494  "<filename role=\"special\">.hgrc</filename> in your home directory.  "
 37.2495 @@ -3224,7 +2301,7 @@
 37.2496  msgstr ""
 37.2497  
 37.2498  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.2499 -#: ../en/ch02-tour-basic.xml:557
 37.2500 +#: ../en/ch01-tour-basic.xml:558
 37.2501  msgid ""
 37.2502  "The <quote><literal>[ui]</literal></quote> line begins a <emphasis>section</"
 37.2503  "emphasis> of the config file, so you can read the <quote><literal>username "
 37.2504 @@ -3236,12 +2313,12 @@
 37.2505  msgstr ""
 37.2506  
 37.2507  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
 37.2508 -#: ../en/ch02-tour-basic.xml:570
 37.2509 +#: ../en/ch01-tour-basic.xml:571
 37.2510  msgid "Choosing a user name"
 37.2511  msgstr "选择用户名称"
 37.2512  
 37.2513  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.2514 -#: ../en/ch02-tour-basic.xml:572
 37.2515 +#: ../en/ch01-tour-basic.xml:573
 37.2516  msgid ""
 37.2517  "You can use any text you like as the value of the <literal>username</literal> "
 37.2518  "config item, since this information is for reading by other people, but for "
 37.2519 @@ -3250,7 +2327,7 @@
 37.2520  msgstr ""
 37.2521  
 37.2522  #. type: Content of: <book><chapter><sect1><sect2><sect3><note><para>
 37.2523 -#: ../en/ch02-tour-basic.xml:579
 37.2524 +#: ../en/ch01-tour-basic.xml:580
 37.2525  msgid ""
 37.2526  "Mercurial's built-in web server obfuscates email addresses, to make it more "
 37.2527  "difficult for the email harvesting tools that spammers use. This reduces the "
 37.2528 @@ -3259,12 +2336,12 @@
 37.2529  msgstr ""
 37.2530  
 37.2531  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.2532 -#: ../en/ch02-tour-basic.xml:589
 37.2533 +#: ../en/ch01-tour-basic.xml:590
 37.2534  msgid "Writing a commit message"
 37.2535  msgstr "写提交日志"
 37.2536  
 37.2537  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2538 -#: ../en/ch02-tour-basic.xml:591
 37.2539 +#: ../en/ch01-tour-basic.xml:592
 37.2540  msgid ""
 37.2541  "When we commit a change, Mercurial drops us into a text editor, to enter a "
 37.2542  "message that will describe the modifications we've made in this changeset.  "
 37.2543 @@ -3274,7 +2351,7 @@
 37.2544  msgstr ""
 37.2545  
 37.2546  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2547 -#: ../en/ch02-tour-basic.xml:601
 37.2548 +#: ../en/ch01-tour-basic.xml:602
 37.2549  msgid ""
 37.2550  "The editor that the <command role=\"hg-cmd\">hg commit</command> command "
 37.2551  "drops us into will contain an empty line, followed by a number of lines "
 37.2552 @@ -3282,7 +2359,7 @@
 37.2553  msgstr ""
 37.2554  
 37.2555  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2556 -#: ../en/ch02-tour-basic.xml:608
 37.2557 +#: ../en/ch01-tour-basic.xml:609
 37.2558  msgid ""
 37.2559  "Mercurial ignores the lines that start with <quote><literal>HG:</literal></"
 37.2560  "quote>; it uses them only to tell us which files it's recording changes to.  "
 37.2561 @@ -3290,12 +2367,12 @@
 37.2562  msgstr ""
 37.2563  
 37.2564  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.2565 -#: ../en/ch02-tour-basic.xml:614
 37.2566 +#: ../en/ch01-tour-basic.xml:615
 37.2567  msgid "Writing a good commit message"
 37.2568  msgstr "写好提交日志"
 37.2569  
 37.2570  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2571 -#: ../en/ch02-tour-basic.xml:616
 37.2572 +#: ../en/ch01-tour-basic.xml:617
 37.2573  msgid ""
 37.2574  "Since <command role=\"hg-cmd\">hg log</command> only prints the first line of "
 37.2575  "a commit message by default, it's best to write a commit message whose first "
 37.2576 @@ -3305,7 +2382,7 @@
 37.2577  msgstr ""
 37.2578  
 37.2579  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2580 -#: ../en/ch02-tour-basic.xml:630
 37.2581 +#: ../en/ch01-tour-basic.xml:631
 37.2582  msgid ""
 37.2583  "As far as the remainder of the contents of the commit message are concerned, "
 37.2584  "there are no hard-and-fast rules.  Mercurial itself doesn't interpret or care "
 37.2585 @@ -3314,7 +2391,7 @@
 37.2586  msgstr ""
 37.2587  
 37.2588  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2589 -#: ../en/ch02-tour-basic.xml:636
 37.2590 +#: ../en/ch01-tour-basic.xml:637
 37.2591  msgid ""
 37.2592  "My personal preference is for short, but informative, commit messages that "
 37.2593  "tell me something that I can't figure out with a quick glance at the output "
 37.2594 @@ -3322,12 +2399,12 @@
 37.2595  msgstr ""
 37.2596  
 37.2597  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.2598 -#: ../en/ch02-tour-basic.xml:643
 37.2599 +#: ../en/ch01-tour-basic.xml:644
 37.2600  msgid "Aborting a commit"
 37.2601  msgstr "终止提交"
 37.2602  
 37.2603  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2604 -#: ../en/ch02-tour-basic.xml:645
 37.2605 +#: ../en/ch01-tour-basic.xml:646
 37.2606  msgid ""
 37.2607  "If you decide that you don't want to commit while in the middle of editing a "
 37.2608  "commit message, simply exit from your editor without saving the file that "
 37.2609 @@ -3336,7 +2413,7 @@
 37.2610  msgstr ""
 37.2611  
 37.2612  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2613 -#: ../en/ch02-tour-basic.xml:650
 37.2614 +#: ../en/ch01-tour-basic.xml:651
 37.2615  msgid ""
 37.2616  "If we run the <command role=\"hg-cmd\">hg commit</command> command without "
 37.2617  "any arguments, it records all of the changes we've made, as reported by "
 37.2618 @@ -3345,12 +2422,12 @@
 37.2619  msgstr ""
 37.2620  
 37.2621  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.2622 -#: ../en/ch02-tour-basic.xml:657
 37.2623 +#: ../en/ch01-tour-basic.xml:658
 37.2624  msgid "Admiring our new handiwork"
 37.2625  msgstr "欣赏我们的新手艺"
 37.2626  
 37.2627  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2628 -#: ../en/ch02-tour-basic.xml:659
 37.2629 +#: ../en/ch01-tour-basic.xml:660
 37.2630  msgid ""
 37.2631  "Once we've finished the commit, we can use the <command role=\"hg-cmd\">hg "
 37.2632  "tip</command> command to display the changeset we just created.  This command "
 37.2633 @@ -3359,19 +2436,19 @@
 37.2634  msgstr ""
 37.2635  
 37.2636  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2637 -#: ../en/ch02-tour-basic.xml:668
 37.2638 +#: ../en/ch01-tour-basic.xml:669
 37.2639  msgid ""
 37.2640  "We refer to the newest revision in the repository as the tip revision, or "
 37.2641  "simply the tip."
 37.2642  msgstr ""
 37.2643  
 37.2644  #. type: Content of: <book><chapter><sect1><title>
 37.2645 -#: ../en/ch02-tour-basic.xml:675
 37.2646 +#: ../en/ch01-tour-basic.xml:676
 37.2647  msgid "Sharing changes"
 37.2648  msgstr "共享修改"
 37.2649  
 37.2650  #. type: Content of: <book><chapter><sect1><para>
 37.2651 -#: ../en/ch02-tour-basic.xml:677
 37.2652 +#: ../en/ch01-tour-basic.xml:678
 37.2653  msgid ""
 37.2654  "We mentioned earlier that repositories in Mercurial are self-contained.  This "
 37.2655  "means that the changeset we just created exists only in our <filename class="
 37.2656 @@ -3380,12 +2457,12 @@
 37.2657  msgstr ""
 37.2658  
 37.2659  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.2660 -#: ../en/ch02-tour-basic.xml:685
 37.2661 +#: ../en/ch01-tour-basic.xml:686
 37.2662  msgid "Pulling changes from another repository"
 37.2663  msgstr "从其它版本库取得修改"
 37.2664  
 37.2665  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2666 -#: ../en/ch02-tour-basic.xml:686
 37.2667 +#: ../en/ch01-tour-basic.xml:687
 37.2668  msgid ""
 37.2669  "To get started, let's clone our original <filename class=\"directory\">hello</"
 37.2670  "filename> repository, which does not contain the change we just committed.  "
 37.2671 @@ -3394,7 +2471,7 @@
 37.2672  msgstr ""
 37.2673  
 37.2674  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2675 -#: ../en/ch02-tour-basic.xml:694
 37.2676 +#: ../en/ch01-tour-basic.xml:695
 37.2677  msgid ""
 37.2678  "We'll use the <command role=\"hg-cmd\">hg pull</command> command to bring "
 37.2679  "changes from <filename class=\"directory\">my-hello</filename> into <filename "
 37.2680 @@ -3407,7 +2484,7 @@
 37.2681  msgstr ""
 37.2682  
 37.2683  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2684 -#: ../en/ch02-tour-basic.xml:707
 37.2685 +#: ../en/ch01-tour-basic.xml:708
 37.2686  msgid ""
 37.2687  "(Of course, someone could cause more changesets to appear in the repository "
 37.2688  "that we ran <command role=\"hg-cmd\">hg incoming</command> in, before we get "
 37.2689 @@ -3416,7 +2493,7 @@
 37.2690  msgstr ""
 37.2691  
 37.2692  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2693 -#: ../en/ch02-tour-basic.xml:714
 37.2694 +#: ../en/ch01-tour-basic.xml:715
 37.2695  msgid ""
 37.2696  "Bringing changes into a repository is a simple matter of running the <command "
 37.2697  "role=\"hg-cmd\">hg pull</command> command, and telling it which repository to "
 37.2698 @@ -3424,7 +2501,7 @@
 37.2699  msgstr ""
 37.2700  
 37.2701  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2702 -#: ../en/ch02-tour-basic.xml:721
 37.2703 +#: ../en/ch01-tour-basic.xml:722
 37.2704  msgid ""
 37.2705  "As you can see from the before-and-after output of <command role=\"hg-cmd"
 37.2706  "\">hg tip</command>, we have successfully pulled changes into our "
 37.2707 @@ -3433,12 +2510,12 @@
 37.2708  msgstr ""
 37.2709  
 37.2710  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.2711 -#: ../en/ch02-tour-basic.xml:729
 37.2712 +#: ../en/ch01-tour-basic.xml:730
 37.2713  msgid "Updating the working directory"
 37.2714  msgstr "更新工作目录"
 37.2715  
 37.2716  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2717 -#: ../en/ch02-tour-basic.xml:731
 37.2718 +#: ../en/ch01-tour-basic.xml:732
 37.2719  msgid ""
 37.2720  "We have so far glossed over the relationship between a repository and its "
 37.2721  "working directory.  The <command role=\"hg-cmd\">hg pull</command> command "
 37.2722 @@ -3450,7 +2527,7 @@
 37.2723  msgstr ""
 37.2724  
 37.2725  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2726 -#: ../en/ch02-tour-basic.xml:743
 37.2727 +#: ../en/ch01-tour-basic.xml:744
 37.2728  msgid ""
 37.2729  "It might seem a bit strange that <command role=\"hg-cmd\">hg pull</command> "
 37.2730  "doesn't update the working directory automatically.  There's actually a good "
 37.2731 @@ -3464,7 +2541,7 @@
 37.2732  msgstr ""
 37.2733  
 37.2734  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2735 -#: ../en/ch02-tour-basic.xml:754
 37.2736 +#: ../en/ch01-tour-basic.xml:755
 37.2737  msgid ""
 37.2738  "However, since pull-then-update is such a common thing to do, Mercurial lets "
 37.2739  "you combine the two by passing the <option role=\"hg-opt-pull\">-u</option> "
 37.2740 @@ -3472,7 +2549,7 @@
 37.2741  msgstr ""
 37.2742  
 37.2743  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2744 -#: ../en/ch02-tour-basic.xml:759
 37.2745 +#: ../en/ch01-tour-basic.xml:760
 37.2746  msgid ""
 37.2747  "If you look back at the output of <command role=\"hg-cmd\">hg pull</command> "
 37.2748  "in section <xref linkend=\"sec.tour.pull\"/> when we ran it without <option "
 37.2749 @@ -3482,14 +2559,14 @@
 37.2750  msgstr ""
 37.2751  
 37.2752  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2753 -#: ../en/ch02-tour-basic.xml:768
 37.2754 +#: ../en/ch01-tour-basic.xml:769
 37.2755  msgid ""
 37.2756  "To find out what revision the working directory is at, use the <command role="
 37.2757  "\"hg-cmd\">hg parents</command> command."
 37.2758  msgstr ""
 37.2759  
 37.2760  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2761 -#: ../en/ch02-tour-basic.xml:774
 37.2762 +#: ../en/ch01-tour-basic.xml:775
 37.2763  msgid ""
 37.2764  "If you look back at figure <xref endterm=\"fig.tour-basic.history.caption\" "
 37.2765  "linkend=\"fig.tour-basic.history\"/>, you'll see arrows connecting each "
 37.2766 @@ -3500,7 +2577,7 @@
 37.2767  msgstr ""
 37.2768  
 37.2769  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2770 -#: ../en/ch02-tour-basic.xml:784
 37.2771 +#: ../en/ch01-tour-basic.xml:785
 37.2772  msgid ""
 37.2773  "To update the working directory to a particular revision, give a revision "
 37.2774  "number or changeset ID to the <command role=\"hg-cmd\">hg update</command> "
 37.2775 @@ -3508,7 +2585,7 @@
 37.2776  msgstr ""
 37.2777  
 37.2778  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2779 -#: ../en/ch02-tour-basic.xml:791
 37.2780 +#: ../en/ch01-tour-basic.xml:792
 37.2781  msgid ""
 37.2782  "If you omit an explicit revision, <command role=\"hg-cmd\">hg update</"
 37.2783  "command> will update to the tip revision, as shown by the second call to "
 37.2784 @@ -3516,12 +2593,12 @@
 37.2785  msgstr ""
 37.2786  
 37.2787  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.2788 -#: ../en/ch02-tour-basic.xml:799
 37.2789 +#: ../en/ch01-tour-basic.xml:800
 37.2790  msgid "Pushing changes to another repository"
 37.2791  msgstr "发布修改到其它版本库"
 37.2792  
 37.2793  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2794 -#: ../en/ch02-tour-basic.xml:801
 37.2795 +#: ../en/ch01-tour-basic.xml:802
 37.2796  msgid ""
 37.2797  "Mercurial lets us push changes to another repository, from the repository "
 37.2798  "we're currently visiting.  As with the example of <command role=\"hg-cmd\">hg "
 37.2799 @@ -3530,21 +2607,21 @@
 37.2800  msgstr ""
 37.2801  
 37.2802  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2803 -#: ../en/ch02-tour-basic.xml:809
 37.2804 +#: ../en/ch01-tour-basic.xml:810
 37.2805  msgid ""
 37.2806  "The <command role=\"hg-cmd\">hg outgoing</command> command tells us what "
 37.2807  "changes would be pushed into another repository."
 37.2808  msgstr ""
 37.2809  
 37.2810  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2811 -#: ../en/ch02-tour-basic.xml:815
 37.2812 +#: ../en/ch01-tour-basic.xml:816
 37.2813  msgid ""
 37.2814  "And the <command role=\"hg-cmd\">hg push</command> command does the actual "
 37.2815  "push."
 37.2816  msgstr ""
 37.2817  
 37.2818  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2819 -#: ../en/ch02-tour-basic.xml:821
 37.2820 +#: ../en/ch01-tour-basic.xml:822
 37.2821  msgid ""
 37.2822  "As with <command role=\"hg-cmd\">hg pull</command>, the <command role=\"hg-cmd"
 37.2823  "\">hg push</command> command does not update the working directory in the "
 37.2824 @@ -3555,19 +2632,19 @@
 37.2825  msgstr ""
 37.2826  
 37.2827  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2828 -#: ../en/ch02-tour-basic.xml:830
 37.2829 +#: ../en/ch01-tour-basic.xml:831
 37.2830  msgid ""
 37.2831  "What happens if we try to pull or push changes and the receiving repository "
 37.2832  "already has those changes? Nothing too exciting."
 37.2833  msgstr ""
 37.2834  
 37.2835  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.2836 -#: ../en/ch02-tour-basic.xml:837
 37.2837 +#: ../en/ch01-tour-basic.xml:838
 37.2838  msgid "Sharing changes over a network"
 37.2839  msgstr "通过网络共享修改"
 37.2840  
 37.2841  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2842 -#: ../en/ch02-tour-basic.xml:839
 37.2843 +#: ../en/ch01-tour-basic.xml:840
 37.2844  msgid ""
 37.2845  "The commands we have covered in the previous few sections are not limited to "
 37.2846  "working with local repositories.  Each works in exactly the same fashion over "
 37.2847 @@ -3575,7 +2652,7 @@
 37.2848  msgstr ""
 37.2849  
 37.2850  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2851 -#: ../en/ch02-tour-basic.xml:847
 37.2852 +#: ../en/ch01-tour-basic.xml:848
 37.2853  msgid ""
 37.2854  "In this example, we can see what changes we could push to the remote "
 37.2855  "repository, but the repository is understandably not set up to let anonymous "
 37.2856 @@ -3583,12 +2660,12 @@
 37.2857  msgstr ""
 37.2858  
 37.2859  #. type: Content of: <book><chapter><title>
 37.2860 -#: ../en/ch03-tour-merge.xml:5
 37.2861 +#: ../en/ch02-tour-merge.xml:5
 37.2862  msgid "A tour of Mercurial: merging work"
 37.2863  msgstr "Mercurial 教程: 合并工作"
 37.2864  
 37.2865  #. type: Content of: <book><chapter><para>
 37.2866 -#: ../en/ch03-tour-merge.xml:7
 37.2867 +#: ../en/ch02-tour-merge.xml:7
 37.2868  msgid ""
 37.2869  "We've now covered cloning a repository, making changes in a repository, and "
 37.2870  "pulling or pushing changes from one repository into another.  Our next step "
 37.2871 @@ -3596,19 +2673,19 @@
 37.2872  msgstr ""
 37.2873  
 37.2874  #. type: Content of: <book><chapter><sect1><title>
 37.2875 -#: ../en/ch03-tour-merge.xml:13
 37.2876 +#: ../en/ch02-tour-merge.xml:13
 37.2877  msgid "Merging streams of work"
 37.2878  msgstr "合并的流程"
 37.2879  
 37.2880  #. type: Content of: <book><chapter><sect1><para>
 37.2881 -#: ../en/ch03-tour-merge.xml:15
 37.2882 +#: ../en/ch02-tour-merge.xml:15
 37.2883  msgid ""
 37.2884  "Merging is a fundamental part of working with a distributed revision control "
 37.2885  "tool."
 37.2886  msgstr ""
 37.2887  
 37.2888  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.2889 -#: ../en/ch03-tour-merge.xml:18
 37.2890 +#: ../en/ch02-tour-merge.xml:18
 37.2891  msgid ""
 37.2892  "Alice and Bob each have a personal copy of a repository for a project they're "
 37.2893  "collaborating on.  Alice fixes a bug in her repository; Bob adds a new "
 37.2894 @@ -3617,7 +2694,7 @@
 37.2895  msgstr ""
 37.2896  
 37.2897  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.2898 -#: ../en/ch03-tour-merge.xml:24
 37.2899 +#: ../en/ch02-tour-merge.xml:24
 37.2900  msgid ""
 37.2901  "I frequently work on several different tasks for a single project at once, "
 37.2902  "each safely isolated in its own repository. Working this way means that I "
 37.2903 @@ -3625,7 +2702,7 @@
 37.2904  msgstr ""
 37.2905  
 37.2906  #. type: Content of: <book><chapter><sect1><para>
 37.2907 -#: ../en/ch03-tour-merge.xml:30
 37.2908 +#: ../en/ch02-tour-merge.xml:30
 37.2909  msgid ""
 37.2910  "Because merging is such a common thing to need to do, Mercurial makes it "
 37.2911  "easy.  Let's walk through the process.  We'll begin by cloning yet another "
 37.2912 @@ -3633,7 +2710,7 @@
 37.2913  msgstr ""
 37.2914  
 37.2915  #. type: Content of: <book><chapter><sect1><para>
 37.2916 -#: ../en/ch03-tour-merge.xml:37
 37.2917 +#: ../en/ch02-tour-merge.xml:37
 37.2918  msgid ""
 37.2919  "We should now have two copies of <filename>hello.c</filename> with different "
 37.2920  "contents.  The histories of the two repositories have also diverged, as "
 37.2921 @@ -3642,14 +2719,14 @@
 37.2922  msgstr ""
 37.2923  
 37.2924  #. type: Content of: <book><chapter><sect1><informalfigure><mediaobject>
 37.2925 -#: ../en/ch03-tour-merge.xml:47
 37.2926 +#: ../en/ch02-tour-merge.xml:47
 37.2927  msgid ""
 37.2928  "<imageobject><imagedata fileref=\"images/tour-merge-sep-repos.png\"/></"
 37.2929  "imageobject>"
 37.2930  msgstr ""
 37.2931  
 37.2932  #. type: Content of: <book><chapter><sect1><informalfigure><mediaobject><caption><para>
 37.2933 -#: ../en/ch03-tour-merge.xml:49
 37.2934 +#: ../en/ch02-tour-merge.xml:49
 37.2935  msgid ""
 37.2936  "Divergent recent histories of the <filename class=\"directory\">my-hello</"
 37.2937  "filename> and <filename class=\"directory\">my-new-hello</filename> "
 37.2938 @@ -3657,7 +2734,7 @@
 37.2939  msgstr ""
 37.2940  
 37.2941  #. type: Content of: <book><chapter><sect1><para>
 37.2942 -#: ../en/ch03-tour-merge.xml:57
 37.2943 +#: ../en/ch02-tour-merge.xml:57
 37.2944  msgid ""
 37.2945  "We already know that pulling changes from our <filename class=\"directory"
 37.2946  "\">my-hello</filename> repository will have no effect on the working "
 37.2947 @@ -3665,19 +2742,19 @@
 37.2948  msgstr ""
 37.2949  
 37.2950  #. type: Content of: <book><chapter><sect1><para>
 37.2951 -#: ../en/ch03-tour-merge.xml:63
 37.2952 +#: ../en/ch02-tour-merge.xml:63
 37.2953  msgid ""
 37.2954  "However, the <command role=\"hg-cmd\">hg pull</command> command says "
 37.2955  "something about <quote>heads</quote>."
 37.2956  msgstr ""
 37.2957  
 37.2958  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.2959 -#: ../en/ch03-tour-merge.xml:67
 37.2960 +#: ../en/ch02-tour-merge.xml:67
 37.2961  msgid "Head changesets"
 37.2962  msgstr "顶点改变集"
 37.2963  
 37.2964  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2965 -#: ../en/ch03-tour-merge.xml:69
 37.2966 +#: ../en/ch02-tour-merge.xml:69
 37.2967  msgid ""
 37.2968  "A head is a change that has no descendants, or children, as they're also "
 37.2969  "known.  The tip revision is thus a head, because the newest revision in a "
 37.2970 @@ -3686,20 +2763,20 @@
 37.2971  msgstr ""
 37.2972  
 37.2973  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
 37.2974 -#: ../en/ch03-tour-merge.xml:77
 37.2975 +#: ../en/ch02-tour-merge.xml:77
 37.2976  msgid ""
 37.2977  "<imageobject><imagedata fileref=\"images/tour-merge-pull.png\"/></imageobject>"
 37.2978  msgstr ""
 37.2979  
 37.2980  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
 37.2981 -#: ../en/ch03-tour-merge.xml:79
 37.2982 +#: ../en/ch02-tour-merge.xml:79
 37.2983  msgid ""
 37.2984  "Repository contents after pulling from <filename class=\"directory\">my-"
 37.2985  "hello</filename> into <filename class=\"directory\">my-new-hello</filename>"
 37.2986  msgstr ""
 37.2987  
 37.2988  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.2989 -#: ../en/ch03-tour-merge.xml:85
 37.2990 +#: ../en/ch02-tour-merge.xml:85
 37.2991  msgid ""
 37.2992  "In figure <xref endterm=\"fig.tour-merge.pull.caption\" linkend=\"fig.tour-"
 37.2993  "merge.pull\"/>, you can see the effect of the pull from <filename class="
 37.2994 @@ -3716,19 +2793,19 @@
 37.2995  msgstr ""
 37.2996  
 37.2997  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.2998 -#: ../en/ch03-tour-merge.xml:106
 37.2999 +#: ../en/ch02-tour-merge.xml:106
 37.3000  msgid "Performing the merge"
 37.3001  msgstr "执行合并"
 37.3002  
 37.3003  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3004 -#: ../en/ch03-tour-merge.xml:108
 37.3005 +#: ../en/ch02-tour-merge.xml:108
 37.3006  msgid ""
 37.3007  "What happens if we try to use the normal <command role=\"hg-cmd\">hg update</"
 37.3008  "command> command to update to the new tip?"
 37.3009  msgstr ""
 37.3010  
 37.3011  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3012 -#: ../en/ch03-tour-merge.xml:114
 37.3013 +#: ../en/ch02-tour-merge.xml:114
 37.3014  msgid ""
 37.3015  "Mercurial is telling us that the <command role=\"hg-cmd\">hg update</command> "
 37.3016  "command won't do a merge; it won't update the working directory when it "
 37.3017 @@ -3738,19 +2815,19 @@
 37.3018  msgstr ""
 37.3019  
 37.3020  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
 37.3021 -#: ../en/ch03-tour-merge.xml:125
 37.3022 +#: ../en/ch02-tour-merge.xml:125
 37.3023  msgid ""
 37.3024  "<imageobject><imagedata fileref=\"images/tour-merge-merge.png\"/></"
 37.3025  "imageobject>"
 37.3026  msgstr ""
 37.3027  
 37.3028  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
 37.3029 -#: ../en/ch03-tour-merge.xml:127
 37.3030 +#: ../en/ch02-tour-merge.xml:127
 37.3031  msgid "Working directory and repository during merge, and following commit"
 37.3032  msgstr ""
 37.3033  
 37.3034  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3035 -#: ../en/ch03-tour-merge.xml:132
 37.3036 +#: ../en/ch02-tour-merge.xml:132
 37.3037  msgid ""
 37.3038  "This updates the working directory so that it contains changes from "
 37.3039  "<emphasis>both</emphasis> heads, which is reflected in both the output of "
 37.3040 @@ -3759,12 +2836,12 @@
 37.3041  msgstr ""
 37.3042  
 37.3043  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.3044 -#: ../en/ch03-tour-merge.xml:142
 37.3045 +#: ../en/ch02-tour-merge.xml:142
 37.3046  msgid "Committing the results of the merge"
 37.3047  msgstr "提交合并结果"
 37.3048  
 37.3049  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3050 -#: ../en/ch03-tour-merge.xml:144
 37.3051 +#: ../en/ch02-tour-merge.xml:144
 37.3052  msgid ""
 37.3053  "Whenever we've done a merge, <command role=\"hg-cmd\">hg parents</command> "
 37.3054  "will display two parents until we <command role=\"hg-cmd\">hg commit</"
 37.3055 @@ -3772,7 +2849,7 @@
 37.3056  msgstr ""
 37.3057  
 37.3058  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3059 -#: ../en/ch03-tour-merge.xml:151
 37.3060 +#: ../en/ch02-tour-merge.xml:151
 37.3061  msgid ""
 37.3062  "We now have a new tip revision; notice that it has <emphasis>both</emphasis> "
 37.3063  "of our former heads as its parents.  These are the same revisions that were "
 37.3064 @@ -3780,7 +2857,7 @@
 37.3065  msgstr ""
 37.3066  
 37.3067  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3068 -#: ../en/ch03-tour-merge.xml:158
 37.3069 +#: ../en/ch02-tour-merge.xml:158
 37.3070  msgid ""
 37.3071  "In figure <xref endterm=\"fig.tour-merge.merge.caption\" linkend=\"fig.tour-"
 37.3072  "merge.merge\"/>, you can see a representation of what happens to the working "
 37.3073 @@ -3790,12 +2867,12 @@
 37.3074  msgstr ""
 37.3075  
 37.3076  #. type: Content of: <book><chapter><sect1><title>
 37.3077 -#: ../en/ch03-tour-merge.xml:169
 37.3078 +#: ../en/ch02-tour-merge.xml:169
 37.3079  msgid "Merging conflicting changes"
 37.3080  msgstr "合并有冲突的改变"
 37.3081  
 37.3082  #. type: Content of: <book><chapter><sect1><para>
 37.3083 -#: ../en/ch03-tour-merge.xml:171
 37.3084 +#: ../en/ch02-tour-merge.xml:171
 37.3085  msgid ""
 37.3086  "Most merges are simple affairs, but sometimes you'll find yourself merging "
 37.3087  "changes where each modifies the same portions of the same files.  Unless both "
 37.3088 @@ -3805,19 +2882,19 @@
 37.3089  msgstr ""
 37.3090  
 37.3091  #. type: Content of: <book><chapter><sect1><informalfigure><mediaobject>
 37.3092 -#: ../en/ch03-tour-merge.xml:180
 37.3093 +#: ../en/ch02-tour-merge.xml:180
 37.3094  msgid ""
 37.3095  "<imageobject><imagedata fileref=\"images/tour-merge-conflict.png\"/> </"
 37.3096  "imageobject>"
 37.3097  msgstr ""
 37.3098  
 37.3099  #. type: Content of: <book><chapter><sect1><informalfigure><mediaobject><caption><para>
 37.3100 -#: ../en/ch03-tour-merge.xml:183
 37.3101 +#: ../en/ch02-tour-merge.xml:183
 37.3102  msgid "Conflicting changes to a document"
 37.3103  msgstr ""
 37.3104  
 37.3105  #. type: Content of: <book><chapter><sect1><para>
 37.3106 -#: ../en/ch03-tour-merge.xml:188
 37.3107 +#: ../en/ch02-tour-merge.xml:188
 37.3108  msgid ""
 37.3109  "Figure <xref endterm=\"fig.tour-merge.conflict.caption\" linkend=\"fig.tour-"
 37.3110  "merge.conflict\"/> illustrates an instance of two conflicting changes to a "
 37.3111 @@ -3828,7 +2905,7 @@
 37.3112  msgstr ""
 37.3113  
 37.3114  #. type: Content of: <book><chapter><sect1><para>
 37.3115 -#: ../en/ch03-tour-merge.xml:196
 37.3116 +#: ../en/ch02-tour-merge.xml:196
 37.3117  msgid ""
 37.3118  "Mercurial doesn't have a built-in facility for handling conflicts. Instead, "
 37.3119  "it runs an external program called <command>hgmerge</command>.  This is a "
 37.3120 @@ -3841,7 +2918,7 @@
 37.3121  msgstr ""
 37.3122  
 37.3123  #. type: Content of: <book><chapter><sect1><para>
 37.3124 -#: ../en/ch03-tour-merge.xml:207
 37.3125 +#: ../en/ch02-tour-merge.xml:207
 37.3126  msgid ""
 37.3127  "It's also possible to get Mercurial to run another program or script instead "
 37.3128  "of <command>hgmerge</command>, by setting the <envar>HGMERGE</envar> "
 37.3129 @@ -3849,12 +2926,12 @@
 37.3130  msgstr ""
 37.3131  
 37.3132  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.3133 -#: ../en/ch03-tour-merge.xml:213
 37.3134 +#: ../en/ch02-tour-merge.xml:213
 37.3135  msgid "Using a graphical merge tool"
 37.3136  msgstr "使用图形合并工具"
 37.3137  
 37.3138  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3139 -#: ../en/ch03-tour-merge.xml:215
 37.3140 +#: ../en/ch02-tour-merge.xml:215
 37.3141  msgid ""
 37.3142  "My preferred graphical merge tool is <command>kdiff3</command>, which I'll "
 37.3143  "use to describe the features that are common to graphical file merging "
 37.3144 @@ -3867,7 +2944,7 @@
 37.3145  msgstr ""
 37.3146  
 37.3147  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.3148 -#: ../en/ch03-tour-merge.xml:226
 37.3149 +#: ../en/ch02-tour-merge.xml:226
 37.3150  msgid ""
 37.3151  "At the left is the <emphasis>base</emphasis> version of the file, i.e. the "
 37.3152  "most recent version from which the two versions we're trying to merge are "
 37.3153 @@ -3875,21 +2952,21 @@
 37.3154  msgstr ""
 37.3155  
 37.3156  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.3157 -#: ../en/ch03-tour-merge.xml:231
 37.3158 +#: ../en/ch02-tour-merge.xml:231
 37.3159  msgid ""
 37.3160  "In the middle is <quote>our</quote> version of the file, with the contents "
 37.3161  "that we modified."
 37.3162  msgstr ""
 37.3163  
 37.3164  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.3165 -#: ../en/ch03-tour-merge.xml:234
 37.3166 +#: ../en/ch02-tour-merge.xml:234
 37.3167  msgid ""
 37.3168  "On the right is <quote>their</quote> version of the file, the one that from "
 37.3169  "the changeset that we're trying to merge with."
 37.3170  msgstr ""
 37.3171  
 37.3172  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3173 -#: ../en/ch03-tour-merge.xml:238
 37.3174 +#: ../en/ch02-tour-merge.xml:238
 37.3175  msgid ""
 37.3176  "In the pane below these is the current <emphasis>result</emphasis> of the "
 37.3177  "merge. Our task is to replace all of the red text, which indicates unresolved "
 37.3178 @@ -3898,7 +2975,7 @@
 37.3179  msgstr ""
 37.3180  
 37.3181  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3182 -#: ../en/ch03-tour-merge.xml:245
 37.3183 +#: ../en/ch02-tour-merge.xml:245
 37.3184  msgid ""
 37.3185  "All four of these panes are <emphasis>locked together</emphasis>; if we "
 37.3186  "scroll vertically or horizontally in any of them, the others are updated to "
 37.3187 @@ -3906,19 +2983,19 @@
 37.3188  msgstr ""
 37.3189  
 37.3190  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
 37.3191 -#: ../en/ch03-tour-merge.xml:252
 37.3192 +#: ../en/ch02-tour-merge.xml:252
 37.3193  msgid ""
 37.3194  "<imageobject><imagedata width=\"100%\" fileref=\"images/kdiff3.png\"/> </"
 37.3195  "imageobject>"
 37.3196  msgstr ""
 37.3197  
 37.3198  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
 37.3199 -#: ../en/ch03-tour-merge.xml:255
 37.3200 +#: ../en/ch02-tour-merge.xml:255
 37.3201  msgid "Using <command>kdiff3</command> to merge versions of a file"
 37.3202  msgstr ""
 37.3203  
 37.3204  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3205 -#: ../en/ch03-tour-merge.xml:261
 37.3206 +#: ../en/ch02-tour-merge.xml:261
 37.3207  msgid ""
 37.3208  "For each conflicting portion of the file, we can choose to resolve the "
 37.3209  "conflict using some combination of text from the base version, ours, or "
 37.3210 @@ -3927,7 +3004,7 @@
 37.3211  msgstr ""
 37.3212  
 37.3213  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3214 -#: ../en/ch03-tour-merge.xml:267
 37.3215 +#: ../en/ch02-tour-merge.xml:267
 37.3216  msgid ""
 37.3217  "There are <emphasis>many</emphasis> file merging tools available, too many to "
 37.3218  "cover here.  They vary in which platforms they are available for, and in "
 37.3219 @@ -3937,12 +3014,12 @@
 37.3220  msgstr ""
 37.3221  
 37.3222  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.3223 -#: ../en/ch03-tour-merge.xml:276
 37.3224 +#: ../en/ch02-tour-merge.xml:276
 37.3225  msgid "A worked example"
 37.3226  msgstr "合并实例"
 37.3227  
 37.3228  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3229 -#: ../en/ch03-tour-merge.xml:278
 37.3230 +#: ../en/ch02-tour-merge.xml:278
 37.3231  msgid ""
 37.3232  "In this example, we will reproduce the file modification history of figure "
 37.3233  "<xref endterm=\"fig.tour-merge.conflict.caption\" linkend=\"fig.tour-merge."
 37.3234 @@ -3951,12 +3028,12 @@
 37.3235  msgstr ""
 37.3236  
 37.3237  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3238 -#: ../en/ch03-tour-merge.xml:286
 37.3239 +#: ../en/ch02-tour-merge.xml:286
 37.3240  msgid "We'll clone the repository and make a change to the file."
 37.3241  msgstr ""
 37.3242  
 37.3243  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3244 -#: ../en/ch03-tour-merge.xml:291
 37.3245 +#: ../en/ch02-tour-merge.xml:291
 37.3246  msgid ""
 37.3247  "And another clone, to simulate someone else making a change to the file. "
 37.3248  "(This hints at the idea that it's not all that unusual to merge with yourself "
 37.3249 @@ -3965,14 +3042,14 @@
 37.3250  msgstr ""
 37.3251  
 37.3252  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3253 -#: ../en/ch03-tour-merge.xml:299
 37.3254 +#: ../en/ch02-tour-merge.xml:299
 37.3255  msgid ""
 37.3256  "Having created two different versions of the file, we'll set up an "
 37.3257  "environment suitable for running our merge."
 37.3258  msgstr ""
 37.3259  
 37.3260  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3261 -#: ../en/ch03-tour-merge.xml:305
 37.3262 +#: ../en/ch02-tour-merge.xml:305
 37.3263  msgid ""
 37.3264  "In this example, I won't use Mercurial's normal <command>hgmerge</command> "
 37.3265  "program to do the merge, because it would drop my nice automated example-"
 37.3266 @@ -3984,12 +3061,12 @@
 37.3267  msgstr ""
 37.3268  
 37.3269  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3270 -#: ../en/ch03-tour-merge.xml:315
 37.3271 +#: ../en/ch02-tour-merge.xml:315
 37.3272  msgid "<emphasis role=\"bold\">XXX FIX THIS EXAMPLE.</emphasis>"
 37.3273  msgstr ""
 37.3274  
 37.3275  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3276 -#: ../en/ch03-tour-merge.xml:320
 37.3277 +#: ../en/ch02-tour-merge.xml:320
 37.3278  msgid ""
 37.3279  "Because <command>merge</command> can't resolve the conflicting changes, it "
 37.3280  "leaves <emphasis>merge markers</emphasis> inside the file that has conflicts, "
 37.3281 @@ -3998,7 +3075,7 @@
 37.3282  msgstr ""
 37.3283  
 37.3284  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3285 -#: ../en/ch03-tour-merge.xml:326
 37.3286 +#: ../en/ch02-tour-merge.xml:326
 37.3287  msgid ""
 37.3288  "Mercurial can tell from the way <command>merge</command> exits that it wasn't "
 37.3289  "able to merge successfully, so it tells us what commands we'll need to run if "
 37.3290 @@ -4008,7 +3085,7 @@
 37.3291  msgstr ""
 37.3292  
 37.3293  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3294 -#: ../en/ch03-tour-merge.xml:333
 37.3295 +#: ../en/ch02-tour-merge.xml:333
 37.3296  msgid ""
 37.3297  "If automatic or manual merges fail, there's nothing to prevent us from "
 37.3298  "<quote>fixing up</quote> the affected files ourselves, and committing the "
 37.3299 @@ -4016,19 +3093,19 @@
 37.3300  msgstr ""
 37.3301  
 37.3302  #. type: Content of: <book><chapter><sect1><title>
 37.3303 -#: ../en/ch03-tour-merge.xml:342
 37.3304 +#: ../en/ch02-tour-merge.xml:342
 37.3305  msgid "Simplifying the pull-merge-commit sequence"
 37.3306  msgstr "简化拉-合并-提交程序"
 37.3307  
 37.3308  #. type: Content of: <book><chapter><sect1><para>
 37.3309 -#: ../en/ch03-tour-merge.xml:344
 37.3310 +#: ../en/ch02-tour-merge.xml:344
 37.3311  msgid ""
 37.3312  "The process of merging changes as outlined above is straightforward, but "
 37.3313  "requires running three commands in sequence."
 37.3314  msgstr ""
 37.3315  
 37.3316  #. type: Content of: <book><chapter><sect1><para>
 37.3317 -#: ../en/ch03-tour-merge.xml:350
 37.3318 +#: ../en/ch02-tour-merge.xml:350
 37.3319  msgid ""
 37.3320  "In the case of the final commit, you also need to enter a commit message, "
 37.3321  "which is almost always going to be a piece of uninteresting "
 37.3322 @@ -4036,7 +3113,7 @@
 37.3323  msgstr ""
 37.3324  
 37.3325  #. type: Content of: <book><chapter><sect1><para>
 37.3326 -#: ../en/ch03-tour-merge.xml:354
 37.3327 +#: ../en/ch02-tour-merge.xml:354
 37.3328  msgid ""
 37.3329  "It would be nice to reduce the number of steps needed, if this were "
 37.3330  "possible.  Indeed, Mercurial is distributed with an extension called <literal "
 37.3331 @@ -4044,7 +3121,7 @@
 37.3332  msgstr ""
 37.3333  
 37.3334  #. type: Content of: <book><chapter><sect1><para>
 37.3335 -#: ../en/ch03-tour-merge.xml:359
 37.3336 +#: ../en/ch02-tour-merge.xml:359
 37.3337  msgid ""
 37.3338  "Mercurial provides a flexible extension mechanism that lets people extend its "
 37.3339  "functionality, while keeping the core of Mercurial small and easy to deal "
 37.3340 @@ -4054,7 +3131,7 @@
 37.3341  msgstr ""
 37.3342  
 37.3343  #. type: Content of: <book><chapter><sect1><para>
 37.3344 -#: ../en/ch03-tour-merge.xml:366
 37.3345 +#: ../en/ch02-tour-merge.xml:366
 37.3346  msgid ""
 37.3347  "The <literal role=\"hg-ext\">fetch</literal> extension adds a new command "
 37.3348  "called, not surprisingly, <command role=\"hg-cmd\">hg fetch</command>.  This "
 37.3349 @@ -4068,7 +3145,7 @@
 37.3350  msgstr ""
 37.3351  
 37.3352  #. type: Content of: <book><chapter><sect1><para>
 37.3353 -#: ../en/ch03-tour-merge.xml:379
 37.3354 +#: ../en/ch02-tour-merge.xml:379
 37.3355  msgid ""
 37.3356  "Enabling the <literal role=\"hg-ext\">fetch</literal> extension is easy.  "
 37.3357  "Edit your <filename role=\"special\">.hgrc</filename>, and either go to the "
 37.3358 @@ -4078,7 +3155,7 @@
 37.3359  msgstr ""
 37.3360  
 37.3361  #. type: Content of: <book><chapter><sect1><para>
 37.3362 -#: ../en/ch03-tour-merge.xml:389
 37.3363 +#: ../en/ch02-tour-merge.xml:388
 37.3364  msgid ""
 37.3365  "(Normally, on the right-hand side of the <quote><literal>=</literal></quote> "
 37.3366  "would appear the location of the extension, but since the <literal role=\"hg-"
 37.3367 @@ -4087,12 +3164,12 @@
 37.3368  msgstr ""
 37.3369  
 37.3370  #. type: Content of: <book><chapter><title>
 37.3371 -#: ../en/ch04-concepts.xml:5
 37.3372 +#: ../en/ch03-concepts.xml:5
 37.3373  msgid "Behind the scenes"
 37.3374  msgstr "Mercurial 内幕"
 37.3375  
 37.3376  #. type: Content of: <book><chapter><para>
 37.3377 -#: ../en/ch04-concepts.xml:7
 37.3378 +#: ../en/ch03-concepts.xml:7
 37.3379  msgid ""
 37.3380  "Unlike many revision control systems, the concepts upon which Mercurial is "
 37.3381  "built are simple enough that it's easy to understand how the software really "
 37.3382 @@ -4101,7 +3178,7 @@
 37.3383  msgstr ""
 37.3384  
 37.3385  #. type: Content of: <book><chapter><para>
 37.3386 -#: ../en/ch04-concepts.xml:13
 37.3387 +#: ../en/ch03-concepts.xml:13
 37.3388  msgid ""
 37.3389  "This understanding gives me confidence that Mercurial has been carefully "
 37.3390  "designed to be both <emphasis>safe</emphasis> and <emphasis>efficient</"
 37.3391 @@ -4111,7 +3188,7 @@
 37.3392  msgstr ""
 37.3393  
 37.3394  #. type: Content of: <book><chapter><para>
 37.3395 -#: ../en/ch04-concepts.xml:20
 37.3396 +#: ../en/ch03-concepts.xml:20
 37.3397  msgid ""
 37.3398  "In this chapter, we'll initially cover the core concepts behind Mercurial's "
 37.3399  "design, then continue to discuss some of the interesting details of its "
 37.3400 @@ -4119,17 +3196,17 @@
 37.3401  msgstr ""
 37.3402  
 37.3403  #. type: Content of: <book><chapter><sect1><title>
 37.3404 -#: ../en/ch04-concepts.xml:25
 37.3405 +#: ../en/ch03-concepts.xml:25
 37.3406  msgid "Mercurial's historical record"
 37.3407  msgstr "Mercurial 的历史记录"
 37.3408  
 37.3409  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.3410 -#: ../en/ch04-concepts.xml:28
 37.3411 +#: ../en/ch03-concepts.xml:28
 37.3412  msgid "Tracking the history of a single file"
 37.3413  msgstr "跟踪单一文件的历史"
 37.3414  
 37.3415  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3416 -#: ../en/ch04-concepts.xml:30
 37.3417 +#: ../en/ch03-concepts.xml:30
 37.3418  msgid ""
 37.3419  "When Mercurial tracks modifications to a file, it stores the history of that "
 37.3420  "file in a metadata object called a <emphasis>filelog</emphasis>.  Each entry "
 37.3421 @@ -4141,7 +3218,7 @@
 37.3422  msgstr ""
 37.3423  
 37.3424  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3425 -#: ../en/ch04-concepts.xml:41
 37.3426 +#: ../en/ch03-concepts.xml:41
 37.3427  msgid ""
 37.3428  "A file that is large, or has a lot of history, has its filelog stored in "
 37.3429  "separate data (<quote><literal>.d</literal></quote> suffix) and index "
 37.3430 @@ -4154,23 +3231,23 @@
 37.3431  msgstr ""
 37.3432  
 37.3433  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
 37.3434 -#: ../en/ch04-concepts.xml:55
 37.3435 +#: ../en/ch03-concepts.xml:55
 37.3436  msgid "<imageobject><imagedata fileref=\"images/filelog.png\"/></imageobject>"
 37.3437  msgstr ""
 37.3438  
 37.3439  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
 37.3440 -#: ../en/ch04-concepts.xml:57
 37.3441 +#: ../en/ch03-concepts.xml:57
 37.3442  msgid ""
 37.3443  "Relationships between files in working directory and filelogs in repository"
 37.3444  msgstr ""
 37.3445  
 37.3446  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.3447 -#: ../en/ch04-concepts.xml:65
 37.3448 +#: ../en/ch03-concepts.xml:65
 37.3449  msgid "Managing tracked files"
 37.3450  msgstr "管理跟踪的文件"
 37.3451  
 37.3452  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3453 -#: ../en/ch04-concepts.xml:67
 37.3454 +#: ../en/ch03-concepts.xml:67
 37.3455  msgid ""
 37.3456  "Mercurial uses a structure called a <emphasis>manifest</emphasis> to collect "
 37.3457  "together information about the files that it tracks.  Each entry in the "
 37.3458 @@ -4180,12 +3257,12 @@
 37.3459  msgstr ""
 37.3460  
 37.3461  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.3462 -#: ../en/ch04-concepts.xml:77
 37.3463 +#: ../en/ch03-concepts.xml:77
 37.3464  msgid "Recording changeset information"
 37.3465  msgstr "记录修改集信息"
 37.3466  
 37.3467  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3468 -#: ../en/ch04-concepts.xml:79
 37.3469 +#: ../en/ch03-concepts.xml:79
 37.3470  msgid ""
 37.3471  "The <emphasis>changelog</emphasis> contains information about each "
 37.3472  "changeset.  Each revision records who committed a change, the changeset "
 37.3473 @@ -4194,12 +3271,12 @@
 37.3474  msgstr ""
 37.3475  
 37.3476  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.3477 -#: ../en/ch04-concepts.xml:87
 37.3478 +#: ../en/ch03-concepts.xml:87
 37.3479  msgid "Relationships between revisions"
 37.3480  msgstr "版本之间的关系"
 37.3481  
 37.3482  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3483 -#: ../en/ch04-concepts.xml:89
 37.3484 +#: ../en/ch03-concepts.xml:89
 37.3485  msgid ""
 37.3486  "Within a changelog, a manifest, or a filelog, each revision stores a pointer "
 37.3487  "to its immediate parent (or to its two parents, if it's a merge revision).  "
 37.3488 @@ -4209,7 +3286,7 @@
 37.3489  msgstr ""
 37.3490  
 37.3491  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3492 -#: ../en/ch04-concepts.xml:96
 37.3493 +#: ../en/ch03-concepts.xml:96
 37.3494  msgid ""
 37.3495  "For every changeset in a repository, there is exactly one revision stored in "
 37.3496  "the changelog.  Each revision of the changelog contains a pointer to a single "
 37.3497 @@ -4220,17 +3297,17 @@
 37.3498  msgstr ""
 37.3499  
 37.3500  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
 37.3501 -#: ../en/ch04-concepts.xml:107
 37.3502 +#: ../en/ch03-concepts.xml:107
 37.3503  msgid "<imageobject><imagedata fileref=\"images/metadata.png\"/></imageobject>"
 37.3504  msgstr ""
 37.3505  
 37.3506  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
 37.3507 -#: ../en/ch04-concepts.xml:109
 37.3508 +#: ../en/ch03-concepts.xml:109
 37.3509  msgid "Metadata relationships"
 37.3510  msgstr ""
 37.3511  
 37.3512  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3513 -#: ../en/ch04-concepts.xml:114
 37.3514 +#: ../en/ch03-concepts.xml:114
 37.3515  msgid ""
 37.3516  "As the illustration shows, there is <emphasis>not</emphasis> a <quote>one to "
 37.3517  "one</quote> relationship between revisions in the changelog, manifest, or "
 37.3518 @@ -4242,24 +3319,24 @@
 37.3519  msgstr ""
 37.3520  
 37.3521  #. type: Content of: <book><chapter><sect1><title>
 37.3522 -#: ../en/ch04-concepts.xml:127
 37.3523 +#: ../en/ch03-concepts.xml:127
 37.3524  msgid "Safe, efficient storage"
 37.3525  msgstr "安全,高效的存储"
 37.3526  
 37.3527  #. type: Content of: <book><chapter><sect1><para>
 37.3528 -#: ../en/ch04-concepts.xml:129
 37.3529 +#: ../en/ch03-concepts.xml:129
 37.3530  msgid ""
 37.3531  "The underpinnings of changelogs, manifests, and filelogs are provided by a "
 37.3532  "single structure called the <emphasis>revlog</emphasis>."
 37.3533  msgstr ""
 37.3534  
 37.3535  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.3536 -#: ../en/ch04-concepts.xml:134
 37.3537 +#: ../en/ch03-concepts.xml:134
 37.3538  msgid "Efficient storage"
 37.3539  msgstr "高效存储"
 37.3540  
 37.3541  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3542 -#: ../en/ch04-concepts.xml:136
 37.3543 +#: ../en/ch03-concepts.xml:136
 37.3544  msgid ""
 37.3545  "The revlog provides efficient storage of revisions using a <emphasis>delta</"
 37.3546  "emphasis> mechanism.  Instead of storing a complete copy of a file for each "
 37.3547 @@ -4269,7 +3346,7 @@
 37.3548  msgstr ""
 37.3549  
 37.3550  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3551 -#: ../en/ch04-concepts.xml:144
 37.3552 +#: ../en/ch03-concepts.xml:144
 37.3553  msgid ""
 37.3554  "Some obsolete revision control systems can only work with deltas of text "
 37.3555  "files.  They must either store binary files as complete snapshots or encoded "
 37.3556 @@ -4279,12 +3356,12 @@
 37.3557  msgstr ""
 37.3558  
 37.3559  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.3560 -#: ../en/ch04-concepts.xml:153
 37.3561 +#: ../en/ch03-concepts.xml:153
 37.3562  msgid "Safe operation"
 37.3563  msgstr "安全操作"
 37.3564  
 37.3565  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3566 -#: ../en/ch04-concepts.xml:155
 37.3567 +#: ../en/ch03-concepts.xml:155
 37.3568  msgid ""
 37.3569  "Mercurial only ever <emphasis>appends</emphasis> data to the end of a revlog "
 37.3570  "file. It never modifies a section of a file after it has written it.  This is "
 37.3571 @@ -4293,7 +3370,7 @@
 37.3572  msgstr ""
 37.3573  
 37.3574  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3575 -#: ../en/ch04-concepts.xml:161
 37.3576 +#: ../en/ch03-concepts.xml:161
 37.3577  msgid ""
 37.3578  "In addition, Mercurial treats every write as part of a <emphasis>transaction</"
 37.3579  "emphasis> that can span a number of files.  A transaction is "
 37.3580 @@ -4305,7 +3382,7 @@
 37.3581  msgstr ""
 37.3582  
 37.3583  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3584 -#: ../en/ch04-concepts.xml:171
 37.3585 +#: ../en/ch03-concepts.xml:171
 37.3586  msgid ""
 37.3587  "The fact that Mercurial only appends to files makes it easier to provide this "
 37.3588  "transactional guarantee.  The easier it is to do stuff like this, the more "
 37.3589 @@ -4313,12 +3390,12 @@
 37.3590  msgstr ""
 37.3591  
 37.3592  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.3593 -#: ../en/ch04-concepts.xml:178
 37.3594 +#: ../en/ch03-concepts.xml:178
 37.3595  msgid "Fast retrieval"
 37.3596  msgstr "快速检索"
 37.3597  
 37.3598  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3599 -#: ../en/ch04-concepts.xml:180
 37.3600 +#: ../en/ch03-concepts.xml:180
 37.3601  msgid ""
 37.3602  "Mercurial cleverly avoids a pitfall common to all earlier revision control "
 37.3603  "systems: the problem of <emphasis>inefficient retrieval</emphasis>. Most "
 37.3604 @@ -4331,17 +3408,17 @@
 37.3605  msgstr ""
 37.3606  
 37.3607  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
 37.3608 -#: ../en/ch04-concepts.xml:193
 37.3609 +#: ../en/ch03-concepts.xml:193
 37.3610  msgid "<imageobject><imagedata fileref=\"images/snapshot.png\"/></imageobject>"
 37.3611  msgstr ""
 37.3612  
 37.3613  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
 37.3614 -#: ../en/ch04-concepts.xml:195
 37.3615 +#: ../en/ch03-concepts.xml:195
 37.3616  msgid "Snapshot of a revlog, with incremental deltas"
 37.3617  msgstr ""
 37.3618  
 37.3619  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3620 -#: ../en/ch04-concepts.xml:200
 37.3621 +#: ../en/ch03-concepts.xml:200
 37.3622  msgid ""
 37.3623  "The innovation that Mercurial applies to this problem is simple but "
 37.3624  "effective.  Once the cumulative amount of delta information stored since the "
 37.3625 @@ -4353,7 +3430,7 @@
 37.3626  msgstr ""
 37.3627  
 37.3628  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3629 -#: ../en/ch04-concepts.xml:209
 37.3630 +#: ../en/ch03-concepts.xml:209
 37.3631  msgid ""
 37.3632  "Figure <xref endterm=\"fig.concepts.snapshot.caption\" linkend=\"fig.concepts."
 37.3633  "snapshot\"/> illustrates the idea.  In an entry in a revlog's index file, "
 37.3634 @@ -4362,12 +3439,12 @@
 37.3635  msgstr ""
 37.3636  
 37.3637  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
 37.3638 -#: ../en/ch04-concepts.xml:216
 37.3639 +#: ../en/ch03-concepts.xml:216
 37.3640  msgid "Aside: the influence of video compression"
 37.3641  msgstr ""
 37.3642  
 37.3643  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.3644 -#: ../en/ch04-concepts.xml:218
 37.3645 +#: ../en/ch03-concepts.xml:218
 37.3646  msgid ""
 37.3647  "If you're familiar with video compression or have ever watched a TV feed "
 37.3648  "through a digital cable or satellite service, you may know that most video "
 37.3649 @@ -4378,7 +3455,7 @@
 37.3650  msgstr ""
 37.3651  
 37.3652  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.3653 -#: ../en/ch04-concepts.xml:227
 37.3654 +#: ../en/ch03-concepts.xml:227
 37.3655  msgid ""
 37.3656  "Because it's possible for a video stream to <quote>drop out</quote> "
 37.3657  "occasionally due to signal glitches, and to limit the accumulation of "
 37.3658 @@ -4391,12 +3468,12 @@
 37.3659  msgstr ""
 37.3660  
 37.3661  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.3662 -#: ../en/ch04-concepts.xml:241
 37.3663 +#: ../en/ch03-concepts.xml:241
 37.3664  msgid "Identification and strong integrity"
 37.3665  msgstr "鉴别和强完整性"
 37.3666  
 37.3667  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3668 -#: ../en/ch04-concepts.xml:243
 37.3669 +#: ../en/ch03-concepts.xml:243
 37.3670  msgid ""
 37.3671  "Along with delta or snapshot information, a revlog entry contains a "
 37.3672  "cryptographic hash of the data that it represents.  This makes it difficult "
 37.3673 @@ -4404,7 +3481,7 @@
 37.3674  msgstr ""
 37.3675  
 37.3676  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3677 -#: ../en/ch04-concepts.xml:248
 37.3678 +#: ../en/ch03-concepts.xml:248
 37.3679  msgid ""
 37.3680  "Hashes provide more than a mere check against corruption; they are used as "
 37.3681  "the identifiers for revisions.  The changeset identification hashes that you "
 37.3682 @@ -4413,7 +3490,7 @@
 37.3683  msgstr ""
 37.3684  
 37.3685  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3686 -#: ../en/ch04-concepts.xml:255
 37.3687 +#: ../en/ch03-concepts.xml:255
 37.3688  msgid ""
 37.3689  "Mercurial verifies that hashes are correct when it retrieves file revisions "
 37.3690  "and when it pulls changes from another repository.  If it encounters an "
 37.3691 @@ -4421,7 +3498,7 @@
 37.3692  msgstr ""
 37.3693  
 37.3694  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3695 -#: ../en/ch04-concepts.xml:260
 37.3696 +#: ../en/ch03-concepts.xml:260
 37.3697  msgid ""
 37.3698  "In addition to the effect it has on retrieval efficiency, Mercurial's use of "
 37.3699  "periodic snapshots makes it more robust against partial data corruption.  If "
 37.3700 @@ -4432,12 +3509,12 @@
 37.3701  msgstr ""
 37.3702  
 37.3703  #. type: Content of: <book><chapter><sect1><title>
 37.3704 -#: ../en/ch04-concepts.xml:272
 37.3705 +#: ../en/ch03-concepts.xml:272
 37.3706  msgid "Revision history, branching, and merging"
 37.3707  msgstr "修订历史,分支与合并"
 37.3708  
 37.3709  #. type: Content of: <book><chapter><sect1><para>
 37.3710 -#: ../en/ch04-concepts.xml:274
 37.3711 +#: ../en/ch03-concepts.xml:274
 37.3712  msgid ""
 37.3713  "Every entry in a Mercurial revlog knows the identity of its immediate "
 37.3714  "ancestor revision, usually referred to as its <emphasis>parent</emphasis>.  "
 37.3715 @@ -4448,7 +3525,7 @@
 37.3716  msgstr ""
 37.3717  
 37.3718  #. type: Content of: <book><chapter><sect1><para>
 37.3719 -#: ../en/ch04-concepts.xml:282
 37.3720 +#: ../en/ch03-concepts.xml:282
 37.3721  msgid ""
 37.3722  "In figure <xref endterm=\"fig.concepts.revlog.caption\" linkend=\"fig."
 37.3723  "concepts.revlog\"/>, you can see an example of the conceptual structure of a "
 37.3724 @@ -4457,7 +3534,7 @@
 37.3725  msgstr ""
 37.3726  
 37.3727  #. type: Content of: <book><chapter><sect1><para>
 37.3728 -#: ../en/ch04-concepts.xml:289
 37.3729 +#: ../en/ch03-concepts.xml:289
 37.3730  msgid ""
 37.3731  "The first revision in a revlog (at the bottom of the image)  has the null ID "
 37.3732  "in both of its parent slots.  For a <quote>normal</quote> revision, its first "
 37.3733 @@ -4469,29 +3546,29 @@
 37.3734  msgstr ""
 37.3735  
 37.3736  #. type: Content of: <book><chapter><sect1><informalfigure><mediaobject>
 37.3737 -#: ../en/ch04-concepts.xml:300
 37.3738 +#: ../en/ch03-concepts.xml:300
 37.3739  msgid "<imageobject><imagedata fileref=\"images/revlog.png\"/></imageobject>"
 37.3740  msgstr ""
 37.3741  
 37.3742  #. type: Content of: <book><chapter><sect1><informalfigure><mediaobject><caption><para>
 37.3743 -#: ../en/ch04-concepts.xml:302
 37.3744 +#: ../en/ch03-concepts.xml:302
 37.3745  msgid "Revision in revlog"
 37.3746  msgstr ""
 37.3747  
 37.3748  #. type: Content of: <book><chapter><sect1><title>
 37.3749 -#: ../en/ch04-concepts.xml:309
 37.3750 +#: ../en/ch03-concepts.xml:309
 37.3751  msgid "The working directory"
 37.3752  msgstr "工作目录"
 37.3753  
 37.3754  #. type: Content of: <book><chapter><sect1><para>
 37.3755 -#: ../en/ch04-concepts.xml:311
 37.3756 +#: ../en/ch03-concepts.xml:311
 37.3757  msgid ""
 37.3758  "In the working directory, Mercurial stores a snapshot of the files from the "
 37.3759  "repository as of a particular changeset."
 37.3760  msgstr ""
 37.3761  
 37.3762  #. type: Content of: <book><chapter><sect1><para>
 37.3763 -#: ../en/ch04-concepts.xml:314
 37.3764 +#: ../en/ch03-concepts.xml:314
 37.3765  msgid ""
 37.3766  "The working directory <quote>knows</quote> which changeset it contains.  When "
 37.3767  "you update the working directory to contain a particular changeset, Mercurial "
 37.3768 @@ -4502,7 +3579,7 @@
 37.3769  msgstr ""
 37.3770  
 37.3771  #. type: Content of: <book><chapter><sect1><para>
 37.3772 -#: ../en/ch04-concepts.xml:323
 37.3773 +#: ../en/ch03-concepts.xml:323
 37.3774  msgid ""
 37.3775  "The <emphasis>dirstate</emphasis> contains Mercurial's knowledge of the "
 37.3776  "working directory.  This details which changeset the working directory is "
 37.3777 @@ -4511,7 +3588,7 @@
 37.3778  msgstr ""
 37.3779  
 37.3780  #. type: Content of: <book><chapter><sect1><para>
 37.3781 -#: ../en/ch04-concepts.xml:329
 37.3782 +#: ../en/ch03-concepts.xml:329
 37.3783  msgid ""
 37.3784  "Just as a revision of a revlog has room for two parents, so that it can "
 37.3785  "represent either a normal revision (with one parent)  or a merge of two "
 37.3786 @@ -4526,12 +3603,12 @@
 37.3787  msgstr ""
 37.3788  
 37.3789  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.3790 -#: ../en/ch04-concepts.xml:343
 37.3791 +#: ../en/ch03-concepts.xml:343
 37.3792  msgid "What happens when you commit"
 37.3793  msgstr "当你提交时发生的事情"
 37.3794  
 37.3795  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3796 -#: ../en/ch04-concepts.xml:345
 37.3797 +#: ../en/ch03-concepts.xml:345
 37.3798  msgid ""
 37.3799  "The dirstate stores parent information for more than just book-keeping "
 37.3800  "purposes.  Mercurial uses the parents of the dirstate as <emphasis>the "
 37.3801 @@ -4539,17 +3616,17 @@
 37.3802  msgstr ""
 37.3803  
 37.3804  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
 37.3805 -#: ../en/ch04-concepts.xml:352
 37.3806 +#: ../en/ch03-concepts.xml:352
 37.3807  msgid "<imageobject><imagedata fileref=\"images/wdir.png\"/></imageobject>"
 37.3808  msgstr ""
 37.3809  
 37.3810  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
 37.3811 -#: ../en/ch04-concepts.xml:354
 37.3812 +#: ../en/ch03-concepts.xml:354
 37.3813  msgid "The working directory can have two parents"
 37.3814  msgstr ""
 37.3815  
 37.3816  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3817 -#: ../en/ch04-concepts.xml:359
 37.3818 +#: ../en/ch03-concepts.xml:359
 37.3819  msgid ""
 37.3820  "Figure <xref endterm=\"fig.concepts.wdir.caption\" linkend=\"fig.concepts.wdir"
 37.3821  "\"/> shows the normal state of the working directory, where it has a single "
 37.3822 @@ -4558,19 +3635,19 @@
 37.3823  msgstr ""
 37.3824  
 37.3825  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
 37.3826 -#: ../en/ch04-concepts.xml:368
 37.3827 +#: ../en/ch03-concepts.xml:368
 37.3828  msgid ""
 37.3829  "<imageobject><imagedata fileref=\"images/wdir-after-commit.png\"/> </"
 37.3830  "imageobject>"
 37.3831  msgstr ""
 37.3832  
 37.3833  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
 37.3834 -#: ../en/ch04-concepts.xml:371
 37.3835 +#: ../en/ch03-concepts.xml:371
 37.3836  msgid "The working directory gains new parents after a commit"
 37.3837  msgstr ""
 37.3838  
 37.3839  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3840 -#: ../en/ch04-concepts.xml:376
 37.3841 +#: ../en/ch03-concepts.xml:376
 37.3842  msgid ""
 37.3843  "It's useful to think of the working directory as <quote>the changeset I'm "
 37.3844  "about to commit</quote>.  Any files that you tell Mercurial that you've "
 37.3845 @@ -4580,7 +3657,7 @@
 37.3846  msgstr ""
 37.3847  
 37.3848  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3849 -#: ../en/ch04-concepts.xml:384
 37.3850 +#: ../en/ch03-concepts.xml:384
 37.3851  msgid ""
 37.3852  "After a commit, Mercurial will update the parents of the working directory, "
 37.3853  "so that the first parent is the ID of the new changeset, and the second is "
 37.3854 @@ -4591,12 +3668,12 @@
 37.3855  msgstr ""
 37.3856  
 37.3857  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.3858 -#: ../en/ch04-concepts.xml:396
 37.3859 +#: ../en/ch03-concepts.xml:396
 37.3860  msgid "Creating a new head"
 37.3861  msgstr "创建新顶点"
 37.3862  
 37.3863  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3864 -#: ../en/ch04-concepts.xml:398
 37.3865 +#: ../en/ch03-concepts.xml:398
 37.3866  msgid ""
 37.3867  "It's perfectly normal to update the working directory to a changeset other "
 37.3868  "than the current tip.  For example, you might want to know what your project "
 37.3869 @@ -4610,19 +3687,19 @@
 37.3870  msgstr ""
 37.3871  
 37.3872  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
 37.3873 -#: ../en/ch04-concepts.xml:412
 37.3874 +#: ../en/ch03-concepts.xml:412
 37.3875  msgid ""
 37.3876  "<imageobject><imagedata fileref=\"images/wdir-pre-branch.png\"/> </"
 37.3877  "imageobject>"
 37.3878  msgstr ""
 37.3879  
 37.3880  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
 37.3881 -#: ../en/ch04-concepts.xml:415
 37.3882 +#: ../en/ch03-concepts.xml:415
 37.3883  msgid "The working directory, updated to an older changeset"
 37.3884  msgstr ""
 37.3885  
 37.3886  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3887 -#: ../en/ch04-concepts.xml:420
 37.3888 +#: ../en/ch03-concepts.xml:420
 37.3889  msgid ""
 37.3890  "Having updated the working directory to an older changeset, what happens if "
 37.3891  "you make some changes, and then commit? Mercurial behaves in the same way as "
 37.3892 @@ -4635,18 +3712,18 @@
 37.3893  msgstr ""
 37.3894  
 37.3895  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
 37.3896 -#: ../en/ch04-concepts.xml:434
 37.3897 +#: ../en/ch03-concepts.xml:434
 37.3898  msgid ""
 37.3899  "<imageobject><imagedata fileref=\"images/wdir-branch.png\"/> </imageobject>"
 37.3900  msgstr ""
 37.3901  
 37.3902  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
 37.3903 -#: ../en/ch04-concepts.xml:437
 37.3904 +#: ../en/ch03-concepts.xml:437
 37.3905  msgid "After a commit made while synced to an older changeset"
 37.3906  msgstr ""
 37.3907  
 37.3908  #. type: Content of: <book><chapter><sect1><sect2><note><para>
 37.3909 -#: ../en/ch04-concepts.xml:443
 37.3910 +#: ../en/ch03-concepts.xml:443
 37.3911  msgid ""
 37.3912  "If you're new to Mercurial, you should keep in mind a common <quote>error</"
 37.3913  "quote>, which is to use the <command role=\"hg-cmd\">hg pull</command> "
 37.3914 @@ -4660,7 +3737,7 @@
 37.3915  msgstr ""
 37.3916  
 37.3917  #. type: Content of: <book><chapter><sect1><sect2><note><para>
 37.3918 -#: ../en/ch04-concepts.xml:455
 37.3919 +#: ../en/ch03-concepts.xml:455
 37.3920  msgid ""
 37.3921  "I put the word <quote>error</quote> in quotes because all that you need to do "
 37.3922  "to rectify this situation is <command role=\"hg-cmd\">hg merge</command>, "
 37.3923 @@ -4671,12 +3748,12 @@
 37.3924  msgstr ""
 37.3925  
 37.3926  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.3927 -#: ../en/ch04-concepts.xml:467
 37.3928 +#: ../en/ch03-concepts.xml:467
 37.3929  msgid "Merging heads"
 37.3930  msgstr "合并顶点"
 37.3931  
 37.3932  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3933 -#: ../en/ch04-concepts.xml:469
 37.3934 +#: ../en/ch03-concepts.xml:469
 37.3935  msgid ""
 37.3936  "When you run the <command role=\"hg-cmd\">hg merge</command> command, "
 37.3937  "Mercurial leaves the first parent of the working directory unchanged, and "
 37.3938 @@ -4686,18 +3763,18 @@
 37.3939  msgstr ""
 37.3940  
 37.3941  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
 37.3942 -#: ../en/ch04-concepts.xml:478
 37.3943 +#: ../en/ch03-concepts.xml:478
 37.3944  msgid ""
 37.3945  "<imageobject><imagedata fileref=\"images/wdir-merge.png\"/> </imageobject>"
 37.3946  msgstr ""
 37.3947  
 37.3948  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
 37.3949 -#: ../en/ch04-concepts.xml:481
 37.3950 +#: ../en/ch03-concepts.xml:481
 37.3951  msgid "Merging two heads"
 37.3952  msgstr ""
 37.3953  
 37.3954  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.3955 -#: ../en/ch04-concepts.xml:486
 37.3956 +#: ../en/ch03-concepts.xml:486
 37.3957  msgid ""
 37.3958  "Mercurial also has to modify the working directory, to merge the files "
 37.3959  "managed in the two changesets.  Simplified a little, the merging process goes "
 37.3960 @@ -4705,33 +3782,33 @@
 37.3961  msgstr ""
 37.3962  
 37.3963  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.3964 -#: ../en/ch04-concepts.xml:491
 37.3965 +#: ../en/ch03-concepts.xml:491
 37.3966  msgid "If neither changeset has modified a file, do nothing with that file."
 37.3967  msgstr ""
 37.3968  
 37.3969  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.3970 -#: ../en/ch04-concepts.xml:494
 37.3971 +#: ../en/ch03-concepts.xml:494
 37.3972  msgid ""
 37.3973  "If one changeset has modified a file, and the other hasn't, create the "
 37.3974  "modified copy of the file in the working directory."
 37.3975  msgstr ""
 37.3976  
 37.3977  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.3978 -#: ../en/ch04-concepts.xml:498
 37.3979 +#: ../en/ch03-concepts.xml:498
 37.3980  msgid ""
 37.3981  "If one changeset has removed a file, and the other hasn't (or has also "
 37.3982  "deleted it), delete the file from the working directory."
 37.3983  msgstr ""
 37.3984  
 37.3985  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.3986 -#: ../en/ch04-concepts.xml:502
 37.3987 +#: ../en/ch03-concepts.xml:502
 37.3988  msgid ""
 37.3989  "If one changeset has removed a file, but the other has modified the file, ask "
 37.3990  "the user what to do: keep the modified file, or remove it?"
 37.3991  msgstr ""
 37.3992  
 37.3993  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.3994 -#: ../en/ch04-concepts.xml:506
 37.3995 +#: ../en/ch03-concepts.xml:506
 37.3996  msgid ""
 37.3997  "If both changesets have modified a file, invoke an external merge program to "
 37.3998  "choose the new contents for the merged file.  This may require input from the "
 37.3999 @@ -4739,14 +3816,14 @@
 37.4000  msgstr ""
 37.4001  
 37.4002  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.4003 -#: ../en/ch04-concepts.xml:511
 37.4004 +#: ../en/ch03-concepts.xml:511
 37.4005  msgid ""
 37.4006  "If one changeset has modified a file, and the other has renamed or copied the "
 37.4007  "file, make sure that the changes follow the new name of the file."
 37.4008  msgstr ""
 37.4009  
 37.4010  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4011 -#: ../en/ch04-concepts.xml:515
 37.4012 +#: ../en/ch03-concepts.xml:515
 37.4013  msgid ""
 37.4014  "There are more details&emdash;merging has plenty of corner cases&emdash;but "
 37.4015  "these are the most common choices that are involved in a merge.  As you can "
 37.4016 @@ -4755,7 +3832,7 @@
 37.4017  msgstr ""
 37.4018  
 37.4019  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4020 -#: ../en/ch04-concepts.xml:522
 37.4021 +#: ../en/ch03-concepts.xml:522
 37.4022  msgid ""
 37.4023  "When you're thinking about what happens when you commit after a merge, once "
 37.4024  "again the working directory is <quote>the changeset I'm about to commit</"
 37.4025 @@ -4765,7 +3842,7 @@
 37.4026  msgstr ""
 37.4027  
 37.4028  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4029 -#: ../en/ch04-concepts.xml:529
 37.4030 +#: ../en/ch03-concepts.xml:529
 37.4031  msgid ""
 37.4032  "Mercurial lets you perform multiple merges, but you must commit the results "
 37.4033  "of each individual merge as you go.  This is necessary because Mercurial only "
 37.4034 @@ -4776,12 +3853,12 @@
 37.4035  msgstr ""
 37.4036  
 37.4037  #. type: Content of: <book><chapter><sect1><title>
 37.4038 -#: ../en/ch04-concepts.xml:540
 37.4039 +#: ../en/ch03-concepts.xml:540
 37.4040  msgid "Other interesting design features"
 37.4041  msgstr "其它有趣的设计特性"
 37.4042  
 37.4043  #. type: Content of: <book><chapter><sect1><para>
 37.4044 -#: ../en/ch04-concepts.xml:542
 37.4045 +#: ../en/ch03-concepts.xml:542
 37.4046  msgid ""
 37.4047  "In the sections above, I've tried to highlight some of the most important "
 37.4048  "aspects of Mercurial's design, to illustrate that it pays careful attention "
 37.4049 @@ -4794,12 +3871,12 @@
 37.4050  msgstr ""
 37.4051  
 37.4052  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.4053 -#: ../en/ch04-concepts.xml:553
 37.4054 +#: ../en/ch03-concepts.xml:553
 37.4055  msgid "Clever compression"
 37.4056  msgstr "智能压缩"
 37.4057  
 37.4058  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4059 -#: ../en/ch04-concepts.xml:555
 37.4060 +#: ../en/ch03-concepts.xml:555
 37.4061  msgid ""
 37.4062  "When appropriate, Mercurial will store both snapshots and deltas in "
 37.4063  "compressed form.  It does this by always <emphasis>trying to</emphasis> "
 37.4064 @@ -4808,7 +3885,7 @@
 37.4065  msgstr ""
 37.4066  
 37.4067  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4068 -#: ../en/ch04-concepts.xml:561
 37.4069 +#: ../en/ch03-concepts.xml:561
 37.4070  msgid ""
 37.4071  "This means that Mercurial does <quote>the right thing</quote> when storing a "
 37.4072  "file whose native form is compressed, such as a <literal>zip</literal> "
 37.4073 @@ -4818,7 +3895,7 @@
 37.4074  msgstr ""
 37.4075  
 37.4076  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4077 -#: ../en/ch04-concepts.xml:569
 37.4078 +#: ../en/ch03-concepts.xml:569
 37.4079  msgid ""
 37.4080  "Deltas between revisions of a compressed file are usually larger than "
 37.4081  "snapshots of the file, and Mercurial again does <quote>the right thing</"
 37.4082 @@ -4828,12 +3905,12 @@
 37.4083  msgstr ""
 37.4084  
 37.4085  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
 37.4086 -#: ../en/ch04-concepts.xml:578
 37.4087 +#: ../en/ch03-concepts.xml:578
 37.4088  msgid "Network recompression"
 37.4089  msgstr "网络重新压缩"
 37.4090  
 37.4091  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.4092 -#: ../en/ch04-concepts.xml:580
 37.4093 +#: ../en/ch03-concepts.xml:580
 37.4094  msgid ""
 37.4095  "When storing revisions on disk, Mercurial uses the <quote>deflate</quote> "
 37.4096  "compression algorithm (the same one used by the popular <literal>zip</"
 37.4097 @@ -4843,7 +3920,7 @@
 37.4098  msgstr ""
 37.4099  
 37.4100  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.4101 -#: ../en/ch04-concepts.xml:588
 37.4102 +#: ../en/ch03-concepts.xml:588
 37.4103  msgid ""
 37.4104  "If the connection is over HTTP, Mercurial recompresses the entire stream of "
 37.4105  "data using a compression algorithm that gives a better compression ratio (the "
 37.4106 @@ -4855,7 +3932,7 @@
 37.4107  msgstr ""
 37.4108  
 37.4109  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.4110 -#: ../en/ch04-concepts.xml:598
 37.4111 +#: ../en/ch03-concepts.xml:598
 37.4112  msgid ""
 37.4113  "(If the connection is over <command>ssh</command>, Mercurial "
 37.4114  "<emphasis>doesn't</emphasis> recompress the stream, because <command>ssh</"
 37.4115 @@ -4863,12 +3940,12 @@
 37.4116  msgstr ""
 37.4117  
 37.4118  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.4119 -#: ../en/ch04-concepts.xml:606
 37.4120 +#: ../en/ch03-concepts.xml:606
 37.4121  msgid "Read/write ordering and atomicity"
 37.4122  msgstr "读写顺序与原子性"
 37.4123  
 37.4124  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4125 -#: ../en/ch04-concepts.xml:608
 37.4126 +#: ../en/ch03-concepts.xml:608
 37.4127  msgid ""
 37.4128  "Appending to files isn't the whole story when it comes to guaranteeing that a "
 37.4129  "reader won't see a partial write.  If you recall figure <xref endterm=\"fig."
 37.4130 @@ -4878,7 +3955,7 @@
 37.4131  msgstr ""
 37.4132  
 37.4133  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4134 -#: ../en/ch04-concepts.xml:616
 37.4135 +#: ../en/ch03-concepts.xml:616
 37.4136  msgid ""
 37.4137  "A writer starts a transaction by writing filelog and manifest data, and "
 37.4138  "doesn't write any changelog data until those are finished.  A reader starts "
 37.4139 @@ -4886,7 +3963,7 @@
 37.4140  msgstr ""
 37.4141  
 37.4142  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4143 -#: ../en/ch04-concepts.xml:621
 37.4144 +#: ../en/ch03-concepts.xml:621
 37.4145  msgid ""
 37.4146  "Since the writer has always finished writing filelog and manifest data before "
 37.4147  "it writes to the changelog, a reader will never read a pointer to a partially "
 37.4148 @@ -4895,12 +3972,12 @@
 37.4149  msgstr ""
 37.4150  
 37.4151  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.4152 -#: ../en/ch04-concepts.xml:629
 37.4153 +#: ../en/ch03-concepts.xml:629
 37.4154  msgid "Concurrent access"
 37.4155  msgstr "并发访问"
 37.4156  
 37.4157  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4158 -#: ../en/ch04-concepts.xml:631
 37.4159 +#: ../en/ch03-concepts.xml:631
 37.4160  msgid ""
 37.4161  "The read/write ordering and atomicity guarantees mean that Mercurial never "
 37.4162  "needs to <emphasis>lock</emphasis> a repository when it's reading data, even "
 37.4163 @@ -4911,7 +3988,7 @@
 37.4164  msgstr ""
 37.4165  
 37.4166  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4167 -#: ../en/ch04-concepts.xml:640
 37.4168 +#: ../en/ch03-concepts.xml:640
 37.4169  msgid ""
 37.4170  "The lockless nature of reading means that if you're sharing a repository on a "
 37.4171  "multi-user system, you don't need to grant other local users permission to "
 37.4172 @@ -4925,7 +4002,7 @@
 37.4173  msgstr ""
 37.4174  
 37.4175  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4176 -#: ../en/ch04-concepts.xml:653
 37.4177 +#: ../en/ch03-concepts.xml:653
 37.4178  msgid ""
 37.4179  "Mercurial uses locks to ensure that only one process can write to a "
 37.4180  "repository at a time (the locking mechanism is safe even over filesystems "
 37.4181 @@ -4939,12 +4016,12 @@
 37.4182  msgstr ""
 37.4183  
 37.4184  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
 37.4185 -#: ../en/ch04-concepts.xml:665
 37.4186 +#: ../en/ch03-concepts.xml:665
 37.4187  msgid "Safe dirstate access"
 37.4188  msgstr "安全的目录状态访问"
 37.4189  
 37.4190  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.4191 -#: ../en/ch04-concepts.xml:667
 37.4192 +#: ../en/ch03-concepts.xml:667
 37.4193  msgid ""
 37.4194  "As with revision data, Mercurial doesn't take a lock to read the dirstate "
 37.4195  "file; it does acquire a lock to write it.  To avoid the possibility of "
 37.4196 @@ -4956,12 +4033,12 @@
 37.4197  msgstr ""
 37.4198  
 37.4199  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.4200 -#: ../en/ch04-concepts.xml:680
 37.4201 +#: ../en/ch03-concepts.xml:680
 37.4202  msgid "Avoiding seeks"
 37.4203  msgstr "避免查找"
 37.4204  
 37.4205  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4206 -#: ../en/ch04-concepts.xml:682
 37.4207 +#: ../en/ch03-concepts.xml:682
 37.4208  msgid ""
 37.4209  "Critical to Mercurial's performance is the avoidance of seeks of the disk "
 37.4210  "head, since any seek is far more expensive than even a comparatively large "
 37.4211 @@ -4969,7 +4046,7 @@
 37.4212  msgstr ""
 37.4213  
 37.4214  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4215 -#: ../en/ch04-concepts.xml:686
 37.4216 +#: ../en/ch03-concepts.xml:686
 37.4217  msgid ""
 37.4218  "This is why, for example, the dirstate is stored in a single file.  If there "
 37.4219  "were a dirstate file per directory that Mercurial tracked, the disk would "
 37.4220 @@ -4978,7 +4055,7 @@
 37.4221  msgstr ""
 37.4222  
 37.4223  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4224 -#: ../en/ch04-concepts.xml:692
 37.4225 +#: ../en/ch03-concepts.xml:692
 37.4226  msgid ""
 37.4227  "Mercurial also uses a <quote>copy on write</quote> scheme when cloning a "
 37.4228  "repository on local storage.  Instead of copying every revlog file from the "
 37.4229 @@ -4991,7 +4068,7 @@
 37.4230  msgstr ""
 37.4231  
 37.4232  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4233 -#: ../en/ch04-concepts.xml:703
 37.4234 +#: ../en/ch03-concepts.xml:703
 37.4235  msgid ""
 37.4236  "A few revision control developers have pointed out that this idea of making a "
 37.4237  "complete private copy of a file is not very efficient in its use of storage.  "
 37.4238 @@ -5003,12 +4080,12 @@
 37.4239  msgstr ""
 37.4240  
 37.4241  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.4242 -#: ../en/ch04-concepts.xml:715
 37.4243 +#: ../en/ch03-concepts.xml:715
 37.4244  msgid "Other contents of the dirstate"
 37.4245  msgstr "目录状态的其它内容"
 37.4246  
 37.4247  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4248 -#: ../en/ch04-concepts.xml:717
 37.4249 +#: ../en/ch03-concepts.xml:717
 37.4250  msgid ""
 37.4251  "Because Mercurial doesn't force you to tell it when you're modifying a file, "
 37.4252  "it uses the dirstate to store some extra information so it can determine "
 37.4253 @@ -5018,7 +4095,7 @@
 37.4254  msgstr ""
 37.4255  
 37.4256  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4257 -#: ../en/ch04-concepts.xml:724
 37.4258 +#: ../en/ch03-concepts.xml:724
 37.4259  msgid ""
 37.4260  "When you explicitly <command role=\"hg-cmd\">hg add</command>, <command role="
 37.4261  "\"hg-cmd\">hg remove</command>, <command role=\"hg-cmd\">hg rename</command> "
 37.4262 @@ -5027,7 +4104,7 @@
 37.4263  msgstr ""
 37.4264  
 37.4265  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4266 -#: ../en/ch04-concepts.xml:731
 37.4267 +#: ../en/ch03-concepts.xml:731
 37.4268  msgid ""
 37.4269  "When Mercurial is checking the states of files in the working directory, it "
 37.4270  "first checks a file's modification time.  If that has not changed, the file "
 37.4271 @@ -5041,17 +4118,17 @@
 37.4272  msgstr ""
 37.4273  
 37.4274  #. type: Content of: <book><chapter><title>
 37.4275 -#: ../en/ch05-daily.xml:5
 37.4276 +#: ../en/ch04-daily.xml:5
 37.4277  msgid "Mercurial in daily use"
 37.4278  msgstr "Mercurial 的日常使用"
 37.4279  
 37.4280  #. type: Content of: <book><chapter><sect1><title>
 37.4281 -#: ../en/ch05-daily.xml:8
 37.4282 +#: ../en/ch04-daily.xml:8
 37.4283  msgid "Telling Mercurial which files to track"
 37.4284  msgstr "告诉 Mercurial 要跟踪哪些文件"
 37.4285  
 37.4286  #. type: Content of: <book><chapter><sect1><para>
 37.4287 -#: ../en/ch05-daily.xml:10
 37.4288 +#: ../en/ch04-daily.xml:10
 37.4289  msgid ""
 37.4290  "Mercurial does not work with files in your repository unless you tell it to "
 37.4291  "manage them.  The <command role=\"hg-cmd\">hg status</command> command will "
 37.4292 @@ -5061,7 +4138,7 @@
 37.4293  
 37.4294  #
 37.4295  #. type: Content of: <book><chapter><sect1><para>
 37.4296 -#: ../en/ch05-daily.xml:17
 37.4297 +#: ../en/ch04-daily.xml:17
 37.4298  msgid ""
 37.4299  "To tell Mercurial to track a file, use the <command role=\"hg-cmd\">hg add</"
 37.4300  "command> command.  Once you have added a file, the entry in the output of "
 37.4301 @@ -5070,7 +4147,7 @@
 37.4302  msgstr ""
 37.4303  
 37.4304  #. type: Content of: <book><chapter><sect1><para>
 37.4305 -#: ../en/ch05-daily.xml:26
 37.4306 +#: ../en/ch04-daily.xml:26
 37.4307  msgid ""
 37.4308  "After you run a <command role=\"hg-cmd\">hg commit</command>, the files that "
 37.4309  "you added before the commit will no longer be listed in the output of "
 37.4310 @@ -5084,7 +4161,7 @@
 37.4311  msgstr ""
 37.4312  
 37.4313  #. type: Content of: <book><chapter><sect1><para>
 37.4314 -#: ../en/ch05-daily.xml:38
 37.4315 +#: ../en/ch04-daily.xml:38
 37.4316  msgid ""
 37.4317  "Once you add a file, Mercurial doesn't do anything with it immediately.  "
 37.4318  "Instead, it will take a snapshot of the file's state the next time you "
 37.4319 @@ -5093,12 +4170,12 @@
 37.4320  msgstr ""
 37.4321  
 37.4322  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.4323 -#: ../en/ch05-daily.xml:45
 37.4324 +#: ../en/ch04-daily.xml:45
 37.4325  msgid "Explicit versus implicit file naming"
 37.4326  msgstr "明确与隐含文件命名"
 37.4327  
 37.4328  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4329 -#: ../en/ch05-daily.xml:47
 37.4330 +#: ../en/ch04-daily.xml:47
 37.4331  msgid ""
 37.4332  "A useful behaviour that Mercurial has is that if you pass the name of a "
 37.4333  "directory to a command, every Mercurial command will treat this as <quote>I "
 37.4334 @@ -5107,7 +4184,7 @@
 37.4335  msgstr ""
 37.4336  
 37.4337  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4338 -#: ../en/ch05-daily.xml:54
 37.4339 +#: ../en/ch04-daily.xml:54
 37.4340  msgid ""
 37.4341  "Notice in this example that Mercurial printed the names of the files it "
 37.4342  "added, whereas it didn't do so when we added the file named <filename>a</"
 37.4343 @@ -5115,7 +4192,7 @@
 37.4344  msgstr ""
 37.4345  
 37.4346  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4347 -#: ../en/ch05-daily.xml:59
 37.4348 +#: ../en/ch04-daily.xml:59
 37.4349  msgid ""
 37.4350  "What's going on is that in the former case, we explicitly named the file to "
 37.4351  "add on the command line, so the assumption that Mercurial makes in such cases "
 37.4352 @@ -5123,7 +4200,7 @@
 37.4353  msgstr ""
 37.4354  
 37.4355  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4356 -#: ../en/ch05-daily.xml:64
 37.4357 +#: ../en/ch04-daily.xml:64
 37.4358  msgid ""
 37.4359  "However, when we <emphasis>imply</emphasis> the names of files by giving the "
 37.4360  "name of a directory, Mercurial takes the extra step of printing the name of "
 37.4361 @@ -5133,12 +4210,12 @@
 37.4362  msgstr ""
 37.4363  
 37.4364  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.4365 -#: ../en/ch05-daily.xml:73
 37.4366 +#: ../en/ch04-daily.xml:73
 37.4367  msgid "Aside: Mercurial tracks files, not directories"
 37.4368  msgstr "旁白: Mercurial 只跟踪文件,不跟踪目录"
 37.4369  
 37.4370  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4371 -#: ../en/ch05-daily.xml:75
 37.4372 +#: ../en/ch04-daily.xml:75
 37.4373  msgid ""
 37.4374  "Mercurial does not track directory information.  Instead, it tracks the path "
 37.4375  "to a file.  Before creating a file, it first creates any missing directory "
 37.4376 @@ -5149,7 +4226,7 @@
 37.4377  msgstr ""
 37.4378  
 37.4379  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4380 -#: ../en/ch05-daily.xml:84
 37.4381 +#: ../en/ch04-daily.xml:84
 37.4382  msgid ""
 37.4383  "Empty directories are rarely useful, and there are unintrusive workarounds "
 37.4384  "that you can use to achieve an appropriate effect.  The developers of "
 37.4385 @@ -5158,7 +4235,7 @@
 37.4386  msgstr ""
 37.4387  
 37.4388  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4389 -#: ../en/ch05-daily.xml:91
 37.4390 +#: ../en/ch04-daily.xml:91
 37.4391  msgid ""
 37.4392  "If you need an empty directory in your repository, there are a few ways to "
 37.4393  "achieve this. One is to create a directory, then <command role=\"hg-cmd\">hg "
 37.4394 @@ -5169,20 +4246,20 @@
 37.4395  msgstr ""
 37.4396  
 37.4397  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4398 -#: ../en/ch05-daily.xml:102
 37.4399 +#: ../en/ch04-daily.xml:102
 37.4400  msgid ""
 37.4401  "Another way to tackle a need for an empty directory is to simply create one "
 37.4402  "in your automated build scripts before they will need it."
 37.4403  msgstr ""
 37.4404  
 37.4405  #. type: Content of: <book><chapter><sect1><title>
 37.4406 -#: ../en/ch05-daily.xml:109
 37.4407 +#: ../en/ch04-daily.xml:109
 37.4408  msgid "How to stop tracking a file"
 37.4409  msgstr "如何停止跟踪文件"
 37.4410  
 37.4411  #
 37.4412  #. type: Content of: <book><chapter><sect1><para>
 37.4413 -#: ../en/ch05-daily.xml:111
 37.4414 +#: ../en/ch04-daily.xml:111
 37.4415  msgid ""
 37.4416  "Once you decide that a file no longer belongs in your repository, use the "
 37.4417  "<command role=\"hg-cmd\">hg remove</command> command; this deletes the file, "
 37.4418 @@ -5192,7 +4269,7 @@
 37.4419  msgstr ""
 37.4420  
 37.4421  #. type: Content of: <book><chapter><sect1><para>
 37.4422 -#: ../en/ch05-daily.xml:120
 37.4423 +#: ../en/ch04-daily.xml:120
 37.4424  msgid ""
 37.4425  "After you <command role=\"hg-cmd\">hg remove</command> a file, Mercurial will "
 37.4426  "no longer track changes to that file, even if you recreate a file with the "
 37.4427 @@ -5203,36 +4280,36 @@
 37.4428  msgstr ""
 37.4429  
 37.4430  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.4431 -#: ../en/ch05-daily.xml:129
 37.4432 +#: ../en/ch04-daily.xml:129
 37.4433  msgid "Removing a file does not affect its history"
 37.4434  msgstr "删除文件不影响历史"
 37.4435  
 37.4436  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4437 -#: ../en/ch05-daily.xml:131
 37.4438 +#: ../en/ch04-daily.xml:131
 37.4439  msgid "It is important to understand that removing a file has only two effects."
 37.4440  msgstr ""
 37.4441  
 37.4442  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.4443 -#: ../en/ch05-daily.xml:134
 37.4444 +#: ../en/ch04-daily.xml:134
 37.4445  msgid "It removes the current version of the file from the working directory."
 37.4446  msgstr ""
 37.4447  
 37.4448  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.4449 -#: ../en/ch05-daily.xml:137
 37.4450 +#: ../en/ch04-daily.xml:137
 37.4451  msgid ""
 37.4452  "It stops Mercurial from tracking changes to the file, from the time of the "
 37.4453  "next commit."
 37.4454  msgstr ""
 37.4455  
 37.4456  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4457 -#: ../en/ch05-daily.xml:140
 37.4458 +#: ../en/ch04-daily.xml:140
 37.4459  msgid ""
 37.4460  "Removing a file <emphasis>does not</emphasis> in any way alter the "
 37.4461  "<emphasis>history</emphasis> of the file."
 37.4462  msgstr ""
 37.4463  
 37.4464  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4465 -#: ../en/ch05-daily.xml:143
 37.4466 +#: ../en/ch04-daily.xml:143
 37.4467  msgid ""
 37.4468  "If you update the working directory to a changeset in which a file that you "
 37.4469  "have removed was still tracked, it will reappear in the working directory, "
 37.4470 @@ -5242,12 +4319,12 @@
 37.4471  msgstr ""
 37.4472  
 37.4473  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.4474 -#: ../en/ch05-daily.xml:153
 37.4475 +#: ../en/ch04-daily.xml:153
 37.4476  msgid "Missing files"
 37.4477  msgstr "丢失的文件"
 37.4478  
 37.4479  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4480 -#: ../en/ch05-daily.xml:155
 37.4481 +#: ../en/ch04-daily.xml:155
 37.4482  msgid ""
 37.4483  "Mercurial considers a file that you have deleted, but not used <command role="
 37.4484  "\"hg-cmd\">hg remove</command> to delete, to be <emphasis>missing</"
 37.4485 @@ -5257,7 +4334,7 @@
 37.4486  msgstr ""
 37.4487  
 37.4488  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4489 -#: ../en/ch05-daily.xml:165
 37.4490 +#: ../en/ch04-daily.xml:165
 37.4491  msgid ""
 37.4492  "If your repository contains a file that <command role=\"hg-cmd\">hg status</"
 37.4493  "command> reports as missing, and you want the file to stay gone, you can run "
 37.4494 @@ -5267,7 +4344,7 @@
 37.4495  msgstr ""
 37.4496  
 37.4497  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4498 -#: ../en/ch05-daily.xml:175
 37.4499 +#: ../en/ch04-daily.xml:175
 37.4500  msgid ""
 37.4501  "On the other hand, if you deleted the missing file by accident, give <command "
 37.4502  "role=\"hg-cmd\">hg revert</command> the name of the file to recover.  It will "
 37.4503 @@ -5275,12 +4352,12 @@
 37.4504  msgstr ""
 37.4505  
 37.4506  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.4507 -#: ../en/ch05-daily.xml:184
 37.4508 +#: ../en/ch04-daily.xml:184
 37.4509  msgid "Aside: why tell Mercurial explicitly to remove a file?"
 37.4510  msgstr "旁白: 为什么要明确告诉 Mercurial 删除文件?"
 37.4511  
 37.4512  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4513 -#: ../en/ch05-daily.xml:187
 37.4514 +#: ../en/ch04-daily.xml:187
 37.4515  msgid ""
 37.4516  "You might wonder why Mercurial requires you to explicitly tell it that you "
 37.4517  "are deleting a file.  Early during the development of Mercurial, it let you "
 37.4518 @@ -5291,12 +4368,12 @@
 37.4519  msgstr ""
 37.4520  
 37.4521  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.4522 -#: ../en/ch05-daily.xml:198
 37.4523 +#: ../en/ch04-daily.xml:198
 37.4524  msgid "Useful shorthand&emdash;adding and removing files in one step"
 37.4525  msgstr "有用的速记&emdash;一个步骤添加和删除文件"
 37.4526  
 37.4527  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4528 -#: ../en/ch05-daily.xml:201
 37.4529 +#: ../en/ch04-daily.xml:201
 37.4530  msgid ""
 37.4531  "Mercurial offers a combination command, <command role=\"hg-cmd\">hg "
 37.4532  "addremove</command>, that adds untracked files and marks missing files as "
 37.4533 @@ -5304,7 +4381,7 @@
 37.4534  msgstr ""
 37.4535  
 37.4536  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4537 -#: ../en/ch05-daily.xml:207
 37.4538 +#: ../en/ch04-daily.xml:207
 37.4539  msgid ""
 37.4540  "The <command role=\"hg-cmd\">hg commit</command> command also provides a "
 37.4541  "<option role=\"hg-opt-commit\">-A</option> option that performs this same add-"
 37.4542 @@ -5312,12 +4389,12 @@
 37.4543  msgstr ""
 37.4544  
 37.4545  #. type: Content of: <book><chapter><sect1><title>
 37.4546 -#: ../en/ch05-daily.xml:217
 37.4547 +#: ../en/ch04-daily.xml:217
 37.4548  msgid "Copying files"
 37.4549  msgstr "复制文件"
 37.4550  
 37.4551  #. type: Content of: <book><chapter><sect1><para>
 37.4552 -#: ../en/ch05-daily.xml:219
 37.4553 +#: ../en/ch04-daily.xml:219
 37.4554  msgid ""
 37.4555  "Mercurial provides a <command role=\"hg-cmd\">hg copy</command> command that "
 37.4556  "lets you make a new copy of a file.  When you copy a file using this command, "
 37.4557 @@ -5327,12 +4404,12 @@
 37.4558  msgstr ""
 37.4559  
 37.4560  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.4561 -#: ../en/ch05-daily.xml:227
 37.4562 +#: ../en/ch04-daily.xml:227
 37.4563  msgid "The results of copying during a merge"
 37.4564  msgstr "合并期间的复制结果"
 37.4565  
 37.4566  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4567 -#: ../en/ch05-daily.xml:229
 37.4568 +#: ../en/ch04-daily.xml:229
 37.4569  msgid ""
 37.4570  "What happens during a merge is that changes <quote>follow</quote> a copy.  To "
 37.4571  "best illustrate what this means, let's create an example.  We'll start with "
 37.4572 @@ -5340,28 +4417,28 @@
 37.4573  msgstr ""
 37.4574  
 37.4575  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4576 -#: ../en/ch05-daily.xml:236
 37.4577 +#: ../en/ch04-daily.xml:236
 37.4578  msgid ""
 37.4579  "We need to do some work in parallel, so that we'll have something to merge.  "
 37.4580  "So let's clone our repository."
 37.4581  msgstr ""
 37.4582  
 37.4583  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4584 -#: ../en/ch05-daily.xml:242
 37.4585 +#: ../en/ch04-daily.xml:242
 37.4586  msgid ""
 37.4587  "Back in our initial repository, let's use the <command role=\"hg-cmd\">hg "
 37.4588  "copy</command> command to make a copy of the first file we created."
 37.4589  msgstr ""
 37.4590  
 37.4591  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4592 -#: ../en/ch05-daily.xml:248
 37.4593 +#: ../en/ch04-daily.xml:248
 37.4594  msgid ""
 37.4595  "If we look at the output of the <command role=\"hg-cmd\">hg status</command> "
 37.4596  "command afterwards, the copied file looks just like a normal added file."
 37.4597  msgstr ""
 37.4598  
 37.4599  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4600 -#: ../en/ch05-daily.xml:254
 37.4601 +#: ../en/ch04-daily.xml:254
 37.4602  msgid ""
 37.4603  "But if we pass the <option role=\"hg-opt-status\">-C</option> option to "
 37.4604  "<command role=\"hg-cmd\">hg status</command>, it prints another line of "
 37.4605 @@ -5370,14 +4447,14 @@
 37.4606  msgstr ""
 37.4607  
 37.4608  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4609 -#: ../en/ch05-daily.xml:262
 37.4610 +#: ../en/ch04-daily.xml:262
 37.4611  msgid ""
 37.4612  "Now, back in the repository we cloned, let's make a change in parallel.  "
 37.4613  "We'll add a line of content to the original file that we created."
 37.4614  msgstr ""
 37.4615  
 37.4616  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4617 -#: ../en/ch05-daily.xml:268
 37.4618 +#: ../en/ch04-daily.xml:268
 37.4619  msgid ""
 37.4620  "Now we have a modified <filename>file</filename> in this repository.  When we "
 37.4621  "pull the changes from the first repository, and merge the two heads, "
 37.4622 @@ -5386,19 +4463,19 @@
 37.4623  msgstr ""
 37.4624  
 37.4625  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.4626 -#: ../en/ch05-daily.xml:278
 37.4627 +#: ../en/ch04-daily.xml:278
 37.4628  msgid "Why should changes follow copies?"
 37.4629  msgstr "为什么复制后需要后续修改?"
 37.4630  
 37.4631  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4632 -#: ../en/ch05-daily.xml:280
 37.4633 +#: ../en/ch04-daily.xml:280
 37.4634  msgid ""
 37.4635  "This behaviour, of changes to a file propagating out to copies of the file, "
 37.4636  "might seem esoteric, but in most cases it's highly desirable."
 37.4637  msgstr ""
 37.4638  
 37.4639  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4640 -#: ../en/ch05-daily.xml:284
 37.4641 +#: ../en/ch04-daily.xml:284
 37.4642  msgid ""
 37.4643  "First of all, remember that this propagation <emphasis>only</emphasis> "
 37.4644  "happens when you merge.  So if you <command role=\"hg-cmd\">hg copy</command> "
 37.4645 @@ -5407,7 +4484,7 @@
 37.4646  msgstr ""
 37.4647  
 37.4648  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4649 -#: ../en/ch05-daily.xml:290
 37.4650 +#: ../en/ch04-daily.xml:290
 37.4651  msgid ""
 37.4652  "The second thing to know is that modifications will only propagate across a "
 37.4653  "copy as long as the repository that you're pulling changes from "
 37.4654 @@ -5415,7 +4492,7 @@
 37.4655  msgstr ""
 37.4656  
 37.4657  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4658 -#: ../en/ch05-daily.xml:295
 37.4659 +#: ../en/ch04-daily.xml:295
 37.4660  msgid ""
 37.4661  "The reason that Mercurial does this is as follows.  Let's say I make an "
 37.4662  "important bug fix in a source file, and commit my changes. Meanwhile, you've "
 37.4663 @@ -5425,7 +4502,7 @@
 37.4664  msgstr ""
 37.4665  
 37.4666  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4667 -#: ../en/ch05-daily.xml:302
 37.4668 +#: ../en/ch04-daily.xml:302
 37.4669  msgid ""
 37.4670  "If you pulled and merged my changes, and Mercurial <emphasis>didn't</"
 37.4671  "emphasis> propagate changes across copies, your source file would now contain "
 37.4672 @@ -5434,7 +4511,7 @@
 37.4673  msgstr ""
 37.4674  
 37.4675  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4676 -#: ../en/ch05-daily.xml:308
 37.4677 +#: ../en/ch04-daily.xml:308
 37.4678  msgid ""
 37.4679  "By automatically propagating the change that fixed the bug from the original "
 37.4680  "file to the copy, Mercurial prevents this class of problem. To my knowledge, "
 37.4681 @@ -5443,7 +4520,7 @@
 37.4682  msgstr ""
 37.4683  
 37.4684  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4685 -#: ../en/ch05-daily.xml:314
 37.4686 +#: ../en/ch04-daily.xml:314
 37.4687  msgid ""
 37.4688  "Once your change history has a record that the copy and subsequent merge "
 37.4689  "occurred, there's usually no further need to propagate changes from the "
 37.4690 @@ -5452,12 +4529,12 @@
 37.4691  msgstr ""
 37.4692  
 37.4693  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.4694 -#: ../en/ch05-daily.xml:322
 37.4695 +#: ../en/ch04-daily.xml:322
 37.4696  msgid "How to make changes <emphasis>not</emphasis> follow a copy"
 37.4697  msgstr "如何让复制后<emphasis>不</emphasis>修改?"
 37.4698  
 37.4699  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4700 -#: ../en/ch05-daily.xml:325
 37.4701 +#: ../en/ch04-daily.xml:325
 37.4702  msgid ""
 37.4703  "If, for some reason, you decide that this business of automatically "
 37.4704  "propagating changes across copies is not for you, simply use your system's "
 37.4705 @@ -5469,12 +4546,12 @@
 37.4706  msgstr ""
 37.4707  
 37.4708  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.4709 -#: ../en/ch05-daily.xml:338
 37.4710 +#: ../en/ch04-daily.xml:338
 37.4711  msgid "Behaviour of the <command role=\"hg-cmd\">hg copy</command> command"
 37.4712  msgstr "命令 <command role=\"hg-cmd\">hg copy</command> 的特性"
 37.4713  
 37.4714  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4715 -#: ../en/ch05-daily.xml:341
 37.4716 +#: ../en/ch04-daily.xml:341
 37.4717  msgid ""
 37.4718  "When you use the <command role=\"hg-cmd\">hg copy</command> command, "
 37.4719  "Mercurial makes a copy of each source file as it currently stands in the "
 37.4720 @@ -5486,7 +4563,7 @@
 37.4721  msgstr ""
 37.4722  
 37.4723  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4724 -#: ../en/ch05-daily.xml:351
 37.4725 +#: ../en/ch04-daily.xml:351
 37.4726  msgid ""
 37.4727  "The <command role=\"hg-cmd\">hg copy</command> command acts similarly to the "
 37.4728  "Unix <command>cp</command> command (you can use the <command role=\"hg-cmd"
 37.4729 @@ -5497,21 +4574,21 @@
 37.4730  msgstr ""
 37.4731  
 37.4732  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4733 -#: ../en/ch05-daily.xml:362
 37.4734 +#: ../en/ch04-daily.xml:362
 37.4735  msgid ""
 37.4736  "If the destination is a directory, Mercurial copies its sources into that "
 37.4737  "directory."
 37.4738  msgstr ""
 37.4739  
 37.4740  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4741 -#: ../en/ch05-daily.xml:367
 37.4742 +#: ../en/ch04-daily.xml:367
 37.4743  msgid ""
 37.4744  "Copying a directory is recursive, and preserves the directory structure of "
 37.4745  "the source."
 37.4746  msgstr ""
 37.4747  
 37.4748  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4749 -#: ../en/ch05-daily.xml:373
 37.4750 +#: ../en/ch04-daily.xml:373
 37.4751  msgid ""
 37.4752  "If the source and destination are both directories, the source tree is "
 37.4753  "recreated in the destination directory."
 37.4754 @@ -5519,7 +4596,7 @@
 37.4755  
 37.4756  #
 37.4757  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4758 -#: ../en/ch05-daily.xml:378
 37.4759 +#: ../en/ch04-daily.xml:378
 37.4760  msgid ""
 37.4761  "As with the <command role=\"hg-cmd\">hg rename</command> command, if you copy "
 37.4762  "a file manually and then want Mercurial to know that you've copied the file, "
 37.4763 @@ -5528,12 +4605,12 @@
 37.4764  msgstr ""
 37.4765  
 37.4766  #. type: Content of: <book><chapter><sect1><title>
 37.4767 -#: ../en/ch05-daily.xml:389
 37.4768 +#: ../en/ch04-daily.xml:389
 37.4769  msgid "Renaming files"
 37.4770  msgstr "改名文件"
 37.4771  
 37.4772  #. type: Content of: <book><chapter><sect1><para>
 37.4773 -#: ../en/ch05-daily.xml:391
 37.4774 +#: ../en/ch04-daily.xml:391
 37.4775  msgid ""
 37.4776  "It's rather more common to need to rename a file than to make a copy of it.  "
 37.4777  "The reason I discussed the <command role=\"hg-cmd\">hg copy</command> command "
 37.4778 @@ -5543,7 +4620,7 @@
 37.4779  msgstr ""
 37.4780  
 37.4781  #. type: Content of: <book><chapter><sect1><para>
 37.4782 -#: ../en/ch05-daily.xml:399
 37.4783 +#: ../en/ch04-daily.xml:399
 37.4784  msgid ""
 37.4785  "When you use the <command role=\"hg-cmd\">hg rename</command> command, "
 37.4786  "Mercurial makes a copy of each source file, then deletes it and marks the "
 37.4787 @@ -5551,14 +4628,14 @@
 37.4788  msgstr ""
 37.4789  
 37.4790  #. type: Content of: <book><chapter><sect1><para>
 37.4791 -#: ../en/ch05-daily.xml:405
 37.4792 +#: ../en/ch04-daily.xml:405
 37.4793  msgid ""
 37.4794  "The <command role=\"hg-cmd\">hg status</command> command shows the newly "
 37.4795  "copied file as added, and the copied-from file as removed."
 37.4796  msgstr ""
 37.4797  
 37.4798  #. type: Content of: <book><chapter><sect1><para>
 37.4799 -#: ../en/ch05-daily.xml:411
 37.4800 +#: ../en/ch04-daily.xml:411
 37.4801  msgid ""
 37.4802  "As with the results of a <command role=\"hg-cmd\">hg copy</command>, we must "
 37.4803  "use the <option role=\"hg-opt-status\">-C</option> option to <command role="
 37.4804 @@ -5567,7 +4644,7 @@
 37.4805  msgstr ""
 37.4806  
 37.4807  #. type: Content of: <book><chapter><sect1><para>
 37.4808 -#: ../en/ch05-daily.xml:420
 37.4809 +#: ../en/ch04-daily.xml:420
 37.4810  msgid ""
 37.4811  "As with <command role=\"hg-cmd\">hg remove</command> and <command role=\"hg-"
 37.4812  "cmd\">hg copy</command>, you can tell Mercurial about a rename after the fact "
 37.4813 @@ -5578,19 +4655,19 @@
 37.4814  msgstr ""
 37.4815  
 37.4816  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.4817 -#: ../en/ch05-daily.xml:430
 37.4818 +#: ../en/ch04-daily.xml:430
 37.4819  msgid "Renaming files and merging changes"
 37.4820  msgstr "改名文件与合并修改"
 37.4821  
 37.4822  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4823 -#: ../en/ch05-daily.xml:432
 37.4824 +#: ../en/ch04-daily.xml:432
 37.4825  msgid ""
 37.4826  "Since Mercurial's rename is implemented as copy-and-remove, the same "
 37.4827  "propagation of changes happens when you merge after a rename as after a copy."
 37.4828  msgstr ""
 37.4829  
 37.4830  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4831 -#: ../en/ch05-daily.xml:436
 37.4832 +#: ../en/ch04-daily.xml:436
 37.4833  msgid ""
 37.4834  "If I modify a file, and you rename it to a new name, and then we merge our "
 37.4835  "respective changes, my modifications to the file under its original name will "
 37.4836 @@ -5600,7 +4677,7 @@
 37.4837  msgstr ""
 37.4838  
 37.4839  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4840 -#: ../en/ch05-daily.xml:443
 37.4841 +#: ../en/ch04-daily.xml:443
 37.4842  msgid ""
 37.4843  "Whereas having changes follow a copy is a feature where you can perhaps nod "
 37.4844  "and say <quote>yes, that might be useful,</quote> it should be clear that "
 37.4845 @@ -5610,12 +4687,12 @@
 37.4846  msgstr ""
 37.4847  
 37.4848  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.4849 -#: ../en/ch05-daily.xml:452
 37.4850 +#: ../en/ch04-daily.xml:452
 37.4851  msgid "Divergent renames and merging"
 37.4852  msgstr "改名与合并的分歧"
 37.4853  
 37.4854  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4855 -#: ../en/ch05-daily.xml:454
 37.4856 +#: ../en/ch04-daily.xml:454
 37.4857  msgid ""
 37.4858  "The case of diverging names occurs when two developers start with a "
 37.4859  "file&emdash;let's call it <filename>foo</filename>&emdash;in their respective "
 37.4860 @@ -5623,17 +4700,17 @@
 37.4861  msgstr ""
 37.4862  
 37.4863  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4864 -#: ../en/ch05-daily.xml:461
 37.4865 +#: ../en/ch04-daily.xml:461
 37.4866  msgid "Anne renames the file to <filename>bar</filename>."
 37.4867  msgstr ""
 37.4868  
 37.4869  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4870 -#: ../en/ch05-daily.xml:465
 37.4871 +#: ../en/ch04-daily.xml:465
 37.4872  msgid "Meanwhile, Bob renames it to <filename>quux</filename>."
 37.4873  msgstr ""
 37.4874  
 37.4875  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4876 -#: ../en/ch05-daily.xml:470
 37.4877 +#: ../en/ch04-daily.xml:470
 37.4878  msgid ""
 37.4879  "I like to think of this as a conflict because each developer has expressed "
 37.4880  "different intentions about what the file ought to be named."
 37.4881 @@ -5641,7 +4718,7 @@
 37.4882  
 37.4883  #
 37.4884  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4885 -#: ../en/ch05-daily.xml:474
 37.4886 +#: ../en/ch04-daily.xml:474
 37.4887  msgid ""
 37.4888  "What do you think should happen when they merge their work? Mercurial's "
 37.4889  "actual behaviour is that it always preserves <emphasis>both</emphasis> names "
 37.4890 @@ -5649,19 +4726,19 @@
 37.4891  msgstr ""
 37.4892  
 37.4893  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4894 -#: ../en/ch05-daily.xml:481
 37.4895 +#: ../en/ch04-daily.xml:481
 37.4896  msgid ""
 37.4897  "Notice that Mercurial does warn about the divergent renames, but it leaves it "
 37.4898  "up to you to do something about the divergence after the merge."
 37.4899  msgstr ""
 37.4900  
 37.4901  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.4902 -#: ../en/ch05-daily.xml:487
 37.4903 +#: ../en/ch04-daily.xml:487
 37.4904  msgid "Convergent renames and merging"
 37.4905  msgstr "收敛改名与合并"
 37.4906  
 37.4907  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4908 -#: ../en/ch05-daily.xml:489
 37.4909 +#: ../en/ch04-daily.xml:489
 37.4910  msgid ""
 37.4911  "Another kind of rename conflict occurs when two people choose to rename "
 37.4912  "different <emphasis>source</emphasis> files to the same "
 37.4913 @@ -5670,12 +4747,12 @@
 37.4914  msgstr ""
 37.4915  
 37.4916  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.4917 -#: ../en/ch05-daily.xml:497
 37.4918 +#: ../en/ch04-daily.xml:497
 37.4919  msgid "Other name-related corner cases"
 37.4920  msgstr "其它名称相关的角落"
 37.4921  
 37.4922  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.4923 -#: ../en/ch05-daily.xml:499
 37.4924 +#: ../en/ch04-daily.xml:499
 37.4925  msgid ""
 37.4926  "Mercurial has a longstanding bug in which it fails to handle a merge where "
 37.4927  "one side has a file with a given name, while another has a directory with the "
 37.4928 @@ -5684,19 +4761,19 @@
 37.4929  msgstr ""
 37.4930  
 37.4931  #. type: Content of: <book><chapter><sect1><title>
 37.4932 -#: ../en/ch05-daily.xml:511
 37.4933 +#: ../en/ch04-daily.xml:511
 37.4934  msgid "Recovering from mistakes"
 37.4935  msgstr "从错误恢复"
 37.4936  
 37.4937  #. type: Content of: <book><chapter><sect1><para>
 37.4938 -#: ../en/ch05-daily.xml:513
 37.4939 +#: ../en/ch04-daily.xml:513
 37.4940  msgid ""
 37.4941  "Mercurial has some useful commands that will help you to recover from some "
 37.4942  "common mistakes."
 37.4943  msgstr ""
 37.4944  
 37.4945  #. type: Content of: <book><chapter><sect1><para>
 37.4946 -#: ../en/ch05-daily.xml:516
 37.4947 +#: ../en/ch04-daily.xml:516
 37.4948  msgid ""
 37.4949  "The <command role=\"hg-cmd\">hg revert</command> command lets you undo "
 37.4950  "changes that you have made to your working directory.  For example, if you "
 37.4951 @@ -5708,7 +4785,7 @@
 37.4952  msgstr ""
 37.4953  
 37.4954  #. type: Content of: <book><chapter><sect1><para>
 37.4955 -#: ../en/ch05-daily.xml:526
 37.4956 +#: ../en/ch04-daily.xml:526
 37.4957  msgid ""
 37.4958  "It's useful to remember that the <command role=\"hg-cmd\">hg revert</command> "
 37.4959  "command is useful for changes that you have not yet committed.  Once you've "
 37.4960 @@ -5717,7 +4794,7 @@
 37.4961  msgstr ""
 37.4962  
 37.4963  #. type: Content of: <book><chapter><sect1><para>
 37.4964 -#: ../en/ch05-daily.xml:532
 37.4965 +#: ../en/ch04-daily.xml:532
 37.4966  msgid ""
 37.4967  "For more information about the <command role=\"hg-cmd\">hg revert</command> "
 37.4968  "command, and details about how to deal with changes you have already "
 37.4969 @@ -5725,12 +4802,12 @@
 37.4970  msgstr ""
 37.4971  
 37.4972  #. type: Content of: <book><chapter><title>
 37.4973 -#: ../en/ch06-collab.xml:5
 37.4974 +#: ../en/ch05-collab.xml:5
 37.4975  msgid "Collaborating with other people"
 37.4976  msgstr "团体协作"
 37.4977  
 37.4978  #. type: Content of: <book><chapter><para>
 37.4979 -#: ../en/ch06-collab.xml:7
 37.4980 +#: ../en/ch05-collab.xml:7
 37.4981  msgid ""
 37.4982  "As a completely decentralised tool, Mercurial doesn't impose any policy on "
 37.4983  "how people ought to work with each other.  However, if you're new to "
 37.4984 @@ -5739,19 +4816,19 @@
 37.4985  msgstr ""
 37.4986  
 37.4987  #. type: Content of: <book><chapter><sect1><title>
 37.4988 -#: ../en/ch06-collab.xml:14
 37.4989 +#: ../en/ch05-collab.xml:14
 37.4990  msgid "Mercurial's web interface"
 37.4991  msgstr "Mercurial 的 web 接口"
 37.4992  
 37.4993  #. type: Content of: <book><chapter><sect1><para>
 37.4994 -#: ../en/ch06-collab.xml:16
 37.4995 +#: ../en/ch05-collab.xml:16
 37.4996  msgid ""
 37.4997  "Mercurial has a powerful web interface that provides several useful "
 37.4998  "capabilities."
 37.4999  msgstr ""
 37.5000  
 37.5001  #. type: Content of: <book><chapter><sect1><para>
 37.5002 -#: ../en/ch06-collab.xml:19
 37.5003 +#: ../en/ch05-collab.xml:19
 37.5004  msgid ""
 37.5005  "For interactive use, the web interface lets you browse a single repository or "
 37.5006  "a collection of repositories.  You can view the history of a repository, "
 37.5007 @@ -5760,7 +4837,7 @@
 37.5008  msgstr ""
 37.5009  
 37.5010  #. type: Content of: <book><chapter><sect1><para>
 37.5011 -#: ../en/ch06-collab.xml:24
 37.5012 +#: ../en/ch05-collab.xml:24
 37.5013  msgid ""
 37.5014  "Also for human consumption, the web interface provides an RSS feed of the "
 37.5015  "changes in a repository.  This lets you <quote>subscribe</quote> to a "
 37.5016 @@ -5772,7 +4849,7 @@
 37.5017  msgstr ""
 37.5018  
 37.5019  #. type: Content of: <book><chapter><sect1><para>
 37.5020 -#: ../en/ch06-collab.xml:34
 37.5021 +#: ../en/ch05-collab.xml:34
 37.5022  msgid ""
 37.5023  "The web interface also lets remote users clone a repository, pull changes "
 37.5024  "from it, and (when the server is configured to permit it) push changes back "
 37.5025 @@ -5781,7 +4858,7 @@
 37.5026  msgstr ""
 37.5027  
 37.5028  #. type: Content of: <book><chapter><sect1><para>
 37.5029 -#: ../en/ch06-collab.xml:40
 37.5030 +#: ../en/ch05-collab.xml:40
 37.5031  msgid ""
 37.5032  "The easiest way to get started with the web interface is to use your web "
 37.5033  "browser to visit an existing repository, such as the master Mercurial "
 37.5034 @@ -5790,7 +4867,7 @@
 37.5035  msgstr ""
 37.5036  
 37.5037  #. type: Content of: <book><chapter><sect1><para>
 37.5038 -#: ../en/ch06-collab.xml:45
 37.5039 +#: ../en/ch05-collab.xml:45
 37.5040  msgid ""
 37.5041  "If you're interested in providing a web interface to your own repositories, "
 37.5042  "Mercurial provides two ways to do this.  The first is using the <command role="
 37.5043 @@ -5804,12 +4881,12 @@
 37.5044  msgstr ""
 37.5045  
 37.5046  #. type: Content of: <book><chapter><sect1><title>
 37.5047 -#: ../en/ch06-collab.xml:60
 37.5048 +#: ../en/ch05-collab.xml:60
 37.5049  msgid "Collaboration models"
 37.5050  msgstr "协作模型"
 37.5051  
 37.5052  #. type: Content of: <book><chapter><sect1><para>
 37.5053 -#: ../en/ch06-collab.xml:62
 37.5054 +#: ../en/ch05-collab.xml:62
 37.5055  msgid ""
 37.5056  "With a suitably flexible tool, making decisions about workflow is much more "
 37.5057  "of a social engineering challenge than a technical one. Mercurial imposes few "
 37.5058 @@ -5819,12 +4896,12 @@
 37.5059  msgstr ""
 37.5060  
 37.5061  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.5062 -#: ../en/ch06-collab.xml:70
 37.5063 +#: ../en/ch05-collab.xml:70
 37.5064  msgid "Factors to keep in mind"
 37.5065  msgstr "要牢记的因素"
 37.5066  
 37.5067  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5068 -#: ../en/ch06-collab.xml:72
 37.5069 +#: ../en/ch05-collab.xml:72
 37.5070  msgid ""
 37.5071  "The most important aspect of any model that you must keep in mind is how well "
 37.5072  "it matches the needs and capabilities of the people who will be using it.  "
 37.5073 @@ -5833,7 +4910,7 @@
 37.5074  msgstr ""
 37.5075  
 37.5076  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5077 -#: ../en/ch06-collab.xml:78
 37.5078 +#: ../en/ch05-collab.xml:78
 37.5079  msgid ""
 37.5080  "I once put together a workflow model that seemed to make perfect sense to me, "
 37.5081  "but that caused a considerable amount of consternation and strife within my "
 37.5082 @@ -5846,7 +4923,7 @@
 37.5083  msgstr ""
 37.5084  
 37.5085  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5086 -#: ../en/ch06-collab.xml:88
 37.5087 +#: ../en/ch05-collab.xml:88
 37.5088  msgid ""
 37.5089  "Don't sweep foreseeable social or technical problems under the rug. Whatever "
 37.5090  "scheme you put into effect, you should plan for mistakes and problem "
 37.5091 @@ -5860,12 +4937,12 @@
 37.5092  msgstr ""
 37.5093  
 37.5094  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.5095 -#: ../en/ch06-collab.xml:102
 37.5096 +#: ../en/ch05-collab.xml:102
 37.5097  msgid "Informal anarchy"
 37.5098  msgstr "无政府状态"
 37.5099  
 37.5100  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5101 -#: ../en/ch06-collab.xml:104
 37.5102 +#: ../en/ch05-collab.xml:104
 37.5103  msgid ""
 37.5104  "I wouldn't suggest an <quote>anything goes</quote> approach as something "
 37.5105  "sustainable, but it's a model that's easy to grasp, and it works perfectly "
 37.5106 @@ -5873,7 +4950,7 @@
 37.5107  msgstr ""
 37.5108  
 37.5109  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5110 -#: ../en/ch06-collab.xml:109
 37.5111 +#: ../en/ch05-collab.xml:109
 37.5112  msgid ""
 37.5113  "As one example, many projects have a loose-knit group of collaborators who "
 37.5114  "rarely physically meet each other.  Some groups like to overcome the "
 37.5115 @@ -5885,7 +4962,7 @@
 37.5116  msgstr ""
 37.5117  
 37.5118  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5119 -#: ../en/ch06-collab.xml:118
 37.5120 +#: ../en/ch05-collab.xml:118
 37.5121  msgid ""
 37.5122  "A sprint is the perfect place to use the <command role=\"hg-cmd\">hg serve</"
 37.5123  "command> command, since <command role=\"hg-cmd\">hg serve</command> does not "
 37.5124 @@ -5900,7 +4977,7 @@
 37.5125  msgstr ""
 37.5126  
 37.5127  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5128 -#: ../en/ch06-collab.xml:132
 37.5129 +#: ../en/ch05-collab.xml:132
 37.5130  msgid ""
 37.5131  "The charm, and the problem, with doing things in an ad hoc fashion like this "
 37.5132  "is that only people who know about your changes, and where they are, can see "
 37.5133 @@ -5910,12 +4987,12 @@
 37.5134  msgstr ""
 37.5135  
 37.5136  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.5137 -#: ../en/ch06-collab.xml:141
 37.5138 +#: ../en/ch05-collab.xml:141
 37.5139  msgid "A single central repository"
 37.5140  msgstr "单一中央版本库"
 37.5141  
 37.5142  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5143 -#: ../en/ch06-collab.xml:143
 37.5144 +#: ../en/ch05-collab.xml:143
 37.5145  msgid ""
 37.5146  "For smaller projects migrating from a centralised revision control tool, "
 37.5147  "perhaps the easiest way to get started is to have changes flow through a "
 37.5148 @@ -5924,7 +5001,7 @@
 37.5149  msgstr ""
 37.5150  
 37.5151  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5152 -#: ../en/ch06-collab.xml:149
 37.5153 +#: ../en/ch05-collab.xml:149
 37.5154  msgid ""
 37.5155  "Contributors start by cloning a copy of this repository.  They can pull "
 37.5156  "changes from it whenever they need to, and some (perhaps all) developers have "
 37.5157 @@ -5933,7 +5010,7 @@
 37.5158  msgstr ""
 37.5159  
 37.5160  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5161 -#: ../en/ch06-collab.xml:154
 37.5162 +#: ../en/ch05-collab.xml:154
 37.5163  msgid ""
 37.5164  "Under this model, it can still often make sense for people to pull changes "
 37.5165  "directly from each other, without going through the central repository.  "
 37.5166 @@ -5946,7 +5023,7 @@
 37.5167  msgstr ""
 37.5168  
 37.5169  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5170 -#: ../en/ch06-collab.xml:165
 37.5171 +#: ../en/ch05-collab.xml:165
 37.5172  msgid ""
 37.5173  "In this kind of scenario, people usually use the <command>ssh</command> "
 37.5174  "protocol to securely push changes to the central repository, as documented in "
 37.5175 @@ -5958,12 +5035,12 @@
 37.5176  msgstr ""
 37.5177  
 37.5178  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.5179 -#: ../en/ch06-collab.xml:178
 37.5180 +#: ../en/ch05-collab.xml:178
 37.5181  msgid "Working with multiple branches"
 37.5182  msgstr "使用多个分支工作"
 37.5183  
 37.5184  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5185 -#: ../en/ch06-collab.xml:180
 37.5186 +#: ../en/ch05-collab.xml:180
 37.5187  msgid ""
 37.5188  "Projects of any significant size naturally tend to make progress on several "
 37.5189  "fronts simultaneously.  In the case of software, it's common for a project to "
 37.5190 @@ -5977,7 +5054,7 @@
 37.5191  msgstr ""
 37.5192  
 37.5193  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5194 -#: ../en/ch06-collab.xml:193
 37.5195 +#: ../en/ch05-collab.xml:193
 37.5196  msgid ""
 37.5197  "Mercurial is particularly well suited to managing a number of simultaneous, "
 37.5198  "but not identical, branches.  Each <quote>development direction</quote> can "
 37.5199 @@ -5988,19 +5065,19 @@
 37.5200  msgstr ""
 37.5201  
 37.5202  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5203 -#: ../en/ch06-collab.xml:202
 37.5204 +#: ../en/ch05-collab.xml:202
 37.5205  msgid ""
 37.5206  "Here's an example of how this can work in practice.  Let's say you have one "
 37.5207  "<quote>main branch</quote> on a central server."
 37.5208  msgstr ""
 37.5209  
 37.5210  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5211 -#: ../en/ch06-collab.xml:208
 37.5212 +#: ../en/ch05-collab.xml:208
 37.5213  msgid "People clone it, make changes locally, test them, and push them back."
 37.5214  msgstr ""
 37.5215  
 37.5216  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5217 -#: ../en/ch06-collab.xml:211
 37.5218 +#: ../en/ch05-collab.xml:211
 37.5219  msgid ""
 37.5220  "Once the main branch reaches a release milestone, you can use the <command "
 37.5221  "role=\"hg-cmd\">hg tag</command> command to give a permanent name to the "
 37.5222 @@ -6008,12 +5085,12 @@
 37.5223  msgstr ""
 37.5224  
 37.5225  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5226 -#: ../en/ch06-collab.xml:217
 37.5227 +#: ../en/ch05-collab.xml:217
 37.5228  msgid "Let's say some ongoing development occurs on the main branch."
 37.5229  msgstr ""
 37.5230  
 37.5231  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5232 -#: ../en/ch06-collab.xml:222
 37.5233 +#: ../en/ch05-collab.xml:222
 37.5234  msgid ""
 37.5235  "Using the tag that was recorded at the milestone, people who clone that "
 37.5236  "repository at any time in the future can use <command role=\"hg-cmd\">hg "
 37.5237 @@ -6023,7 +5100,7 @@
 37.5238  
 37.5239  #
 37.5240  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5241 -#: ../en/ch06-collab.xml:230
 37.5242 +#: ../en/ch05-collab.xml:230
 37.5243  msgid ""
 37.5244  "In addition, immediately after the main branch is tagged, someone can then "
 37.5245  "clone the main branch on the server to a new <quote>stable</quote> branch, "
 37.5246 @@ -6031,7 +5108,7 @@
 37.5247  msgstr ""
 37.5248  
 37.5249  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5250 -#: ../en/ch06-collab.xml:236
 37.5251 +#: ../en/ch05-collab.xml:236
 37.5252  msgid ""
 37.5253  "Someone who needs to make a change to the stable branch can then clone "
 37.5254  "<emphasis>that</emphasis> repository, make their changes, commit, and push "
 37.5255 @@ -6039,7 +5116,7 @@
 37.5256  msgstr ""
 37.5257  
 37.5258  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5259 -#: ../en/ch06-collab.xml:242
 37.5260 +#: ../en/ch05-collab.xml:242
 37.5261  msgid ""
 37.5262  "Because Mercurial repositories are independent, and Mercurial doesn't move "
 37.5263  "changes around automatically, the stable and main branches are "
 37.5264 @@ -6049,7 +5126,7 @@
 37.5265  msgstr ""
 37.5266  
 37.5267  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5268 -#: ../en/ch06-collab.xml:249
 37.5269 +#: ../en/ch05-collab.xml:249
 37.5270  msgid ""
 37.5271  "You'll often want all of your bugfixes on the stable branch to show up on the "
 37.5272  "main branch, too.  Rather than rewrite a bugfix on the main branch, you can "
 37.5273 @@ -6058,7 +5135,7 @@
 37.5274  msgstr ""
 37.5275  
 37.5276  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5277 -#: ../en/ch06-collab.xml:257
 37.5278 +#: ../en/ch05-collab.xml:257
 37.5279  msgid ""
 37.5280  "The main branch will still contain changes that are not on the stable branch, "
 37.5281  "but it will also contain all of the bugfixes from the stable branch.  The "
 37.5282 @@ -6066,12 +5143,12 @@
 37.5283  msgstr ""
 37.5284  
 37.5285  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
 37.5286 -#: ../en/ch06-collab.xml:264 ../en/ch06-collab.xml:278
 37.5287 +#: ../en/ch05-collab.xml:264 ../en/ch05-collab.xml:278
 37.5288  msgid "Feature branches"
 37.5289  msgstr "特性分支"
 37.5290  
 37.5291  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5292 -#: ../en/ch06-collab.xml:266
 37.5293 +#: ../en/ch05-collab.xml:266
 37.5294  msgid ""
 37.5295  "For larger projects, an effective way to manage change is to break up a team "
 37.5296  "into smaller groups.  Each group has a shared branch of its own, cloned from "
 37.5297 @@ -6081,14 +5158,14 @@
 37.5298  msgstr ""
 37.5299  
 37.5300  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
 37.5301 -#: ../en/ch06-collab.xml:275
 37.5302 +#: ../en/ch05-collab.xml:275
 37.5303  msgid ""
 37.5304  "<imageobject><imagedata fileref=\"images/feature-branches.png\"/> </"
 37.5305  "imageobject>"
 37.5306  msgstr ""
 37.5307  
 37.5308  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5309 -#: ../en/ch06-collab.xml:283
 37.5310 +#: ../en/ch05-collab.xml:283
 37.5311  msgid ""
 37.5312  "When a particular feature is deemed to be in suitable shape, someone on that "
 37.5313  "feature team pulls and merges from the master branch into the feature branch, "
 37.5314 @@ -6096,12 +5173,12 @@
 37.5315  msgstr ""
 37.5316  
 37.5317  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.5318 -#: ../en/ch06-collab.xml:290
 37.5319 +#: ../en/ch05-collab.xml:290
 37.5320  msgid "The release train"
 37.5321  msgstr "发布列车"
 37.5322  
 37.5323  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5324 -#: ../en/ch06-collab.xml:292
 37.5325 +#: ../en/ch05-collab.xml:292
 37.5326  msgid ""
 37.5327  "Some projects are organised on a <quote>train</quote> basis: a release is "
 37.5328  "scheduled to happen every few months, and whatever features are ready when "
 37.5329 @@ -6109,7 +5186,7 @@
 37.5330  msgstr ""
 37.5331  
 37.5332  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5333 -#: ../en/ch06-collab.xml:297
 37.5334 +#: ../en/ch05-collab.xml:297
 37.5335  msgid ""
 37.5336  "This model resembles working with feature branches.  The difference is that "
 37.5337  "when a feature branch misses a train, someone on the feature team pulls and "
 37.5338 @@ -6119,12 +5196,12 @@
 37.5339  msgstr ""
 37.5340  
 37.5341  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.5342 -#: ../en/ch06-collab.xml:306
 37.5343 +#: ../en/ch05-collab.xml:306
 37.5344  msgid "The Linux kernel model"
 37.5345  msgstr "Linux 内核模型"
 37.5346  
 37.5347  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5348 -#: ../en/ch06-collab.xml:308
 37.5349 +#: ../en/ch05-collab.xml:308
 37.5350  msgid ""
 37.5351  "The development of the Linux kernel has a shallow hierarchical structure, "
 37.5352  "surrounded by a cloud of apparent chaos.  Because most Linux developers use "
 37.5353 @@ -6134,7 +5211,7 @@
 37.5354  msgstr ""
 37.5355  
 37.5356  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5357 -#: ../en/ch06-collab.xml:316
 37.5358 +#: ../en/ch05-collab.xml:316
 37.5359  msgid ""
 37.5360  "At the center of the community sits Linus Torvalds, the creator of Linux.  He "
 37.5361  "publishes a single source repository that is considered the "
 37.5362 @@ -6144,7 +5221,7 @@
 37.5363  msgstr ""
 37.5364  
 37.5365  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5366 -#: ../en/ch06-collab.xml:323
 37.5367 +#: ../en/ch05-collab.xml:323
 37.5368  msgid ""
 37.5369  "Linus has a number of <quote>trusted lieutenants</quote>.  As a general rule, "
 37.5370  "he pulls whatever changes they publish, in most cases without even reviewing "
 37.5371 @@ -6158,7 +5235,7 @@
 37.5372  msgstr ""
 37.5373  
 37.5374  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5375 -#: ../en/ch06-collab.xml:335
 37.5376 +#: ../en/ch05-collab.xml:335
 37.5377  msgid ""
 37.5378  "Individual lieutenants have their own approaches to reviewing, accepting, and "
 37.5379  "publishing changes; and for deciding when to feed them to Linus.  In "
 37.5380 @@ -6171,7 +5248,7 @@
 37.5381  msgstr ""
 37.5382  
 37.5383  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5384 -#: ../en/ch06-collab.xml:346
 37.5385 +#: ../en/ch05-collab.xml:346
 37.5386  msgid ""
 37.5387  "This model has two notable features.  The first is that it's <quote>pull "
 37.5388  "only</quote>.  You have to ask, convince, or beg another developer to take a "
 37.5389 @@ -6181,7 +5258,7 @@
 37.5390  msgstr ""
 37.5391  
 37.5392  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5393 -#: ../en/ch06-collab.xml:353
 37.5394 +#: ../en/ch05-collab.xml:353
 37.5395  msgid ""
 37.5396  "The second is that it's based on reputation and acclaim.  If you're an "
 37.5397  "unknown, Linus will probably ignore changes from you without even "
 37.5398 @@ -6195,7 +5272,7 @@
 37.5399  msgstr ""
 37.5400  
 37.5401  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5402 -#: ../en/ch06-collab.xml:364
 37.5403 +#: ../en/ch05-collab.xml:364
 37.5404  msgid ""
 37.5405  "Reputation and acclaim don't necessarily cross subsystem or <quote>people</"
 37.5406  "quote> boundaries.  If you're a respected but specialised storage hacker, and "
 37.5407 @@ -6204,7 +5281,7 @@
 37.5408  msgstr ""
 37.5409  
 37.5410  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5411 -#: ../en/ch06-collab.xml:371
 37.5412 +#: ../en/ch05-collab.xml:371
 37.5413  msgid ""
 37.5414  "To people who come from more orderly project backgrounds, the comparatively "
 37.5415  "chaotic Linux kernel development process often seems completely insane.  It's "
 37.5416 @@ -6214,12 +5291,12 @@
 37.5417  msgstr ""
 37.5418  
 37.5419  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.5420 -#: ../en/ch06-collab.xml:381
 37.5421 +#: ../en/ch05-collab.xml:381
 37.5422  msgid "Pull-only versus shared-push collaboration"
 37.5423  msgstr "只读与共享写协作"
 37.5424  
 37.5425  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5426 -#: ../en/ch06-collab.xml:383
 37.5427 +#: ../en/ch05-collab.xml:383
 37.5428  msgid ""
 37.5429  "A perpetual source of heat in the open source community is whether a "
 37.5430  "development model in which people only ever pull changes from others is "
 37.5431 @@ -6228,7 +5305,7 @@
 37.5432  msgstr ""
 37.5433  
 37.5434  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5435 -#: ../en/ch06-collab.xml:389
 37.5436 +#: ../en/ch05-collab.xml:389
 37.5437  msgid ""
 37.5438  "Typically, the backers of the shared-push model use tools that actively "
 37.5439  "enforce this approach.  If you're using a centralised revision control tool "
 37.5440 @@ -6239,7 +5316,7 @@
 37.5441  msgstr ""
 37.5442  
 37.5443  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5444 -#: ../en/ch06-collab.xml:397
 37.5445 +#: ../en/ch05-collab.xml:397
 37.5446  msgid ""
 37.5447  "A good distributed revision control tool, such as Mercurial, will support "
 37.5448  "both models.  You and your collaborators can then structure how you work "
 37.5449 @@ -6248,12 +5325,12 @@
 37.5450  msgstr ""
 37.5451  
 37.5452  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.5453 -#: ../en/ch06-collab.xml:405
 37.5454 +#: ../en/ch05-collab.xml:405
 37.5455  msgid "Where collaboration meets branch management"
 37.5456  msgstr "协作与分支管理"
 37.5457  
 37.5458  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5459 -#: ../en/ch06-collab.xml:407
 37.5460 +#: ../en/ch05-collab.xml:407
 37.5461  msgid ""
 37.5462  "Once you and your team set up some shared repositories and start propagating "
 37.5463  "changes back and forth between local and shared repos, you begin to face a "
 37.5464 @@ -6265,24 +5342,24 @@
 37.5465  msgstr ""
 37.5466  
 37.5467  #. type: Content of: <book><chapter><sect1><title>
 37.5468 -#: ../en/ch06-collab.xml:419
 37.5469 +#: ../en/ch05-collab.xml:419
 37.5470  msgid "The technical side of sharing"
 37.5471  msgstr "共享的技术因素"
 37.5472  
 37.5473  #. type: Content of: <book><chapter><sect1><para>
 37.5474 -#: ../en/ch06-collab.xml:421
 37.5475 +#: ../en/ch05-collab.xml:421
 37.5476  msgid ""
 37.5477  "The remainder of this chapter is devoted to the question of serving data to "
 37.5478  "your collaborators."
 37.5479  msgstr ""
 37.5480  
 37.5481  #. type: Content of: <book><chapter><sect1><title>
 37.5482 -#: ../en/ch06-collab.xml:426
 37.5483 +#: ../en/ch05-collab.xml:426
 37.5484  msgid "Informal sharing with <command role=\"hg-cmd\">hg serve</command>"
 37.5485  msgstr "使用 <command role=\"hg-cmd\">hg serve</command> 进行非正式共享"
 37.5486  
 37.5487  #. type: Content of: <book><chapter><sect1><para>
 37.5488 -#: ../en/ch06-collab.xml:429
 37.5489 +#: ../en/ch05-collab.xml:429
 37.5490  msgid ""
 37.5491  "Mercurial's <command role=\"hg-cmd\">hg serve</command> command is "
 37.5492  "wonderfully suited to small, tight-knit, and fast-paced group environments.  "
 37.5493 @@ -6291,7 +5368,7 @@
 37.5494  msgstr ""
 37.5495  
 37.5496  #. type: Content of: <book><chapter><sect1><para>
 37.5497 -#: ../en/ch06-collab.xml:434
 37.5498 +#: ../en/ch05-collab.xml:434
 37.5499  msgid ""
 37.5500  "Run <command role=\"hg-cmd\">hg serve</command> inside a repository, and in "
 37.5501  "under a second it will bring up a specialised HTTP server; this will accept "
 37.5502 @@ -6304,21 +5381,21 @@
 37.5503  msgstr ""
 37.5504  
 37.5505  #. type: Content of: <book><chapter><sect1><para>
 37.5506 -#: ../en/ch06-collab.xml:445
 37.5507 +#: ../en/ch05-collab.xml:445
 37.5508  msgid ""
 37.5509  "The <command role=\"hg-cmd\">hg serve</command> command is <emphasis>not</"
 37.5510  "emphasis> a general-purpose web server. It can do only two things:"
 37.5511  msgstr ""
 37.5512  
 37.5513  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.5514 -#: ../en/ch06-collab.xml:449
 37.5515 +#: ../en/ch05-collab.xml:449
 37.5516  msgid ""
 37.5517  "Allow people to browse the history of the repository it's serving, from their "
 37.5518  "normal web browsers."
 37.5519  msgstr ""
 37.5520  
 37.5521  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.5522 -#: ../en/ch06-collab.xml:453
 37.5523 +#: ../en/ch05-collab.xml:453
 37.5524  msgid ""
 37.5525  "Speak Mercurial's wire protocol, so that people can <command role=\"hg-cmd"
 37.5526  "\">hg clone</command> or <command role=\"hg-cmd\">hg pull</command> changes "
 37.5527 @@ -6326,7 +5403,7 @@
 37.5528  msgstr ""
 37.5529  
 37.5530  #. type: Content of: <book><chapter><sect1><para>
 37.5531 -#: ../en/ch06-collab.xml:458
 37.5532 +#: ../en/ch05-collab.xml:458
 37.5533  msgid ""
 37.5534  "In particular, <command role=\"hg-cmd\">hg serve</command> won't allow remote "
 37.5535  "users to <emphasis>modify</emphasis> your repository.  It's intended for read-"
 37.5536 @@ -6334,7 +5411,7 @@
 37.5537  msgstr ""
 37.5538  
 37.5539  #. type: Content of: <book><chapter><sect1><para>
 37.5540 -#: ../en/ch06-collab.xml:462
 37.5541 +#: ../en/ch05-collab.xml:462
 37.5542  msgid ""
 37.5543  "If you're getting started with Mercurial, there's nothing to prevent you from "
 37.5544  "using <command role=\"hg-cmd\">hg serve</command> to serve up a repository on "
 37.5545 @@ -6345,12 +5422,12 @@
 37.5546  msgstr ""
 37.5547  
 37.5548  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.5549 -#: ../en/ch06-collab.xml:472
 37.5550 +#: ../en/ch05-collab.xml:472
 37.5551  msgid "A few things to keep in mind"
 37.5552  msgstr "要牢记的几件事"
 37.5553  
 37.5554  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5555 -#: ../en/ch06-collab.xml:474
 37.5556 +#: ../en/ch05-collab.xml:474
 37.5557  msgid ""
 37.5558  "Because it provides unauthenticated read access to all clients, you should "
 37.5559  "only use <command role=\"hg-cmd\">hg serve</command> in an environment where "
 37.5560 @@ -6359,7 +5436,7 @@
 37.5561  msgstr ""
 37.5562  
 37.5563  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5564 -#: ../en/ch06-collab.xml:480
 37.5565 +#: ../en/ch05-collab.xml:480
 37.5566  msgid ""
 37.5567  "The <command role=\"hg-cmd\">hg serve</command> command knows nothing about "
 37.5568  "any firewall software you might have installed on your system or network.  It "
 37.5569 @@ -6370,7 +5447,7 @@
 37.5570  msgstr ""
 37.5571  
 37.5572  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5573 -#: ../en/ch06-collab.xml:489
 37.5574 +#: ../en/ch05-collab.xml:489
 37.5575  msgid ""
 37.5576  "By default, <command role=\"hg-cmd\">hg serve</command> listens for incoming "
 37.5577  "connections on port 8000.  If another process is already listening on the "
 37.5578 @@ -6379,7 +5456,7 @@
 37.5579  msgstr ""
 37.5580  
 37.5581  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5582 -#: ../en/ch06-collab.xml:495
 37.5583 +#: ../en/ch05-collab.xml:495
 37.5584  msgid ""
 37.5585  "Normally, when <command role=\"hg-cmd\">hg serve</command> starts, it prints "
 37.5586  "no output, which can be a bit unnerving.  If you'd like to confirm that it is "
 37.5587 @@ -6389,12 +5466,12 @@
 37.5588  msgstr ""
 37.5589  
 37.5590  #. type: Content of: <book><chapter><sect1><title>
 37.5591 -#: ../en/ch06-collab.xml:505
 37.5592 +#: ../en/ch05-collab.xml:505
 37.5593  msgid "Using the Secure Shell (ssh) protocol"
 37.5594  msgstr "使用 ssh 协议"
 37.5595  
 37.5596  #. type: Content of: <book><chapter><sect1><para>
 37.5597 -#: ../en/ch06-collab.xml:507
 37.5598 +#: ../en/ch05-collab.xml:507
 37.5599  msgid ""
 37.5600  "You can pull and push changes securely over a network connection using the "
 37.5601  "Secure Shell (<literal>ssh</literal>)  protocol.  To use this successfully, "
 37.5602 @@ -6403,7 +5480,7 @@
 37.5603  msgstr ""
 37.5604  
 37.5605  #. type: Content of: <book><chapter><sect1><para>
 37.5606 -#: ../en/ch06-collab.xml:512
 37.5607 +#: ../en/ch05-collab.xml:512
 37.5608  msgid ""
 37.5609  "If you're not familiar with ssh, it's a network protocol that lets you "
 37.5610  "securely communicate with another computer.  To use it with Mercurial, you'll "
 37.5611 @@ -6412,31 +5489,31 @@
 37.5612  msgstr ""
 37.5613  
 37.5614  #. type: Content of: <book><chapter><sect1><para>
 37.5615 -#: ../en/ch06-collab.xml:518
 37.5616 +#: ../en/ch05-collab.xml:518
 37.5617  msgid ""
 37.5618  "(If you <emphasis>are</emphasis> familiar with ssh, you'll probably find some "
 37.5619  "of the material that follows to be elementary in nature.)"
 37.5620  msgstr ""
 37.5621  
 37.5622  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.5623 -#: ../en/ch06-collab.xml:523
 37.5624 +#: ../en/ch05-collab.xml:523
 37.5625  msgid "How to read and write ssh URLs"
 37.5626  msgstr "如何读写 ssh 路径"
 37.5627  
 37.5628  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5629 -#: ../en/ch06-collab.xml:525
 37.5630 +#: ../en/ch05-collab.xml:525
 37.5631  msgid "An ssh URL tends to look like this:"
 37.5632  msgstr ""
 37.5633  
 37.5634  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.5635 -#: ../en/ch06-collab.xml:528
 37.5636 +#: ../en/ch05-collab.xml:528
 37.5637  msgid ""
 37.5638  "The <quote><literal>ssh://</literal></quote> part tells Mercurial to use the "
 37.5639  "ssh protocol."
 37.5640  msgstr ""
 37.5641  
 37.5642  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.5643 -#: ../en/ch06-collab.xml:531
 37.5644 +#: ../en/ch05-collab.xml:531
 37.5645  msgid ""
 37.5646  "The <quote><literal>bos@</literal></quote> component indicates what username "
 37.5647  "to log into the server as.  You can leave this out if the remote username is "
 37.5648 @@ -6444,28 +5521,28 @@
 37.5649  msgstr ""
 37.5650  
 37.5651  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.5652 -#: ../en/ch06-collab.xml:536
 37.5653 +#: ../en/ch05-collab.xml:536
 37.5654  msgid ""
 37.5655  "The <quote><literal>hg.serpentine.com</literal></quote> gives the hostname of "
 37.5656  "the server to log into."
 37.5657  msgstr ""
 37.5658  
 37.5659  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.5660 -#: ../en/ch06-collab.xml:540
 37.5661 +#: ../en/ch05-collab.xml:540
 37.5662  msgid ""
 37.5663  "The <quote>:22</quote> identifies the port number to connect to the server "
 37.5664 -"on.  The default port is 22, so you only need to specify this part if you're "
 37.5665 -"<emphasis>not</emphasis> using port 22."
 37.5666 +"on.  The default port is 22, so you only need to specify a colon and port "
 37.5667 +"number if you're <emphasis>not</emphasis> using port 22."
 37.5668  msgstr ""
 37.5669  
 37.5670  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.5671 -#: ../en/ch06-collab.xml:545
 37.5672 +#: ../en/ch05-collab.xml:545
 37.5673  msgid ""
 37.5674  "The remainder of the URL is the local path to the repository on the server."
 37.5675  msgstr ""
 37.5676  
 37.5677  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5678 -#: ../en/ch06-collab.xml:549
 37.5679 +#: ../en/ch05-collab.xml:549
 37.5680  msgid ""
 37.5681  "There's plenty of scope for confusion with the path component of ssh URLs, as "
 37.5682  "there is no standard way for tools to interpret it.  Some programs behave "
 37.5683 @@ -6475,7 +5552,7 @@
 37.5684  msgstr ""
 37.5685  
 37.5686  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5687 -#: ../en/ch06-collab.xml:556
 37.5688 +#: ../en/ch05-collab.xml:556
 37.5689  msgid ""
 37.5690  "Mercurial treats the path to a repository on the server as relative to the "
 37.5691  "remote user's home directory.  For example, if user <literal>foo</literal> on "
 37.5692 @@ -6486,7 +5563,7 @@
 37.5693  msgstr ""
 37.5694  
 37.5695  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5696 -#: ../en/ch06-collab.xml:565
 37.5697 +#: ../en/ch05-collab.xml:565
 37.5698  msgid ""
 37.5699  "If you want to specify a path relative to another user's home directory, you "
 37.5700  "can use a path that starts with a tilde character followed by the user's name "
 37.5701 @@ -6494,19 +5571,19 @@
 37.5702  msgstr ""
 37.5703  
 37.5704  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5705 -#: ../en/ch06-collab.xml:571
 37.5706 +#: ../en/ch05-collab.xml:571
 37.5707  msgid ""
 37.5708  "And if you really want to specify an <emphasis>absolute</emphasis> path on "
 37.5709  "the server, begin the path component with two slashes, as in this example."
 37.5710  msgstr ""
 37.5711  
 37.5712  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.5713 -#: ../en/ch06-collab.xml:578
 37.5714 +#: ../en/ch05-collab.xml:578
 37.5715  msgid "Finding an ssh client for your system"
 37.5716  msgstr "为你的系统寻找 ssh 客户端"
 37.5717  
 37.5718  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5719 -#: ../en/ch06-collab.xml:580
 37.5720 +#: ../en/ch05-collab.xml:580
 37.5721  msgid ""
 37.5722  "Almost every Unix-like system comes with OpenSSH preinstalled.  If you're "
 37.5723  "using such a system, run <literal>which ssh</literal> to find out if the "
 37.5724 @@ -6517,50 +5594,50 @@
 37.5725  msgstr ""
 37.5726  
 37.5727  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5728 -#: ../en/ch06-collab.xml:588
 37.5729 +#: ../en/ch05-collab.xml:588
 37.5730  msgid ""
 37.5731  "On Windows, you'll first need to download a suitable ssh client.  There are "
 37.5732  "two alternatives."
 37.5733  msgstr ""
 37.5734  
 37.5735  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.5736 -#: ../en/ch06-collab.xml:591
 37.5737 +#: ../en/ch05-collab.xml:591
 37.5738  msgid ""
 37.5739  "Simon Tatham's excellent PuTTY package <citation>web:putty</citation> "
 37.5740  "provides a complete suite of ssh client commands."
 37.5741  msgstr ""
 37.5742  
 37.5743  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.5744 -#: ../en/ch06-collab.xml:595
 37.5745 +#: ../en/ch05-collab.xml:595
 37.5746  msgid ""
 37.5747  "If you have a high tolerance for pain, you can use the Cygwin port of OpenSSH."
 37.5748  msgstr ""
 37.5749  
 37.5750  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5751 -#: ../en/ch06-collab.xml:598
 37.5752 -msgid ""
 37.5753 -"In either case, you'll need to edit your \\hgini\\ file to tell Mercurial "
 37.5754 -"where to find the actual client command.  For example, if you're using PuTTY, "
 37.5755 -"you'll need to use the <command>plink</command> command as a command-line ssh "
 37.5756 -"client."
 37.5757 +#: ../en/ch05-collab.xml:598
 37.5758 +msgid ""
 37.5759 +"In either case, you'll need to edit your <filename role=\"special\">hg.ini</"
 37.5760 +"filename> file to tell Mercurial where to find the actual client command.  "
 37.5761 +"For example, if you're using PuTTY, you'll need to use the <command>plink</"
 37.5762 +"command> command as a command-line ssh client."
 37.5763  msgstr ""
 37.5764  
 37.5765  #. type: Content of: <book><chapter><sect1><sect2><note><para>
 37.5766 -#: ../en/ch06-collab.xml:607
 37.5767 +#: ../en/ch05-collab.xml:608
 37.5768  msgid ""
 37.5769  "The path to <command>plink</command> shouldn't contain any whitespace "
 37.5770  "characters, or Mercurial may not be able to run it correctly (so putting it "
 37.5771 -"in <filename class=\"directory\">C:\\\\Program Files</filename> is probably "
 37.5772 -"not a good idea)."
 37.5773 -msgstr ""
 37.5774 -
 37.5775 -#. type: Content of: <book><chapter><sect1><sect2><title>
 37.5776 -#: ../en/ch06-collab.xml:616
 37.5777 +"in <filename class=\"directory\">C:\\Program Files</filename> is probably not "
 37.5778 +"a good idea)."
 37.5779 +msgstr ""
 37.5780 +
 37.5781 +#. type: Content of: <book><chapter><sect1><sect2><title>
 37.5782 +#: ../en/ch05-collab.xml:617
 37.5783  msgid "Generating a key pair"
 37.5784  msgstr "产生密钥对"
 37.5785  
 37.5786  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5787 -#: ../en/ch06-collab.xml:618
 37.5788 +#: ../en/ch05-collab.xml:619
 37.5789  msgid ""
 37.5790  "To avoid the need to repetitively type a password every time you need to use "
 37.5791  "your ssh client, I recommend generating a key pair.  On a Unix-like system, "
 37.5792 @@ -6570,7 +5647,7 @@
 37.5793  msgstr ""
 37.5794  
 37.5795  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5796 -#: ../en/ch06-collab.xml:626
 37.5797 +#: ../en/ch05-collab.xml:627
 37.5798  msgid ""
 37.5799  "When you generate a key pair, it's usually <emphasis>highly</emphasis> "
 37.5800  "advisable to protect it with a passphrase.  (The only time that you might not "
 37.5801 @@ -6579,7 +5656,7 @@
 37.5802  msgstr ""
 37.5803  
 37.5804  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5805 -#: ../en/ch06-collab.xml:632
 37.5806 +#: ../en/ch05-collab.xml:633
 37.5807  msgid ""
 37.5808  "Simply generating a key pair isn't enough, however.  You'll need to add the "
 37.5809  "public key to the set of authorised keys for whatever user you're logging in "
 37.5810 @@ -6590,7 +5667,7 @@
 37.5811  msgstr ""
 37.5812  
 37.5813  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5814 -#: ../en/ch06-collab.xml:641
 37.5815 +#: ../en/ch05-collab.xml:642
 37.5816  msgid ""
 37.5817  "On a Unix-like system, your public key will have a <filename>.pub</filename> "
 37.5818  "extension.  If you're using <command>puttygen</command> on Windows, you can "
 37.5819 @@ -6600,12 +5677,12 @@
 37.5820  msgstr ""
 37.5821  
 37.5822  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.5823 -#: ../en/ch06-collab.xml:650
 37.5824 +#: ../en/ch05-collab.xml:651
 37.5825  msgid "Using an authentication agent"
 37.5826  msgstr "使用认证代理"
 37.5827  
 37.5828  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5829 -#: ../en/ch06-collab.xml:652
 37.5830 +#: ../en/ch05-collab.xml:653
 37.5831  msgid ""
 37.5832  "An authentication agent is a daemon that stores passphrases in memory (so it "
 37.5833  "will forget passphrases if you log out and log back in again). An ssh client "
 37.5834 @@ -6617,7 +5694,7 @@
 37.5835  msgstr ""
 37.5836  
 37.5837  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5838 -#: ../en/ch06-collab.xml:661
 37.5839 +#: ../en/ch05-collab.xml:662
 37.5840  msgid ""
 37.5841  "The downside of storing passphrases in an agent is that it's possible for a "
 37.5842  "well-prepared attacker to recover the plain text of your passphrases, in some "
 37.5843 @@ -6627,7 +5704,7 @@
 37.5844  msgstr ""
 37.5845  
 37.5846  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5847 -#: ../en/ch06-collab.xml:668
 37.5848 +#: ../en/ch05-collab.xml:669
 37.5849  msgid ""
 37.5850  "On Unix-like systems, the agent is called <command>ssh-agent</command>, and "
 37.5851  "it's often run automatically for you when you log in.  You'll need to use the "
 37.5852 @@ -6638,12 +5715,12 @@
 37.5853  msgstr ""
 37.5854  
 37.5855  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.5856 -#: ../en/ch06-collab.xml:679
 37.5857 +#: ../en/ch05-collab.xml:680
 37.5858  msgid "Configuring the server side properly"
 37.5859  msgstr "正确配置服务器端"
 37.5860  
 37.5861  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5862 -#: ../en/ch06-collab.xml:681
 37.5863 +#: ../en/ch05-collab.xml:682
 37.5864  msgid ""
 37.5865  "Because ssh can be fiddly to set up if you're new to it, there's a variety of "
 37.5866  "things that can go wrong.  Add Mercurial on top, and there's plenty more "
 37.5867 @@ -6653,7 +5730,7 @@
 37.5868  msgstr ""
 37.5869  
 37.5870  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5871 -#: ../en/ch06-collab.xml:689
 37.5872 +#: ../en/ch05-collab.xml:690
 37.5873  msgid ""
 37.5874  "Before you try using Mercurial to talk to an ssh server, it's best to make "
 37.5875  "sure that you can use the normal <command>ssh</command> or <command>putty</"
 37.5876 @@ -6666,7 +5743,7 @@
 37.5877  msgstr ""
 37.5878  
 37.5879  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5880 -#: ../en/ch06-collab.xml:700
 37.5881 +#: ../en/ch05-collab.xml:701
 37.5882  msgid ""
 37.5883  "The first thing to be sure of on the server side is that you can actually log "
 37.5884  "in from another machine at all.  If you can't use <command>ssh</command> or "
 37.5885 @@ -6675,7 +5752,7 @@
 37.5886  msgstr ""
 37.5887  
 37.5888  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.5889 -#: ../en/ch06-collab.xml:707
 37.5890 +#: ../en/ch05-collab.xml:708
 37.5891  msgid ""
 37.5892  "If you get a <quote>connection refused</quote> error, either there isn't an "
 37.5893  "SSH daemon running on the server at all, or it's inaccessible due to firewall "
 37.5894 @@ -6683,7 +5760,7 @@
 37.5895  msgstr ""
 37.5896  
 37.5897  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.5898 -#: ../en/ch06-collab.xml:712
 37.5899 +#: ../en/ch05-collab.xml:713
 37.5900  msgid ""
 37.5901  "If you get a <quote>no route to host</quote> error, you either have an "
 37.5902  "incorrect address for the server or a seriously locked down firewall that "
 37.5903 @@ -6691,7 +5768,7 @@
 37.5904  msgstr ""
 37.5905  
 37.5906  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.5907 -#: ../en/ch06-collab.xml:717
 37.5908 +#: ../en/ch05-collab.xml:718
 37.5909  msgid ""
 37.5910  "If you get a <quote>permission denied</quote> error, you may have mistyped "
 37.5911  "the username on the server, or you could have mistyped your key's passphrase "
 37.5912 @@ -6699,7 +5776,7 @@
 37.5913  msgstr ""
 37.5914  
 37.5915  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5916 -#: ../en/ch06-collab.xml:722
 37.5917 +#: ../en/ch05-collab.xml:723
 37.5918  msgid ""
 37.5919  "In summary, if you're having trouble talking to the server's ssh daemon, "
 37.5920  "first make sure that one is running at all.  On many systems it will be "
 37.5921 @@ -6711,7 +5788,7 @@
 37.5922  msgstr ""
 37.5923  
 37.5924  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5925 -#: ../en/ch06-collab.xml:732
 37.5926 +#: ../en/ch05-collab.xml:733
 37.5927  msgid ""
 37.5928  "If you're using an authentication agent on the client side to store "
 37.5929  "passphrases for your keys, you ought to be able to log into the server "
 37.5930 @@ -6720,26 +5797,26 @@
 37.5931  msgstr ""
 37.5932  
 37.5933  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.5934 -#: ../en/ch06-collab.xml:738
 37.5935 +#: ../en/ch05-collab.xml:739
 37.5936  msgid ""
 37.5937  "You might have forgotten to use <command>ssh-add</command> or "
 37.5938  "<command>pageant</command> to store the passphrase."
 37.5939  msgstr ""
 37.5940  
 37.5941  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.5942 -#: ../en/ch06-collab.xml:742
 37.5943 +#: ../en/ch05-collab.xml:743
 37.5944  msgid "You might have stored the passphrase for the wrong key."
 37.5945  msgstr ""
 37.5946  
 37.5947  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5948 -#: ../en/ch06-collab.xml:745
 37.5949 +#: ../en/ch05-collab.xml:746
 37.5950  msgid ""
 37.5951  "If you're being prompted for the remote user's password, there are another "
 37.5952  "few possible problems to check."
 37.5953  msgstr ""
 37.5954  
 37.5955  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.5956 -#: ../en/ch06-collab.xml:748
 37.5957 +#: ../en/ch05-collab.xml:749
 37.5958  msgid ""
 37.5959  "Either the user's home directory or their <filename role=\"special\" class="
 37.5960  "\"directory\">.ssh</filename> directory might have excessively liberal "
 37.5961 @@ -6750,7 +5827,7 @@
 37.5962  msgstr ""
 37.5963  
 37.5964  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.5965 -#: ../en/ch06-collab.xml:757
 37.5966 +#: ../en/ch05-collab.xml:758
 37.5967  msgid ""
 37.5968  "The user's <filename role=\"special\">authorized_keys</filename> file may "
 37.5969  "have a problem. If anyone other than the user owns or can write to that file, "
 37.5970 @@ -6758,7 +5835,7 @@
 37.5971  msgstr ""
 37.5972  
 37.5973  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5974 -#: ../en/ch06-collab.xml:764
 37.5975 +#: ../en/ch05-collab.xml:765
 37.5976  msgid ""
 37.5977  "In the ideal world, you should be able to run the following command "
 37.5978  "successfully, and it should print exactly one line of output, the current "
 37.5979 @@ -6766,7 +5843,7 @@
 37.5980  msgstr ""
 37.5981  
 37.5982  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5983 -#: ../en/ch06-collab.xml:769
 37.5984 +#: ../en/ch05-collab.xml:770
 37.5985  msgid ""
 37.5986  "If, on your server, you have login scripts that print banners or other junk "
 37.5987  "even when running non-interactive commands like this, you should fix them "
 37.5988 @@ -6781,7 +5858,7 @@
 37.5989  msgstr ""
 37.5990  
 37.5991  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.5992 -#: ../en/ch06-collab.xml:783
 37.5993 +#: ../en/ch05-collab.xml:784
 37.5994  msgid ""
 37.5995  "Once you've verified that plain old ssh is working with your server, the next "
 37.5996  "step is to ensure that Mercurial runs on the server.  The following command "
 37.5997 @@ -6789,7 +5866,7 @@
 37.5998  msgstr ""
 37.5999  
 37.6000  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6001 -#: ../en/ch06-collab.xml:788
 37.6002 +#: ../en/ch05-collab.xml:791
 37.6003  msgid ""
 37.6004  "If you see an error message instead of normal <command role=\"hg-cmd\">hg "
 37.6005  "version</command> output, this is usually because you haven't installed "
 37.6006 @@ -6799,21 +5876,21 @@
 37.6007  msgstr ""
 37.6008  
 37.6009  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.6010 -#: ../en/ch06-collab.xml:795
 37.6011 +#: ../en/ch05-collab.xml:798
 37.6012  msgid ""
 37.6013  "Is Mercurial really installed on the server at all? I know this sounds "
 37.6014  "trivial, but it's worth checking!"
 37.6015  msgstr ""
 37.6016  
 37.6017  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.6018 -#: ../en/ch06-collab.xml:799
 37.6019 +#: ../en/ch05-collab.xml:802
 37.6020  msgid ""
 37.6021  "Maybe your shell's search path (usually set via the <envar>PATH</envar> "
 37.6022  "environment variable) is simply misconfigured."
 37.6023  msgstr ""
 37.6024  
 37.6025  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.6026 -#: ../en/ch06-collab.xml:803
 37.6027 +#: ../en/ch05-collab.xml:806
 37.6028  msgid ""
 37.6029  "Perhaps your <envar>PATH</envar> environment variable is only being set to "
 37.6030  "point to the location of the <command>hg</command> executable if the login "
 37.6031 @@ -6822,7 +5899,7 @@
 37.6032  msgstr ""
 37.6033  
 37.6034  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.6035 -#: ../en/ch06-collab.xml:810
 37.6036 +#: ../en/ch05-collab.xml:813
 37.6037  msgid ""
 37.6038  "The <envar>PYTHONPATH</envar> environment variable may need to contain the "
 37.6039  "path to the Mercurial Python modules.  It might not be set at all; it could "
 37.6040 @@ -6830,7 +5907,7 @@
 37.6041  msgstr ""
 37.6042  
 37.6043  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6044 -#: ../en/ch06-collab.xml:817
 37.6045 +#: ../en/ch05-collab.xml:820
 37.6046  msgid ""
 37.6047  "If you can run <command role=\"hg-cmd\">hg version</command> over an ssh "
 37.6048  "connection, well done! You've got the server and client sorted out.  You "
 37.6049 @@ -6841,12 +5918,12 @@
 37.6050  msgstr ""
 37.6051  
 37.6052  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.6053 -#: ../en/ch06-collab.xml:827
 37.6054 +#: ../en/ch05-collab.xml:830
 37.6055  msgid "Using compression with ssh"
 37.6056  msgstr "通过 ssh 使用压缩"
 37.6057  
 37.6058  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6059 -#: ../en/ch06-collab.xml:829
 37.6060 +#: ../en/ch05-collab.xml:832
 37.6061  msgid ""
 37.6062  "Mercurial does not compress data when it uses the ssh protocol, because the "
 37.6063  "ssh protocol can transparently compress data.  However, the default behaviour "
 37.6064 @@ -6854,7 +5931,7 @@
 37.6065  msgstr ""
 37.6066  
 37.6067  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6068 -#: ../en/ch06-collab.xml:834
 37.6069 +#: ../en/ch05-collab.xml:837
 37.6070  msgid ""
 37.6071  "Over any network other than a fast LAN (even a wireless network), using "
 37.6072  "compression is likely to significantly speed up Mercurial's network "
 37.6073 @@ -6864,16 +5941,16 @@
 37.6074  msgstr ""
 37.6075  
 37.6076  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6077 -#: ../en/ch06-collab.xml:841
 37.6078 +#: ../en/ch05-collab.xml:844
 37.6079  msgid ""
 37.6080  "Both <command>ssh</command> and <command>plink</command> accept a <option "
 37.6081  "role=\"cmd-opt-ssh\">-C</option> option which turns on compression.  You can "
 37.6082 -"easily edit your <filename role=\"special\"> /.hgrc</filename>\\ to enable "
 37.6083 +"easily edit your <filename role=\"special\">~/.hgrc</filename> to enable "
 37.6084  "compression for all of Mercurial's uses of the ssh protocol."
 37.6085  msgstr ""
 37.6086  
 37.6087  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6088 -#: ../en/ch06-collab.xml:848
 37.6089 +#: ../en/ch05-collab.xml:852
 37.6090  msgid ""
 37.6091  "If you use <command>ssh</command>, you can configure it to always use "
 37.6092  "compression when talking to your server.  To do this, edit your <filename "
 37.6093 @@ -6882,7 +5959,7 @@
 37.6094  msgstr ""
 37.6095  
 37.6096  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6097 -#: ../en/ch06-collab.xml:855
 37.6098 +#: ../en/ch05-collab.xml:860
 37.6099  msgid ""
 37.6100  "This defines an alias, <literal>hg</literal>.  When you use it on the "
 37.6101  "<command>ssh</command> command line or in a Mercurial <literal>ssh</literal>-"
 37.6102 @@ -6892,19 +5969,19 @@
 37.6103  msgstr ""
 37.6104  
 37.6105  #. type: Content of: <book><chapter><sect1><title>
 37.6106 -#: ../en/ch06-collab.xml:866
 37.6107 +#: ../en/ch05-collab.xml:871
 37.6108  msgid "Serving over HTTP using CGI"
 37.6109  msgstr "使用 CGI 通过 HTTP 提供服务"
 37.6110  
 37.6111  #. type: Content of: <book><chapter><sect1><para>
 37.6112 -#: ../en/ch06-collab.xml:868
 37.6113 +#: ../en/ch05-collab.xml:873
 37.6114  msgid ""
 37.6115  "Depending on how ambitious you are, configuring Mercurial's CGI interface can "
 37.6116  "take anything from a few moments to several hours."
 37.6117  msgstr ""
 37.6118  
 37.6119  #. type: Content of: <book><chapter><sect1><para>
 37.6120 -#: ../en/ch06-collab.xml:872
 37.6121 +#: ../en/ch05-collab.xml:877
 37.6122  msgid ""
 37.6123  "We'll begin with the simplest of examples, and work our way towards a more "
 37.6124  "complex configuration.  Even for the most basic case, you're almost certainly "
 37.6125 @@ -6912,7 +5989,7 @@
 37.6126  msgstr ""
 37.6127  
 37.6128  #. type: Content of: <book><chapter><sect1><note><para>
 37.6129 -#: ../en/ch06-collab.xml:878
 37.6130 +#: ../en/ch05-collab.xml:883
 37.6131  msgid ""
 37.6132  "Configuring a web server is a complex, fiddly, and highly system-dependent "
 37.6133  "activity.  I can't possibly give you instructions that will cover anything "
 37.6134 @@ -6922,33 +5999,33 @@
 37.6135  msgstr ""
 37.6136  
 37.6137  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.6138 -#: ../en/ch06-collab.xml:888
 37.6139 +#: ../en/ch05-collab.xml:893
 37.6140  msgid "Web server configuration checklist"
 37.6141  msgstr "Web 服务器配置检查表"
 37.6142  
 37.6143  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6144 -#: ../en/ch06-collab.xml:890
 37.6145 +#: ../en/ch05-collab.xml:895
 37.6146  msgid ""
 37.6147  "Before you continue, do take a few moments to check a few aspects of your "
 37.6148  "system's setup."
 37.6149  msgstr ""
 37.6150  
 37.6151  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.6152 -#: ../en/ch06-collab.xml:894
 37.6153 +#: ../en/ch05-collab.xml:899
 37.6154  msgid ""
 37.6155  "Do you have a web server installed at all? Mac OS X ships with Apache, but "
 37.6156  "many other systems may not have a web server installed."
 37.6157  msgstr ""
 37.6158  
 37.6159  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.6160 -#: ../en/ch06-collab.xml:898
 37.6161 +#: ../en/ch05-collab.xml:903
 37.6162  msgid ""
 37.6163  "If you have a web server installed, is it actually running? On most systems, "
 37.6164  "even if one is present, it will be disabled by default."
 37.6165  msgstr ""
 37.6166  
 37.6167  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.6168 -#: ../en/ch06-collab.xml:902
 37.6169 +#: ../en/ch05-collab.xml:907
 37.6170  msgid ""
 37.6171  "Is your server configured to allow you to run CGI programs in the directory "
 37.6172  "where you plan to do so? Most servers default to explicitly disabling the "
 37.6173 @@ -6956,7 +6033,7 @@
 37.6174  msgstr ""
 37.6175  
 37.6176  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6177 -#: ../en/ch06-collab.xml:908
 37.6178 +#: ../en/ch05-collab.xml:913
 37.6179  msgid ""
 37.6180  "If you don't have a web server installed, and don't have substantial "
 37.6181  "experience configuring Apache, you should consider using the "
 37.6182 @@ -6969,22 +6046,22 @@
 37.6183  msgstr ""
 37.6184  
 37.6185  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.6186 -#: ../en/ch06-collab.xml:921
 37.6187 +#: ../en/ch05-collab.xml:926
 37.6188  msgid "Basic CGI configuration"
 37.6189  msgstr "基本 CGI 配置"
 37.6190  
 37.6191  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6192 -#: ../en/ch06-collab.xml:923
 37.6193 +#: ../en/ch05-collab.xml:928
 37.6194  msgid ""
 37.6195  "On Unix-like systems, it's common for users to have a subdirectory named "
 37.6196  "something like <filename class=\"directory\">public_html</filename> in their "
 37.6197  "home directory, from which they can serve up web pages.  A file named "
 37.6198  "<filename>foo</filename> in this directory will be accessible at a URL of the "
 37.6199 -"form <literal>http://www.example.com/\\ {</literal>username/foo}."
 37.6200 -msgstr ""
 37.6201 -
 37.6202 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.6203 -#: ../en/ch06-collab.xml:932
 37.6204 +"form <literal>http://www.example.com/username/foo</literal>."
 37.6205 +msgstr ""
 37.6206 +
 37.6207 +#. type: Content of: <book><chapter><sect1><sect2><para>
 37.6208 +#: ../en/ch05-collab.xml:936
 37.6209  msgid ""
 37.6210  "To get started, find the <filename role=\"special\">hgweb.cgi</filename> "
 37.6211  "script that should be present in your Mercurial installation.  If you can't "
 37.6212 @@ -6994,14 +6071,14 @@
 37.6213  msgstr ""
 37.6214  
 37.6215  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6216 -#: ../en/ch06-collab.xml:939 ../en/ch06-collab.xml:1112
 37.6217 +#: ../en/ch05-collab.xml:943 ../en/ch05-collab.xml:1112
 37.6218  msgid ""
 37.6219  "You'll need to copy this script into your <filename class=\"directory"
 37.6220  "\">public_html</filename> directory, and ensure that it's executable."
 37.6221  msgstr ""
 37.6222  
 37.6223  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6224 -#: ../en/ch06-collab.xml:944
 37.6225 +#: ../en/ch05-collab.xml:948
 37.6226  msgid ""
 37.6227  "The <literal>755</literal> argument to <command>chmod</command> is a little "
 37.6228  "more general than just making the script executable: it ensures that the "
 37.6229 @@ -7014,12 +6091,12 @@
 37.6230  msgstr ""
 37.6231  
 37.6232  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
 37.6233 -#: ../en/ch06-collab.xml:958
 37.6234 +#: ../en/ch05-collab.xml:962
 37.6235  msgid "What could <emphasis>possibly</emphasis> go wrong?"
 37.6236  msgstr "什么<emphasis>可能</emphasis>会出错?"
 37.6237  
 37.6238  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.6239 -#: ../en/ch06-collab.xml:961
 37.6240 +#: ../en/ch05-collab.xml:965
 37.6241  msgid ""
 37.6242  "Once you've copied the CGI script into place, go into a web browser, and try "
 37.6243  "to open the URL <ulink url=\"http://myhostname/ myuser/hgweb.cgi\">http://"
 37.6244 @@ -7033,7 +6110,7 @@
 37.6245  msgstr ""
 37.6246  
 37.6247  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.6248 -#: ../en/ch06-collab.xml:975
 37.6249 +#: ../en/ch05-collab.xml:979
 37.6250  msgid ""
 37.6251  "Your web server may have per-user directories disabled.  If you're using "
 37.6252  "Apache, search your config file for a <literal>UserDir</literal> directive.  "
 37.6253 @@ -7046,7 +6123,7 @@
 37.6254  msgstr ""
 37.6255  
 37.6256  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.6257 -#: ../en/ch06-collab.xml:986
 37.6258 +#: ../en/ch05-collab.xml:990
 37.6259  msgid ""
 37.6260  "Your file access permissions may be too restrictive.  The web server must be "
 37.6261  "able to traverse your home directory and directories under your <filename "
 37.6262 @@ -7056,7 +6133,7 @@
 37.6263  msgstr ""
 37.6264  
 37.6265  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.6266 -#: ../en/ch06-collab.xml:996
 37.6267 +#: ../en/ch05-collab.xml:1000
 37.6268  msgid ""
 37.6269  "The other possibility with permissions is that you might get a completely "
 37.6270  "empty window when you try to load the script.  In this case, it's likely that "
 37.6271 @@ -7066,15 +6143,21 @@
 37.6272  msgstr ""
 37.6273  
 37.6274  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.6275 -#: ../en/ch06-collab.xml:1003
 37.6276 +#: ../en/ch05-collab.xml:1007
 37.6277  msgid ""
 37.6278  "Your web server may be configured to disallow execution of CGI programs in "
 37.6279  "your per-user web directory.  Here's Apache's default per-user configuration "
 37.6280  "from my Fedora system."
 37.6281  msgstr ""
 37.6282  
 37.6283 +#. type: CDATA
 37.6284 +#: ../en/ch05-collab.xml:1012
 37.6285 +#, no-wrap
 37.6286 +msgid "&ch06-apache-config.lst;]]"
 37.6287 +msgstr ""
 37.6288 +
 37.6289  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.6290 -#: ../en/ch06-collab.xml:1014
 37.6291 +#: ../en/ch05-collab.xml:1014
 37.6292  msgid ""
 37.6293  "If you find a similar-looking <literal>Directory</literal> group in your "
 37.6294  "Apache configuration, the directive to look at inside it is <literal>Options</"
 37.6295 @@ -7083,7 +6166,7 @@
 37.6296  msgstr ""
 37.6297  
 37.6298  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.6299 -#: ../en/ch06-collab.xml:1021
 37.6300 +#: ../en/ch05-collab.xml:1021
 37.6301  msgid ""
 37.6302  "If you find that Apache serves you the text of the CGI script instead of "
 37.6303  "executing it, you may need to either uncomment (if already present) or add a "
 37.6304 @@ -7091,7 +6174,7 @@
 37.6305  msgstr ""
 37.6306  
 37.6307  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.6308 -#: ../en/ch06-collab.xml:1027
 37.6309 +#: ../en/ch05-collab.xml:1027
 37.6310  msgid ""
 37.6311  "The next possibility is that you might be served with a colourful Python "
 37.6312  "backtrace claiming that it can't import a <literal>mercurial</literal>-"
 37.6313 @@ -7106,7 +6189,7 @@
 37.6314  msgstr ""
 37.6315  
 37.6316  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.6317 -#: ../en/ch06-collab.xml:1041
 37.6318 +#: ../en/ch05-collab.xml:1041
 37.6319  msgid ""
 37.6320  "Finally, you are <emphasis>certain</emphasis> to by served with another "
 37.6321  "colourful Python backtrace: this one will complain that it can't find "
 37.6322 @@ -7117,19 +6200,19 @@
 37.6323  msgstr ""
 37.6324  
 37.6325  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.6326 -#: ../en/ch06-collab.xml:1051
 37.6327 +#: ../en/ch05-collab.xml:1051
 37.6328  msgid ""
 37.6329  "At this point, when you try to reload the page, you should be presented with "
 37.6330  "a nice HTML view of your repository's history.  Whew!"
 37.6331  msgstr ""
 37.6332  
 37.6333  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
 37.6334 -#: ../en/ch06-collab.xml:1057
 37.6335 +#: ../en/ch05-collab.xml:1057
 37.6336  msgid "Configuring lighttpd"
 37.6337  msgstr "配置 lighttpd"
 37.6338  
 37.6339  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.6340 -#: ../en/ch06-collab.xml:1059
 37.6341 +#: ../en/ch05-collab.xml:1059
 37.6342  msgid ""
 37.6343  "To be exhaustive in my experiments, I tried configuring the increasingly "
 37.6344  "popular <literal>lighttpd</literal> web server to serve the same repository "
 37.6345 @@ -7140,7 +6223,7 @@
 37.6346  msgstr ""
 37.6347  
 37.6348  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.6349 -#: ../en/ch06-collab.xml:1069
 37.6350 +#: ../en/ch05-collab.xml:1069
 37.6351  msgid ""
 37.6352  "Once I had Apache running, getting <literal>lighttpd</literal> to serve the "
 37.6353  "repository was a snap (in other words, even if you're trying to use "
 37.6354 @@ -7152,7 +6235,7 @@
 37.6355  msgstr ""
 37.6356  
 37.6357  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.6358 -#: ../en/ch06-collab.xml:1081
 37.6359 +#: ../en/ch05-collab.xml:1081
 37.6360  msgid ""
 37.6361  "With this done, <literal>lighttpd</literal> ran immediately for me.  If I had "
 37.6362  "configured <literal>lighttpd</literal> before Apache, I'd almost certainly "
 37.6363 @@ -7163,12 +6246,12 @@
 37.6364  msgstr ""
 37.6365  
 37.6366  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.6367 -#: ../en/ch06-collab.xml:1094
 37.6368 +#: ../en/ch05-collab.xml:1094
 37.6369  msgid "Sharing multiple repositories with one CGI script"
 37.6370  msgstr "使用一个 CGI 脚本共享多个版本库"
 37.6371  
 37.6372  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6373 -#: ../en/ch06-collab.xml:1096
 37.6374 +#: ../en/ch05-collab.xml:1096
 37.6375  msgid ""
 37.6376  "The <filename role=\"special\">hgweb.cgi</filename> script only lets you "
 37.6377  "publish a single repository, which is an annoying restriction.  If you want "
 37.6378 @@ -7178,7 +6261,7 @@
 37.6379  msgstr ""
 37.6380  
 37.6381  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6382 -#: ../en/ch06-collab.xml:1104
 37.6383 +#: ../en/ch05-collab.xml:1104
 37.6384  msgid ""
 37.6385  "The procedure to configure <filename role=\"special\">hgwebdir.cgi</filename> "
 37.6386  "is only a little more involved than for <filename role=\"special\">hgweb.cgi</"
 37.6387 @@ -7189,7 +6272,7 @@
 37.6388  msgstr ""
 37.6389  
 37.6390  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6391 -#: ../en/ch06-collab.xml:1117
 37.6392 +#: ../en/ch05-collab.xml:1117
 37.6393  msgid ""
 37.6394  "With basic configuration out of the way, try to visit <ulink url=\"http://"
 37.6395  "myhostname/ myuser/hgwebdir.cgi\">http://myhostname/ myuser/hgwebdir.cgi</"
 37.6396 @@ -7199,7 +6282,7 @@
 37.6397  msgstr ""
 37.6398  
 37.6399  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6400 -#: ../en/ch06-collab.xml:1126
 37.6401 +#: ../en/ch05-collab.xml:1126
 37.6402  msgid ""
 37.6403  "The <filename role=\"special\">hgwebdir.cgi</filename> script relies on an "
 37.6404  "external configuration file.  By default, it searches for a file named "
 37.6405 @@ -7211,7 +6294,7 @@
 37.6406  msgstr ""
 37.6407  
 37.6408  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6409 -#: ../en/ch06-collab.xml:1136
 37.6410 +#: ../en/ch05-collab.xml:1136
 37.6411  msgid ""
 37.6412  "The easiest way to configure <filename role=\"special\">hgwebdir.cgi</"
 37.6413  "filename> is with a section named <literal>collections</literal>.  This will "
 37.6414 @@ -7220,7 +6303,7 @@
 37.6415  msgstr ""
 37.6416  
 37.6417  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6418 -#: ../en/ch06-collab.xml:1144
 37.6419 +#: ../en/ch05-collab.xml:1144
 37.6420  msgid ""
 37.6421  "Mercurial interprets this by looking at the directory name on the "
 37.6422  "<emphasis>right</emphasis> hand side of the <quote><literal>=</literal></"
 37.6423 @@ -7232,7 +6315,7 @@
 37.6424  msgstr ""
 37.6425  
 37.6426  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6427 -#: ../en/ch06-collab.xml:1153
 37.6428 +#: ../en/ch05-collab.xml:1153
 37.6429  msgid ""
 37.6430  "Given the example above, if we have a repository whose local path is "
 37.6431  "<filename class=\"directory\">/my/root/this/repo</filename>, the CGI script "
 37.6432 @@ -7246,7 +6329,7 @@
 37.6433  msgstr ""
 37.6434  
 37.6435  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6436 -#: ../en/ch06-collab.xml:1167
 37.6437 +#: ../en/ch05-collab.xml:1167
 37.6438  msgid ""
 37.6439  "If we replace <filename class=\"directory\">/my/root</filename> on the left "
 37.6440  "hand side of this example with <filename class=\"directory\">/my</filename>, "
 37.6441 @@ -7257,7 +6340,7 @@
 37.6442  msgstr ""
 37.6443  
 37.6444  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6445 -#: ../en/ch06-collab.xml:1177
 37.6446 +#: ../en/ch05-collab.xml:1177
 37.6447  msgid ""
 37.6448  "The <filename role=\"special\">hgwebdir.cgi</filename> script will "
 37.6449  "recursively search each directory listed in the <literal>collections</"
 37.6450 @@ -7266,7 +6349,7 @@
 37.6451  msgstr ""
 37.6452  
 37.6453  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6454 -#: ../en/ch06-collab.xml:1183
 37.6455 +#: ../en/ch05-collab.xml:1183
 37.6456  msgid ""
 37.6457  "The <literal>collections</literal> mechanism makes it easy to publish many "
 37.6458  "repositories in a <quote>fire and forget</quote> manner.  You only need to "
 37.6459 @@ -7277,12 +6360,12 @@
 37.6460  msgstr ""
 37.6461  
 37.6462  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
 37.6463 -#: ../en/ch06-collab.xml:1193
 37.6464 +#: ../en/ch05-collab.xml:1193
 37.6465  msgid "Explicitly specifying which repositories to publish"
 37.6466  msgstr "明确指出要发布的版本库"
 37.6467  
 37.6468  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.6469 -#: ../en/ch06-collab.xml:1196
 37.6470 +#: ../en/ch05-collab.xml:1196
 37.6471  msgid ""
 37.6472  "In addition to the <literal>collections</literal> mechanism, the <filename "
 37.6473  "role=\"special\">hgwebdir.cgi</filename> script allows you to publish a "
 37.6474 @@ -7291,7 +6374,7 @@
 37.6475  msgstr ""
 37.6476  
 37.6477  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.6478 -#: ../en/ch06-collab.xml:1204
 37.6479 +#: ../en/ch05-collab.xml:1205
 37.6480  msgid ""
 37.6481  "In this case, the virtual path (the component that will appear in a URL) is "
 37.6482  "on the left hand side of each definition, while the path to the repository is "
 37.6483 @@ -7301,7 +6384,7 @@
 37.6484  msgstr ""
 37.6485  
 37.6486  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.6487 -#: ../en/ch06-collab.xml:1211
 37.6488 +#: ../en/ch05-collab.xml:1212
 37.6489  msgid ""
 37.6490  "If you wish, you can use both the <literal>collections</literal> and "
 37.6491  "<literal>paths</literal> mechanisms simultaneously in a single configuration "
 37.6492 @@ -7309,7 +6392,7 @@
 37.6493  msgstr ""
 37.6494  
 37.6495  #. type: Content of: <book><chapter><sect1><sect2><sect3><note><para>
 37.6496 -#: ../en/ch06-collab.xml:1217
 37.6497 +#: ../en/ch05-collab.xml:1218
 37.6498  msgid ""
 37.6499  "If multiple repositories have the same virtual path, <filename role=\"special"
 37.6500  "\">hgwebdir.cgi</filename> will not report an error.  Instead, it will behave "
 37.6501 @@ -7317,12 +6400,12 @@
 37.6502  msgstr ""
 37.6503  
 37.6504  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.6505 -#: ../en/ch06-collab.xml:1226
 37.6506 +#: ../en/ch05-collab.xml:1227
 37.6507  msgid "Downloading source archives"
 37.6508  msgstr "下载源代码档案包"
 37.6509  
 37.6510  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6511 -#: ../en/ch06-collab.xml:1228
 37.6512 +#: ../en/ch05-collab.xml:1229
 37.6513  msgid ""
 37.6514  "Mercurial's web interface lets users download an archive of any revision.  "
 37.6515  "This archive will contain a snapshot of the working directory as of that "
 37.6516 @@ -7330,21 +6413,21 @@
 37.6517  msgstr ""
 37.6518  
 37.6519  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6520 -#: ../en/ch06-collab.xml:1233
 37.6521 +#: ../en/ch05-collab.xml:1234
 37.6522  msgid ""
 37.6523  "By default, this feature is not enabled.  To enable it, you'll need to add an "
 37.6524  "<envar role=\"rc-item-web\">allow_archive</envar> item to the <literal role="
 37.6525 -"\"rc-web\">web</literal> section of your <filename role=\"special\"> /.hgrc</"
 37.6526 +"\"rc-web\">web</literal> section of your <filename role=\"special\">~/.hgrc</"
 37.6527  "filename>."
 37.6528  msgstr ""
 37.6529  
 37.6530  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.6531 -#: ../en/ch06-collab.xml:1241
 37.6532 +#: ../en/ch05-collab.xml:1242
 37.6533  msgid "Web configuration options"
 37.6534  msgstr "Web 配置选项"
 37.6535  
 37.6536  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6537 -#: ../en/ch06-collab.xml:1243
 37.6538 +#: ../en/ch05-collab.xml:1244
 37.6539  msgid ""
 37.6540  "Mercurial's web interfaces (the <command role=\"hg-cmd\">hg serve</command> "
 37.6541  "command, and the <filename role=\"special\">hgweb.cgi</filename> and "
 37.6542 @@ -7354,7 +6437,7 @@
 37.6543  msgstr ""
 37.6544  
 37.6545  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.6546 -#: ../en/ch06-collab.xml:1251
 37.6547 +#: ../en/ch05-collab.xml:1252
 37.6548  msgid ""
 37.6549  "<envar role=\"rc-item-web\">allow_archive</envar>: Determines which (if any) "
 37.6550  "archive download mechanisms Mercurial supports.  If you enable this feature, "
 37.6551 @@ -7364,7 +6447,7 @@
 37.6552  msgstr ""
 37.6553  
 37.6554  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><itemizedlist><listitem><para>
 37.6555 -#: ../en/ch06-collab.xml:1260
 37.6556 +#: ../en/ch05-collab.xml:1261
 37.6557  msgid ""
 37.6558  "<literal>bz2</literal>: A <command>tar</command> archive, compressed using "
 37.6559  "<literal>bzip2</literal> compression.  This has the best compression ratio, "
 37.6560 @@ -7372,14 +6455,14 @@
 37.6561  msgstr ""
 37.6562  
 37.6563  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><itemizedlist><listitem><para>
 37.6564 -#: ../en/ch06-collab.xml:1266
 37.6565 +#: ../en/ch05-collab.xml:1267
 37.6566  msgid ""
 37.6567  "<literal>gz</literal>: A <command>tar</command> archive, compressed using "
 37.6568  "<literal>gzip</literal> compression."
 37.6569  msgstr ""
 37.6570  
 37.6571  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><itemizedlist><listitem><para>
 37.6572 -#: ../en/ch06-collab.xml:1270
 37.6573 +#: ../en/ch05-collab.xml:1271
 37.6574  msgid ""
 37.6575  "<literal>zip</literal>: A <command>zip</command> archive, compressed using "
 37.6576  "LZW compression.  This format has the worst compression ratio, but is widely "
 37.6577 @@ -7387,7 +6470,7 @@
 37.6578  msgstr ""
 37.6579  
 37.6580  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.6581 -#: ../en/ch06-collab.xml:1276
 37.6582 +#: ../en/ch05-collab.xml:1277
 37.6583  msgid ""
 37.6584  "If you provide an empty list, or don't have an <envar role=\"rc-item-web"
 37.6585  "\">allow_archive</envar> entry at all, this feature will be disabled.  Here "
 37.6586 @@ -7395,7 +6478,7 @@
 37.6587  msgstr ""
 37.6588  
 37.6589  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.6590 -#: ../en/ch06-collab.xml:1283
 37.6591 +#: ../en/ch05-collab.xml:1284
 37.6592  msgid ""
 37.6593  "<envar role=\"rc-item-web\">allowpull</envar>: Boolean.  Determines whether "
 37.6594  "the web interface allows remote users to <command role=\"hg-cmd\">hg pull</"
 37.6595 @@ -7405,33 +6488,33 @@
 37.6596  msgstr ""
 37.6597  
 37.6598  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.6599 -#: ../en/ch06-collab.xml:1292
 37.6600 +#: ../en/ch05-collab.xml:1293
 37.6601  msgid ""
 37.6602  "<envar role=\"rc-item-web\">contact</envar>: String.  A free-form (but "
 37.6603  "preferably brief) string identifying the person or group in charge of the "
 37.6604  "repository.  This often contains the name and email address of a person or "
 37.6605  "mailing list.  It often makes sense to place this entry in a repository's own "
 37.6606  "<filename role=\"special\">.hg/hgrc</filename> file, but it can make sense to "
 37.6607 -"use in a global <filename role=\"special\"> /.hgrc</filename>\\ if every "
 37.6608 +"use in a global <filename role=\"special\">~/.hgrc</filename> if every "
 37.6609  "repository has a single maintainer."
 37.6610  msgstr ""
 37.6611  
 37.6612  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.6613 -#: ../en/ch06-collab.xml:1303
 37.6614 +#: ../en/ch05-collab.xml:1304
 37.6615  msgid ""
 37.6616  "<envar role=\"rc-item-web\">maxchanges</envar>: Integer.  The default maximum "
 37.6617  "number of changesets to display in a single page of output."
 37.6618  msgstr ""
 37.6619  
 37.6620  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.6621 -#: ../en/ch06-collab.xml:1307
 37.6622 +#: ../en/ch05-collab.xml:1308
 37.6623  msgid ""
 37.6624  "<envar role=\"rc-item-web\">maxfiles</envar>: Integer.  The default maximum "
 37.6625  "number of modified files to display in a single page of output."
 37.6626  msgstr ""
 37.6627  
 37.6628  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.6629 -#: ../en/ch06-collab.xml:1311
 37.6630 +#: ../en/ch05-collab.xml:1312
 37.6631  msgid ""
 37.6632  "<envar role=\"rc-item-web\">stripes</envar>: Integer.  If the web interface "
 37.6633  "displays alternating <quote>stripes</quote> to make it easier to visually "
 37.6634 @@ -7440,7 +6523,7 @@
 37.6635  msgstr ""
 37.6636  
 37.6637  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.6638 -#: ../en/ch06-collab.xml:1317
 37.6639 +#: ../en/ch05-collab.xml:1318
 37.6640  msgid ""
 37.6641  "<envar role=\"rc-item-web\">style</envar>: Controls the template Mercurial "
 37.6642  "uses to display the web interface.  Mercurial ships with two web templates, "
 37.6643 @@ -7451,7 +6534,7 @@
 37.6644  msgstr ""
 37.6645  
 37.6646  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.6647 -#: ../en/ch06-collab.xml:1328
 37.6648 +#: ../en/ch05-collab.xml:1330
 37.6649  msgid ""
 37.6650  "<envar role=\"rc-item-web\">templates</envar>: Path.  The directory in which "
 37.6651  "to search for template files.  By default, Mercurial searches in the "
 37.6652 @@ -7459,32 +6542,32 @@
 37.6653  msgstr ""
 37.6654  
 37.6655  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.6656 -#: ../en/ch06-collab.xml:1333
 37.6657 +#: ../en/ch05-collab.xml:1335
 37.6658  msgid ""
 37.6659  "If you are using <filename role=\"special\">hgwebdir.cgi</filename>, you can "
 37.6660  "place a few configuration items in a <literal role=\"rc-web\">web</literal> "
 37.6661  "section of the <filename role=\"special\">hgweb.config</filename> file "
 37.6662 -"instead of a <filename role=\"special\"> /.hgrc</filename>\\ file, for "
 37.6663 +"instead of a <filename role=\"special\">~/.hgrc</filename> file, for "
 37.6664  "convenience.  These items are <envar role=\"rc-item-web\">motd</envar> and "
 37.6665  "<envar role=\"rc-item-web\">style</envar>."
 37.6666  msgstr ""
 37.6667  
 37.6668  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
 37.6669 -#: ../en/ch06-collab.xml:1344
 37.6670 +#: ../en/ch05-collab.xml:1346
 37.6671  msgid "Options specific to an individual repository"
 37.6672  msgstr "针对单个版本库的选项"
 37.6673  
 37.6674  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.6675 -#: ../en/ch06-collab.xml:1346
 37.6676 +#: ../en/ch05-collab.xml:1348
 37.6677  msgid ""
 37.6678  "A few <literal role=\"rc-web\">web</literal> configuration items ought to be "
 37.6679  "placed in a repository's local <filename role=\"special\">.hg/hgrc</"
 37.6680 -"filename>, rather than a user's or global <filename role=\"special\"> /.hgrc</"
 37.6681 +"filename>, rather than a user's or global <filename role=\"special\">~/.hgrc</"
 37.6682  "filename>."
 37.6683  msgstr ""
 37.6684  
 37.6685  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
 37.6686 -#: ../en/ch06-collab.xml:1352
 37.6687 +#: ../en/ch05-collab.xml:1353
 37.6688  msgid ""
 37.6689  "<envar role=\"rc-item-web\">description</envar>: String.  A free-form (but "
 37.6690  "preferably brief) string that describes the contents or purpose of the "
 37.6691 @@ -7492,7 +6575,7 @@
 37.6692  msgstr ""
 37.6693  
 37.6694  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
 37.6695 -#: ../en/ch06-collab.xml:1357
 37.6696 +#: ../en/ch05-collab.xml:1358
 37.6697  msgid ""
 37.6698  "<envar role=\"rc-item-web\">name</envar>: String.  The name to use for the "
 37.6699  "repository in the web interface.  This overrides the default name, which is "
 37.6700 @@ -7500,21 +6583,21 @@
 37.6701  msgstr ""
 37.6702  
 37.6703  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
 37.6704 -#: ../en/ch06-collab.xml:1365
 37.6705 +#: ../en/ch05-collab.xml:1366
 37.6706  msgid ""
 37.6707  "Options specific to the <command role=\"hg-cmd\">hg serve</command> command"
 37.6708  msgstr "命令 <command role=\"hg-cmd\">hg serve</command> 的选项"
 37.6709  
 37.6710  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.6711 -#: ../en/ch06-collab.xml:1368
 37.6712 +#: ../en/ch05-collab.xml:1369
 37.6713  msgid ""
 37.6714  "Some of the items in the <literal role=\"rc-web\">web</literal> section of a "
 37.6715 -"<filename role=\"special\"> /.hgrc</filename>\\ file are only for use with "
 37.6716 -"the <command role=\"hg-cmd\">hg serve</command> command."
 37.6717 +"<filename role=\"special\">~/.hgrc</filename> file are only for use with the "
 37.6718 +"<command role=\"hg-cmd\">hg serve</command> command."
 37.6719  msgstr ""
 37.6720  
 37.6721  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
 37.6722 -#: ../en/ch06-collab.xml:1374
 37.6723 +#: ../en/ch05-collab.xml:1375
 37.6724  msgid ""
 37.6725  "<envar role=\"rc-item-web\">accesslog</envar>: Path.  The name of a file into "
 37.6726  "which to write an access log.  By default, the <command role=\"hg-cmd\">hg "
 37.6727 @@ -7524,7 +6607,7 @@
 37.6728  msgstr ""
 37.6729  
 37.6730  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
 37.6731 -#: ../en/ch06-collab.xml:1382
 37.6732 +#: ../en/ch05-collab.xml:1383
 37.6733  msgid ""
 37.6734  "<envar role=\"rc-item-web\">address</envar>: String.  The local address on "
 37.6735  "which the server should listen for incoming connections.  By default, the "
 37.6736 @@ -7532,7 +6615,7 @@
 37.6737  msgstr ""
 37.6738  
 37.6739  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
 37.6740 -#: ../en/ch06-collab.xml:1387
 37.6741 +#: ../en/ch05-collab.xml:1388
 37.6742  msgid ""
 37.6743  "<envar role=\"rc-item-web\">errorlog</envar>: Path.  The name of a file into "
 37.6744  "which to write an error log.  By default, the <command role=\"hg-cmd\">hg "
 37.6745 @@ -7541,30 +6624,31 @@
 37.6746  msgstr ""
 37.6747  
 37.6748  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
 37.6749 -#: ../en/ch06-collab.xml:1393
 37.6750 +#: ../en/ch05-collab.xml:1394
 37.6751  msgid ""
 37.6752  "<envar role=\"rc-item-web\">ipv6</envar>: Boolean.  Whether to use the IPv6 "
 37.6753  "protocol. By default, IPv6 is not used."
 37.6754  msgstr ""
 37.6755  
 37.6756  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
 37.6757 -#: ../en/ch06-collab.xml:1397
 37.6758 +#: ../en/ch05-collab.xml:1398
 37.6759  msgid ""
 37.6760  "<envar role=\"rc-item-web\">port</envar>: Integer.  The TCP port number on "
 37.6761  "which the server should listen.  The default port number used is 8000."
 37.6762  msgstr ""
 37.6763  
 37.6764  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
 37.6765 -#: ../en/ch06-collab.xml:1404
 37.6766 -msgid ""
 37.6767 -"Choosing the right <filename role=\"special\"> /.hgrc</filename>\\ file to "
 37.6768 -"add <literal role=\"rc-web\">web</literal> items to"
 37.6769 +#: ../en/ch05-collab.xml:1405
 37.6770 +#, fuzzy
 37.6771 +msgid ""
 37.6772 +"Choosing the right <filename role=\"special\">~/.hgrc</filename> file to add "
 37.6773 +"<literal role=\"rc-web\">web</literal> items to"
 37.6774  msgstr ""
 37.6775  "选择正确的 <filename role=\"special\"> /.hgrc</filename> 文件增加到 <literal "
 37.6776  "role=\"rc-web\">web</literal> 条目"
 37.6777  
 37.6778  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.6779 -#: ../en/ch06-collab.xml:1408
 37.6780 +#: ../en/ch05-collab.xml:1409
 37.6781  msgid ""
 37.6782  "It is important to remember that a web server like Apache or "
 37.6783  "<literal>lighttpd</literal> will run under a user ID that is different to "
 37.6784 @@ -7573,38 +6657,37 @@
 37.6785  msgstr ""
 37.6786  
 37.6787  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.6788 -#: ../en/ch06-collab.xml:1415
 37.6789 +#: ../en/ch05-collab.xml:1416
 37.6790  msgid ""
 37.6791  "If you add <literal role=\"rc-web\">web</literal> items to your own personal "
 37.6792 -"<filename role=\"special\"> /.hgrc</filename>\\ file, CGI scripts won't read "
 37.6793 -"that <filename role=\"special\"> /.hgrc</filename>\\ file.  Those settings "
 37.6794 -"will thus only affect the behaviour of the <command role=\"hg-cmd\">hg serve</"
 37.6795 +"<filename role=\"special\">~/.hgrc</filename> file, CGI scripts won't read "
 37.6796 +"that <filename role=\"special\">~/.hgrc</filename> file.  Those settings will "
 37.6797 +"thus only affect the behaviour of the <command role=\"hg-cmd\">hg serve</"
 37.6798  "command> command when you run it.  To cause CGI scripts to see your settings, "
 37.6799 -"either create a <filename role=\"special\"> /.hgrc</filename>\\ file in the "
 37.6800 +"either create a <filename role=\"special\">~/.hgrc</filename> file in the "
 37.6801  "home directory of the user ID that runs your web server, or add those "
 37.6802 -"settings to a system-wide <filename role=\"special\"> /.hgrc</filename>\\ "
 37.6803 -"file."
 37.6804 +"settings to a system-wide <filename role=\"special\">~/.hgrc</filename> file."
 37.6805  msgstr ""
 37.6806  
 37.6807  #. type: Content of: <book><chapter><title>
 37.6808 -#: ../en/ch07-filenames.xml:5
 37.6809 +#: ../en/ch06-filenames.xml:5
 37.6810  msgid "File names and pattern matching"
 37.6811  msgstr "文件名称与模式匹配"
 37.6812  
 37.6813  #. type: Content of: <book><chapter><para>
 37.6814 -#: ../en/ch07-filenames.xml:7
 37.6815 +#: ../en/ch06-filenames.xml:7
 37.6816  msgid ""
 37.6817  "Mercurial provides mechanisms that let you work with file names in a "
 37.6818  "consistent and expressive way."
 37.6819  msgstr ""
 37.6820  
 37.6821  #. type: Content of: <book><chapter><sect1><title>
 37.6822 -#: ../en/ch07-filenames.xml:11
 37.6823 +#: ../en/ch06-filenames.xml:11
 37.6824  msgid "Simple file naming"
 37.6825  msgstr "简单文件名称"
 37.6826  
 37.6827  #. type: Content of: <book><chapter><sect1><para>
 37.6828 -#: ../en/ch07-filenames.xml:13
 37.6829 +#: ../en/ch06-filenames.xml:13
 37.6830  msgid ""
 37.6831  "Mercurial uses a unified piece of machinery <quote>under the hood</quote> to "
 37.6832  "handle file names.  Every command behaves uniformly with respect to file "
 37.6833 @@ -7612,7 +6695,7 @@
 37.6834  msgstr ""
 37.6835  
 37.6836  #. type: Content of: <book><chapter><sect1><para>
 37.6837 -#: ../en/ch07-filenames.xml:18
 37.6838 +#: ../en/ch06-filenames.xml:18
 37.6839  msgid ""
 37.6840  "If you explicitly name real files on the command line, Mercurial works with "
 37.6841  "exactly those files, as you would expect.  &interaction.filenames.files;"
 37.6842 @@ -7620,7 +6703,7 @@
 37.6843  
 37.6844  #
 37.6845  #. type: Content of: <book><chapter><sect1><para>
 37.6846 -#: ../en/ch07-filenames.xml:22
 37.6847 +#: ../en/ch06-filenames.xml:22
 37.6848  msgid ""
 37.6849  "When you provide a directory name, Mercurial will interpret this as "
 37.6850  "<quote>operate on every file in this directory and its subdirectories</"
 37.6851 @@ -7630,12 +6713,12 @@
 37.6852  msgstr ""
 37.6853  
 37.6854  #. type: Content of: <book><chapter><sect1><title>
 37.6855 -#: ../en/ch07-filenames.xml:33
 37.6856 +#: ../en/ch06-filenames.xml:33
 37.6857  msgid "Running commands without any file names"
 37.6858  msgstr "不提供文件名称的执行命令"
 37.6859  
 37.6860  #. type: Content of: <book><chapter><sect1><para>
 37.6861 -#: ../en/ch07-filenames.xml:35
 37.6862 +#: ../en/ch06-filenames.xml:35
 37.6863  msgid ""
 37.6864  "Mercurial's commands that work with file names have useful default behaviours "
 37.6865  "when you invoke them without providing any file names or patterns.  What kind "
 37.6866 @@ -7645,14 +6728,14 @@
 37.6867  msgstr ""
 37.6868  
 37.6869  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.6870 -#: ../en/ch07-filenames.xml:42
 37.6871 +#: ../en/ch06-filenames.xml:42
 37.6872  msgid ""
 37.6873  "Most commands will operate on the entire working directory. This is what the "
 37.6874  "<command role=\"hg-cmd\">hg add</command> command does, for example."
 37.6875  msgstr ""
 37.6876  
 37.6877  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.6878 -#: ../en/ch07-filenames.xml:46
 37.6879 +#: ../en/ch06-filenames.xml:46
 37.6880  msgid ""
 37.6881  "If the command has effects that are difficult or impossible to reverse, it "
 37.6882  "will force you to explicitly provide at least one name or pattern (see "
 37.6883 @@ -7662,7 +6745,7 @@
 37.6884  
 37.6885  #
 37.6886  #. type: Content of: <book><chapter><sect1><para>
 37.6887 -#: ../en/ch07-filenames.xml:54
 37.6888 +#: ../en/ch06-filenames.xml:54
 37.6889  msgid ""
 37.6890  "It's easy to work around these default behaviours if they don't suit you.  If "
 37.6891  "a command normally operates on the whole working directory, you can invoke it "
 37.6892 @@ -7672,7 +6755,7 @@
 37.6893  
 37.6894  #
 37.6895  #. type: Content of: <book><chapter><sect1><para>
 37.6896 -#: ../en/ch07-filenames.xml:62
 37.6897 +#: ../en/ch06-filenames.xml:62
 37.6898  msgid ""
 37.6899  "Along the same lines, some commands normally print file names relative to the "
 37.6900  "root of the repository, even if you're invoking them from a subdirectory.  "
 37.6901 @@ -7685,12 +6768,12 @@
 37.6902  msgstr ""
 37.6903  
 37.6904  #. type: Content of: <book><chapter><sect1><title>
 37.6905 -#: ../en/ch07-filenames.xml:76
 37.6906 +#: ../en/ch06-filenames.xml:76
 37.6907  msgid "Telling you what's going on"
 37.6908  msgstr "告诉你正在做什么"
 37.6909  
 37.6910  #. type: Content of: <book><chapter><sect1><para>
 37.6911 -#: ../en/ch07-filenames.xml:78
 37.6912 +#: ../en/ch06-filenames.xml:78
 37.6913  msgid ""
 37.6914  "The <command role=\"hg-cmd\">hg add</command> example in the preceding "
 37.6915  "section illustrates something else that's helpful about Mercurial commands.  "
 37.6916 @@ -7700,7 +6783,7 @@
 37.6917  msgstr ""
 37.6918  
 37.6919  #. type: Content of: <book><chapter><sect1><para>
 37.6920 -#: ../en/ch07-filenames.xml:85
 37.6921 +#: ../en/ch06-filenames.xml:85
 37.6922  msgid ""
 37.6923  "The principle here is of <emphasis>least surprise</emphasis>.  If you've "
 37.6924  "exactly named a file on the command line, there's no point in repeating it "
 37.6925 @@ -7710,7 +6793,7 @@
 37.6926  msgstr ""
 37.6927  
 37.6928  #. type: Content of: <book><chapter><sect1><para>
 37.6929 -#: ../en/ch07-filenames.xml:92
 37.6930 +#: ../en/ch06-filenames.xml:92
 37.6931  msgid ""
 37.6932  "For commands that behave this way, you can silence them using the <option "
 37.6933  "role=\"hg-opt-global\">-q</option> option.  You can also get them to print "
 37.6934 @@ -7719,12 +6802,12 @@
 37.6935  msgstr ""
 37.6936  
 37.6937  #. type: Content of: <book><chapter><sect1><title>
 37.6938 -#: ../en/ch07-filenames.xml:100
 37.6939 +#: ../en/ch06-filenames.xml:100
 37.6940  msgid "Using patterns to identify files"
 37.6941  msgstr "使用模式标识文件"
 37.6942  
 37.6943  #. type: Content of: <book><chapter><sect1><para>
 37.6944 -#: ../en/ch07-filenames.xml:102
 37.6945 +#: ../en/ch06-filenames.xml:102
 37.6946  msgid ""
 37.6947  "In addition to working with file and directory names, Mercurial lets you use "
 37.6948  "<emphasis>patterns</emphasis> to identify files.  Mercurial's pattern "
 37.6949 @@ -7732,7 +6815,7 @@
 37.6950  msgstr ""
 37.6951  
 37.6952  #. type: Content of: <book><chapter><sect1><para>
 37.6953 -#: ../en/ch07-filenames.xml:106
 37.6954 +#: ../en/ch06-filenames.xml:106
 37.6955  msgid ""
 37.6956  "On Unix-like systems (Linux, MacOS, etc.), the job of matching file names to "
 37.6957  "patterns normally falls to the shell.  On these systems, you must explicitly "
 37.6958 @@ -7742,21 +6825,21 @@
 37.6959  msgstr ""
 37.6960  
 37.6961  #. type: Content of: <book><chapter><sect1><para>
 37.6962 -#: ../en/ch07-filenames.xml:113
 37.6963 +#: ../en/ch06-filenames.xml:113
 37.6964  msgid ""
 37.6965  "To provide a pattern in place of a regular name on the command line, the "
 37.6966  "mechanism is simple:"
 37.6967  msgstr ""
 37.6968  
 37.6969  #. type: Content of: <book><chapter><sect1><para>
 37.6970 -#: ../en/ch07-filenames.xml:116
 37.6971 +#: ../en/ch06-filenames.xml:116
 37.6972  msgid ""
 37.6973  "That is, a pattern is identified by a short text string that says what kind "
 37.6974  "of pattern this is, followed by a colon, followed by the actual pattern."
 37.6975  msgstr ""
 37.6976  
 37.6977  #. type: Content of: <book><chapter><sect1><para>
 37.6978 -#: ../en/ch07-filenames.xml:120
 37.6979 +#: ../en/ch06-filenames.xml:120
 37.6980  msgid ""
 37.6981  "Mercurial supports two kinds of pattern syntax.  The most frequently used is "
 37.6982  "called <literal>glob</literal>; this is the same kind of pattern matching "
 37.6983 @@ -7765,7 +6848,7 @@
 37.6984  msgstr ""
 37.6985  
 37.6986  #. type: Content of: <book><chapter><sect1><para>
 37.6987 -#: ../en/ch07-filenames.xml:125
 37.6988 +#: ../en/ch06-filenames.xml:125
 37.6989  msgid ""
 37.6990  "When Mercurial does automatic pattern matching on Windows, it uses "
 37.6991  "<literal>glob</literal> syntax.  You can thus omit the <quote><literal>glob:</"
 37.6992 @@ -7773,14 +6856,14 @@
 37.6993  msgstr ""
 37.6994  
 37.6995  #. type: Content of: <book><chapter><sect1><para>
 37.6996 -#: ../en/ch07-filenames.xml:130
 37.6997 +#: ../en/ch06-filenames.xml:130
 37.6998  msgid ""
 37.6999  "The <literal>re</literal> syntax is more powerful; it lets you specify "
 37.7000  "patterns using regular expressions, also known as regexps."
 37.7001  msgstr ""
 37.7002  
 37.7003  #. type: Content of: <book><chapter><sect1><para>
 37.7004 -#: ../en/ch07-filenames.xml:134
 37.7005 +#: ../en/ch06-filenames.xml:134
 37.7006  msgid ""
 37.7007  "By the way, in the examples that follow, notice that I'm careful to wrap all "
 37.7008  "of my patterns in quote characters, so that they won't get expanded by the "
 37.7009 @@ -7788,12 +6871,12 @@
 37.7010  msgstr ""
 37.7011  
 37.7012  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.7013 -#: ../en/ch07-filenames.xml:140
 37.7014 +#: ../en/ch06-filenames.xml:140
 37.7015  msgid "Shell-style <literal>glob</literal> patterns"
 37.7016  msgstr "外壳风格的 <literal>glob</literal>  模式"
 37.7017  
 37.7018  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7019 -#: ../en/ch07-filenames.xml:142
 37.7020 +#: ../en/ch06-filenames.xml:142
 37.7021  msgid ""
 37.7022  "This is an overview of the kinds of patterns you can use when you're matching "
 37.7023  "on glob patterns."
 37.7024 @@ -7801,7 +6884,7 @@
 37.7025  
 37.7026  #
 37.7027  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7028 -#: ../en/ch07-filenames.xml:145
 37.7029 +#: ../en/ch06-filenames.xml:145
 37.7030  msgid ""
 37.7031  "The <quote><literal>*</literal></quote> character matches any string, within "
 37.7032  "a single directory."
 37.7033 @@ -7809,7 +6892,7 @@
 37.7034  
 37.7035  #
 37.7036  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7037 -#: ../en/ch07-filenames.xml:150
 37.7038 +#: ../en/ch06-filenames.xml:150
 37.7039  msgid ""
 37.7040  "The <quote><literal>**</literal></quote> pattern matches any string, and "
 37.7041  "crosses directory boundaries.  It's not a standard Unix glob token, but it's "
 37.7042 @@ -7818,13 +6901,13 @@
 37.7043  
 37.7044  #
 37.7045  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7046 -#: ../en/ch07-filenames.xml:157
 37.7047 +#: ../en/ch06-filenames.xml:157
 37.7048  msgid ""
 37.7049  "The <quote><literal>?</literal></quote> pattern matches any single character."
 37.7050  msgstr ""
 37.7051  
 37.7052  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7053 -#: ../en/ch07-filenames.xml:162
 37.7054 +#: ../en/ch06-filenames.xml:162
 37.7055  msgid ""
 37.7056  "The <quote><literal>[</literal></quote> character begins a "
 37.7057  "<emphasis>character class</emphasis>.  This matches any single character "
 37.7058 @@ -7835,7 +6918,7 @@
 37.7059  msgstr ""
 37.7060  
 37.7061  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7062 -#: ../en/ch07-filenames.xml:172
 37.7063 +#: ../en/ch06-filenames.xml:172
 37.7064  msgid ""
 37.7065  "If the first character after the <quote><literal>[</literal></quote> in a "
 37.7066  "character class is a <quote><literal>!</literal></quote>, it "
 37.7067 @@ -7844,7 +6927,7 @@
 37.7068  msgstr ""
 37.7069  
 37.7070  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7071 -#: ../en/ch07-filenames.xml:178
 37.7072 +#: ../en/ch06-filenames.xml:178
 37.7073  msgid ""
 37.7074  "A <quote><literal>{</literal></quote> begins a group of subpatterns, where "
 37.7075  "the whole group matches if any subpattern in the group matches.  The "
 37.7076 @@ -7853,13 +6936,13 @@
 37.7077  msgstr ""
 37.7078  
 37.7079  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
 37.7080 -#: ../en/ch07-filenames.xml:187
 37.7081 +#: ../en/ch06-filenames.xml:187
 37.7082  msgid "Watch out!"
 37.7083  msgstr "千万小心!"
 37.7084  
 37.7085  #
 37.7086  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.7087 -#: ../en/ch07-filenames.xml:189
 37.7088 +#: ../en/ch06-filenames.xml:189
 37.7089  msgid ""
 37.7090  "Don't forget that if you want to match a pattern in any directory, you should "
 37.7091  "not be using the <quote><literal>*</literal></quote> match-any token, as this "
 37.7092 @@ -7869,12 +6952,12 @@
 37.7093  msgstr ""
 37.7094  
 37.7095  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.7096 -#: ../en/ch07-filenames.xml:201
 37.7097 +#: ../en/ch06-filenames.xml:201
 37.7098  msgid "Regular expression matching with <literal>re</literal> patterns"
 37.7099  msgstr "使用 <literal>re</literal> 模式的正则表达式匹配"
 37.7100  
 37.7101  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7102 -#: ../en/ch07-filenames.xml:204
 37.7103 +#: ../en/ch06-filenames.xml:204
 37.7104  msgid ""
 37.7105  "Mercurial accepts the same regular expression syntax as the Python "
 37.7106  "programming language (it uses Python's regexp engine internally). This is "
 37.7107 @@ -7883,7 +6966,7 @@
 37.7108  msgstr ""
 37.7109  
 37.7110  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7111 -#: ../en/ch07-filenames.xml:210
 37.7112 +#: ../en/ch06-filenames.xml:210
 37.7113  msgid ""
 37.7114  "I won't discuss Mercurial's regexp dialect in any detail here, as regexps are "
 37.7115  "not often used.  Perl-style regexps are in any case already exhaustively "
 37.7116 @@ -7893,7 +6976,7 @@
 37.7117  msgstr ""
 37.7118  
 37.7119  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7120 -#: ../en/ch07-filenames.xml:217
 37.7121 +#: ../en/ch06-filenames.xml:217
 37.7122  msgid ""
 37.7123  "A regexp is matched against an entire file name, relative to the root of the "
 37.7124  "repository.  In other words, even if you're already in subbdirectory "
 37.7125 @@ -7903,7 +6986,7 @@
 37.7126  msgstr ""
 37.7127  
 37.7128  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7129 -#: ../en/ch07-filenames.xml:224
 37.7130 +#: ../en/ch06-filenames.xml:224
 37.7131  msgid ""
 37.7132  "One thing to note, if you're familiar with Perl-style regexps, is that "
 37.7133  "Mercurial's are <emphasis>rooted</emphasis>.  That is, a regexp starts "
 37.7134 @@ -7913,12 +6996,12 @@
 37.7135  msgstr ""
 37.7136  
 37.7137  #. type: Content of: <book><chapter><sect1><title>
 37.7138 -#: ../en/ch07-filenames.xml:234
 37.7139 +#: ../en/ch06-filenames.xml:234
 37.7140  msgid "Filtering files"
 37.7141  msgstr "过滤文件"
 37.7142  
 37.7143  #. type: Content of: <book><chapter><sect1><para>
 37.7144 -#: ../en/ch07-filenames.xml:236
 37.7145 +#: ../en/ch06-filenames.xml:236
 37.7146  msgid ""
 37.7147  "Not only does Mercurial give you a variety of ways to specify files; it lets "
 37.7148  "you further winnow those files using <emphasis>filters</emphasis>.  Commands "
 37.7149 @@ -7926,7 +7009,7 @@
 37.7150  msgstr ""
 37.7151  
 37.7152  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.7153 -#: ../en/ch07-filenames.xml:241
 37.7154 +#: ../en/ch06-filenames.xml:241
 37.7155  msgid ""
 37.7156  "<option role=\"hg-opt-global\">-I</option>, or <option role=\"hg-opt-global"
 37.7157  "\">--include</option>, lets you specify a pattern that file names must match "
 37.7158 @@ -7934,7 +7017,7 @@
 37.7159  msgstr ""
 37.7160  
 37.7161  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.7162 -#: ../en/ch07-filenames.xml:246
 37.7163 +#: ../en/ch06-filenames.xml:246
 37.7164  msgid ""
 37.7165  "<option role=\"hg-opt-global\">-X</option>, or <option role=\"hg-opt-global"
 37.7166  "\">--exclude</option>, gives you a way to <emphasis>avoid</emphasis> "
 37.7167 @@ -7942,7 +7025,7 @@
 37.7168  msgstr ""
 37.7169  
 37.7170  #. type: Content of: <book><chapter><sect1><para>
 37.7171 -#: ../en/ch07-filenames.xml:251
 37.7172 +#: ../en/ch06-filenames.xml:251
 37.7173  msgid ""
 37.7174  "You can provide multiple <option role=\"hg-opt-global\">-I</option> and "
 37.7175  "<option role=\"hg-opt-global\">-X</option> options on the command line, and "
 37.7176 @@ -7951,36 +7034,36 @@
 37.7177  msgstr ""
 37.7178  
 37.7179  #. type: Content of: <book><chapter><sect1><para>
 37.7180 -#: ../en/ch07-filenames.xml:258
 37.7181 +#: ../en/ch06-filenames.xml:258
 37.7182  msgid ""
 37.7183  "You can read a <option role=\"hg-opt-global\">-I</option> filter as "
 37.7184  "<quote>process only the files that match this filter</quote>."
 37.7185  msgstr ""
 37.7186  
 37.7187  #. type: Content of: <book><chapter><sect1><para>
 37.7188 -#: ../en/ch07-filenames.xml:264
 37.7189 +#: ../en/ch06-filenames.xml:264
 37.7190  msgid ""
 37.7191  "The <option role=\"hg-opt-global\">-X</option> filter is best read as "
 37.7192  "<quote>process only the files that don't match this pattern</quote>."
 37.7193  msgstr ""
 37.7194  
 37.7195  #. type: Content of: <book><chapter><sect1><title>
 37.7196 -#: ../en/ch07-filenames.xml:272
 37.7197 +#: ../en/ch06-filenames.xml:272
 37.7198  msgid "Ignoring unwanted files and directories"
 37.7199  msgstr "忽略不需要的文件和目录"
 37.7200  
 37.7201  #. type: Content of: <book><chapter><sect1><para>
 37.7202 -#: ../en/ch07-filenames.xml:274
 37.7203 +#: ../en/ch06-filenames.xml:274
 37.7204  msgid "XXX."
 37.7205  msgstr ""
 37.7206  
 37.7207  #. type: Content of: <book><chapter><sect1><title>
 37.7208 -#: ../en/ch07-filenames.xml:278
 37.7209 +#: ../en/ch06-filenames.xml:278
 37.7210  msgid "Case sensitivity"
 37.7211  msgstr "大小写敏感性"
 37.7212  
 37.7213  #. type: Content of: <book><chapter><sect1><para>
 37.7214 -#: ../en/ch07-filenames.xml:280
 37.7215 +#: ../en/ch06-filenames.xml:280
 37.7216  msgid ""
 37.7217  "If you're working in a mixed development environment that contains both Linux "
 37.7218  "(or other Unix) systems and Macs or Windows systems, you should keep in the "
 37.7219 @@ -7991,7 +7074,7 @@
 37.7220  msgstr ""
 37.7221  
 37.7222  #. type: Content of: <book><chapter><sect1><para>
 37.7223 -#: ../en/ch07-filenames.xml:289
 37.7224 +#: ../en/ch06-filenames.xml:289
 37.7225  msgid ""
 37.7226  "Operating systems and filesystems differ in the way they handle the "
 37.7227  "<emphasis>case</emphasis> of characters in file and directory names.  There "
 37.7228 @@ -7999,7 +7082,7 @@
 37.7229  msgstr ""
 37.7230  
 37.7231  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.7232 -#: ../en/ch07-filenames.xml:294
 37.7233 +#: ../en/ch06-filenames.xml:294
 37.7234  msgid ""
 37.7235  "Completely case insensitive.  Uppercase and lowercase versions of a letter "
 37.7236  "are treated as identical, both when creating a file and during subsequent "
 37.7237 @@ -8007,7 +7090,7 @@
 37.7238  msgstr ""
 37.7239  
 37.7240  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.7241 -#: ../en/ch07-filenames.xml:299
 37.7242 +#: ../en/ch06-filenames.xml:299
 37.7243  msgid ""
 37.7244  "Case preserving, but insensitive.  When a file or directory is created, the "
 37.7245  "case of its name is stored, and can be retrieved and displayed by the "
 37.7246 @@ -8019,7 +7102,7 @@
 37.7247  msgstr ""
 37.7248  
 37.7249  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.7250 -#: ../en/ch07-filenames.xml:310
 37.7251 +#: ../en/ch06-filenames.xml:310
 37.7252  msgid ""
 37.7253  "Case sensitive.  The case of a name is significant at all times. The names "
 37.7254  "<filename>foo</filename> and {FoO} identify different files.  This is the way "
 37.7255 @@ -8027,7 +7110,7 @@
 37.7256  msgstr ""
 37.7257  
 37.7258  #. type: Content of: <book><chapter><sect1><para>
 37.7259 -#: ../en/ch07-filenames.xml:316
 37.7260 +#: ../en/ch06-filenames.xml:316
 37.7261  msgid ""
 37.7262  "On Unix-like systems, it is possible to have any or all of the above ways of "
 37.7263  "handling case in action at once.  For example, if you use a USB thumb drive "
 37.7264 @@ -8036,12 +7119,12 @@
 37.7265  msgstr ""
 37.7266  
 37.7267  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.7268 -#: ../en/ch07-filenames.xml:323
 37.7269 +#: ../en/ch06-filenames.xml:323
 37.7270  msgid "Safe, portable repository storage"
 37.7271  msgstr "安全,可移植的版本库存储"
 37.7272  
 37.7273  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7274 -#: ../en/ch07-filenames.xml:325
 37.7275 +#: ../en/ch06-filenames.xml:325
 37.7276  msgid ""
 37.7277  "Mercurial's repository storage mechanism is <emphasis>case safe</emphasis>.  "
 37.7278  "It translates file names so that they can be safely stored on both case "
 37.7279 @@ -8052,12 +7135,12 @@
 37.7280  msgstr ""
 37.7281  
 37.7282  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.7283 -#: ../en/ch07-filenames.xml:336
 37.7284 +#: ../en/ch06-filenames.xml:336
 37.7285  msgid "Detecting case conflicts"
 37.7286  msgstr "检测大小写冲突"
 37.7287  
 37.7288  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7289 -#: ../en/ch07-filenames.xml:338
 37.7290 +#: ../en/ch06-filenames.xml:338
 37.7291  msgid ""
 37.7292  "When operating in the working directory, Mercurial honours the naming policy "
 37.7293  "of the filesystem where the working directory is located.  If the filesystem "
 37.7294 @@ -8066,7 +7149,7 @@
 37.7295  msgstr ""
 37.7296  
 37.7297  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7298 -#: ../en/ch07-filenames.xml:344
 37.7299 +#: ../en/ch06-filenames.xml:344
 37.7300  msgid ""
 37.7301  "An important aspect of this approach is that it is possible to commit a "
 37.7302  "changeset on a case sensitive (typically Linux or Unix) filesystem that will "
 37.7303 @@ -8079,7 +7162,7 @@
 37.7304  msgstr ""
 37.7305  
 37.7306  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7307 -#: ../en/ch07-filenames.xml:355
 37.7308 +#: ../en/ch06-filenames.xml:355
 37.7309  msgid ""
 37.7310  "If a Windows or Mac user pulls this change, they will not initially have a "
 37.7311  "problem, because Mercurial's repository storage mechanism is case safe.  "
 37.7312 @@ -8091,12 +7174,12 @@
 37.7313  msgstr ""
 37.7314  
 37.7315  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.7316 -#: ../en/ch07-filenames.xml:367
 37.7317 +#: ../en/ch06-filenames.xml:367
 37.7318  msgid "Fixing a case conflict"
 37.7319  msgstr "修正大小写冲突"
 37.7320  
 37.7321  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7322 -#: ../en/ch07-filenames.xml:369
 37.7323 +#: ../en/ch06-filenames.xml:369
 37.7324  msgid ""
 37.7325  "If you are using Windows or a Mac in a mixed environment where some of your "
 37.7326  "collaborators are using Linux or Unix, and Mercurial reports a case folding "
 37.7327 @@ -8106,7 +7189,7 @@
 37.7328  msgstr ""
 37.7329  
 37.7330  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7331 -#: ../en/ch07-filenames.xml:376
 37.7332 +#: ../en/ch06-filenames.xml:376
 37.7333  msgid ""
 37.7334  "Just find a nearby Linux or Unix box, clone the problem repository onto it, "
 37.7335  "and use Mercurial's <command role=\"hg-cmd\">hg rename</command> command to "
 37.7336 @@ -8118,7 +7201,7 @@
 37.7337  msgstr ""
 37.7338  
 37.7339  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7340 -#: ../en/ch07-filenames.xml:386
 37.7341 +#: ../en/ch06-filenames.xml:386
 37.7342  msgid ""
 37.7343  "The changeset with case-conflicting names will remain in your project's "
 37.7344  "history, and you still won't be able to <command role=\"hg-cmd\">hg update</"
 37.7345 @@ -8127,7 +7210,7 @@
 37.7346  msgstr ""
 37.7347  
 37.7348  #. type: Content of: <book><chapter><sect1><sect2><note><para>
 37.7349 -#: ../en/ch07-filenames.xml:393
 37.7350 +#: ../en/ch06-filenames.xml:393
 37.7351  msgid ""
 37.7352  "Prior to version 0.9.3, Mercurial did not use a case safe repository storage "
 37.7353  "mechanism, and did not detect case folding conflicts.  If you are using an "
 37.7354 @@ -8136,12 +7219,12 @@
 37.7355  msgstr ""
 37.7356  
 37.7357  #. type: Content of: <book><chapter><title>
 37.7358 -#: ../en/ch08-branch.xml:5
 37.7359 +#: ../en/ch07-branch.xml:5
 37.7360  msgid "Managing releases and branchy development"
 37.7361  msgstr "发布管理与分支开发"
 37.7362  
 37.7363  #. type: Content of: <book><chapter><para>
 37.7364 -#: ../en/ch08-branch.xml:7
 37.7365 +#: ../en/ch07-branch.xml:7
 37.7366  msgid ""
 37.7367  "Mercurial provides several mechanisms for you to manage a project that is "
 37.7368  "making progress on multiple fronts at once.  To understand these mechanisms, "
 37.7369 @@ -8149,7 +7232,7 @@
 37.7370  msgstr ""
 37.7371  
 37.7372  #. type: Content of: <book><chapter><para>
 37.7373 -#: ../en/ch08-branch.xml:12
 37.7374 +#: ../en/ch07-branch.xml:12
 37.7375  msgid ""
 37.7376  "Many software projects issue periodic <quote>major</quote> releases that "
 37.7377  "contain substantial new features.  In parallel, they may issue <quote>minor</"
 37.7378 @@ -8158,7 +7241,7 @@
 37.7379  msgstr ""
 37.7380  
 37.7381  #. type: Content of: <book><chapter><para>
 37.7382 -#: ../en/ch08-branch.xml:18
 37.7383 +#: ../en/ch07-branch.xml:18
 37.7384  msgid ""
 37.7385  "In this chapter, we'll start by talking about how to keep records of project "
 37.7386  "milestones such as releases.  We'll then continue on to talk about the flow "
 37.7387 @@ -8167,12 +7250,12 @@
 37.7388  msgstr ""
 37.7389  
 37.7390  #. type: Content of: <book><chapter><sect1><title>
 37.7391 -#: ../en/ch08-branch.xml:25
 37.7392 +#: ../en/ch07-branch.xml:25
 37.7393  msgid "Giving a persistent name to a revision"
 37.7394  msgstr "给版本指定一个永久的名称"
 37.7395  
 37.7396  #. type: Content of: <book><chapter><sect1><para>
 37.7397 -#: ../en/ch08-branch.xml:27
 37.7398 +#: ../en/ch07-branch.xml:27
 37.7399  msgid ""
 37.7400  "Once you decide that you'd like to call a particular revision a "
 37.7401  "<quote>release</quote>, it's a good idea to record the identity of that "
 37.7402 @@ -8183,7 +7266,7 @@
 37.7403  
 37.7404  #
 37.7405  #. type: Content of: <book><chapter><sect1><para>
 37.7406 -#: ../en/ch08-branch.xml:34
 37.7407 +#: ../en/ch07-branch.xml:34
 37.7408  msgid ""
 37.7409  "Mercurial lets you give a permanent name to any revision using the <command "
 37.7410  "role=\"hg-cmd\">hg tag</command> command.  Not surprisingly, these names are "
 37.7411 @@ -8191,7 +7274,7 @@
 37.7412  msgstr ""
 37.7413  
 37.7414  #. type: Content of: <book><chapter><sect1><para>
 37.7415 -#: ../en/ch08-branch.xml:40
 37.7416 +#: ../en/ch07-branch.xml:40
 37.7417  msgid ""
 37.7418  "A tag is nothing more than a <quote>symbolic name</quote> for a revision.  "
 37.7419  "Tags exist purely for your convenience, so that you have a handy permanent "
 37.7420 @@ -8202,22 +7285,22 @@
 37.7421  msgstr ""
 37.7422  
 37.7423  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.7424 -#: ../en/ch08-branch.xml:49
 37.7425 +#: ../en/ch07-branch.xml:49
 37.7426  msgid "Colon (ASCII 58, <quote><literal>:</literal></quote>)"
 37.7427  msgstr ""
 37.7428  
 37.7429  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.7430 -#: ../en/ch08-branch.xml:52
 37.7431 +#: ../en/ch07-branch.xml:52
 37.7432  msgid "Carriage return (ASCII 13, <quote><literal>\\r</literal></quote>)"
 37.7433  msgstr ""
 37.7434  
 37.7435  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.7436 -#: ../en/ch08-branch.xml:55
 37.7437 +#: ../en/ch07-branch.xml:55
 37.7438  msgid "Newline (ASCII 10, <quote><literal>\\n</literal></quote>)"
 37.7439  msgstr ""
 37.7440  
 37.7441  #. type: Content of: <book><chapter><sect1><para>
 37.7442 -#: ../en/ch08-branch.xml:59
 37.7443 +#: ../en/ch07-branch.xml:59
 37.7444  msgid ""
 37.7445  "You can use the <command role=\"hg-cmd\">hg tags</command> command to display "
 37.7446  "the tags present in your repository.  In the output, each tagged revision is "
 37.7447 @@ -8226,7 +7309,7 @@
 37.7448  msgstr ""
 37.7449  
 37.7450  #. type: Content of: <book><chapter><sect1><para>
 37.7451 -#: ../en/ch08-branch.xml:67
 37.7452 +#: ../en/ch07-branch.xml:67
 37.7453  msgid ""
 37.7454  "Notice that <literal>tip</literal> is listed in the output of <command role="
 37.7455  "\"hg-cmd\">hg tags</command>.  The <literal>tip</literal> tag is a special "
 37.7456 @@ -8235,7 +7318,7 @@
 37.7457  msgstr ""
 37.7458  
 37.7459  #. type: Content of: <book><chapter><sect1><para>
 37.7460 -#: ../en/ch08-branch.xml:73
 37.7461 +#: ../en/ch07-branch.xml:73
 37.7462  msgid ""
 37.7463  "In the output of the <command role=\"hg-cmd\">hg tags</command> command, tags "
 37.7464  "are listed in reverse order, by revision number.  This usually means that "
 37.7465 @@ -8245,7 +7328,7 @@
 37.7466  msgstr ""
 37.7467  
 37.7468  #. type: Content of: <book><chapter><sect1><para>
 37.7469 -#: ../en/ch08-branch.xml:80
 37.7470 +#: ../en/ch07-branch.xml:80
 37.7471  msgid ""
 37.7472  "When you run <command role=\"hg-cmd\">hg log</command>, if it displays a "
 37.7473  "revision that has tags associated with it, it will print those tags."
 37.7474 @@ -8253,7 +7336,7 @@
 37.7475  
 37.7476  #
 37.7477  #. type: Content of: <book><chapter><sect1><para>
 37.7478 -#: ../en/ch08-branch.xml:86
 37.7479 +#: ../en/ch07-branch.xml:86
 37.7480  msgid ""
 37.7481  "Any time you need to provide a revision ID to a Mercurial command, the "
 37.7482  "command will accept a tag name in its place.  Internally, Mercurial will "
 37.7483 @@ -8261,7 +7344,7 @@
 37.7484  msgstr ""
 37.7485  
 37.7486  #. type: Content of: <book><chapter><sect1><para>
 37.7487 -#: ../en/ch08-branch.xml:93
 37.7488 +#: ../en/ch07-branch.xml:93
 37.7489  msgid ""
 37.7490  "There's no limit on the number of tags you can have in a repository, or on "
 37.7491  "the number of tags that a single revision can have.  As a practical matter, "
 37.7492 @@ -8272,7 +7355,7 @@
 37.7493  msgstr ""
 37.7494  
 37.7495  #. type: Content of: <book><chapter><sect1><para>
 37.7496 -#: ../en/ch08-branch.xml:101
 37.7497 +#: ../en/ch07-branch.xml:101
 37.7498  msgid ""
 37.7499  "For example, if your project has milestones as frequent as every few days, "
 37.7500  "it's perfectly reasonable to tag each one of those.  But if you have a "
 37.7501 @@ -8283,14 +7366,14 @@
 37.7502  msgstr ""
 37.7503  
 37.7504  #. type: Content of: <book><chapter><sect1><para>
 37.7505 -#: ../en/ch08-branch.xml:109
 37.7506 +#: ../en/ch07-branch.xml:109
 37.7507  msgid ""
 37.7508  "If you want to remove a tag that you no longer want, use <command role=\"hg-"
 37.7509  "cmd\">hg tag --remove</command>."
 37.7510  msgstr ""
 37.7511  
 37.7512  #. type: Content of: <book><chapter><sect1><para>
 37.7513 -#: ../en/ch08-branch.xml:114
 37.7514 +#: ../en/ch07-branch.xml:114
 37.7515  msgid ""
 37.7516  "You can also modify a tag at any time, so that it identifies a different "
 37.7517  "revision, by simply issuing a new <command role=\"hg-cmd\">hg tag</command> "
 37.7518 @@ -8300,7 +7383,7 @@
 37.7519  msgstr ""
 37.7520  
 37.7521  #. type: Content of: <book><chapter><sect1><para>
 37.7522 -#: ../en/ch08-branch.xml:123
 37.7523 +#: ../en/ch07-branch.xml:123
 37.7524  msgid ""
 37.7525  "There will still be a permanent record of the previous identity of the tag, "
 37.7526  "but Mercurial will no longer use it.  There's thus no penalty to tagging the "
 37.7527 @@ -8310,7 +7393,7 @@
 37.7528  
 37.7529  #
 37.7530  #. type: Content of: <book><chapter><sect1><para>
 37.7531 -#: ../en/ch08-branch.xml:129
 37.7532 +#: ../en/ch07-branch.xml:129
 37.7533  msgid ""
 37.7534  "Mercurial stores tags in a normal revision-controlled file in your "
 37.7535  "repository.  If you've created any tags, you'll find them in a file named "
 37.7536 @@ -8322,12 +7405,12 @@
 37.7537  msgstr ""
 37.7538  
 37.7539  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.7540 -#: ../en/ch08-branch.xml:142
 37.7541 +#: ../en/ch07-branch.xml:142
 37.7542  msgid "Handling tag conflicts during a merge"
 37.7543  msgstr "在合并期间处理标签冲突"
 37.7544  
 37.7545  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7546 -#: ../en/ch08-branch.xml:144
 37.7547 +#: ../en/ch07-branch.xml:144
 37.7548  msgid ""
 37.7549  "You won't often need to care about the <filename role=\"special\">.hgtags</"
 37.7550  "filename> file, but it sometimes makes its presence known during a merge.  "
 37.7551 @@ -8337,7 +7420,7 @@
 37.7552  msgstr ""
 37.7553  
 37.7554  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7555 -#: ../en/ch08-branch.xml:151
 37.7556 +#: ../en/ch07-branch.xml:151
 37.7557  msgid ""
 37.7558  "If you're resolving a conflict in the <filename role=\"special\">.hgtags</"
 37.7559  "filename> file during a merge, there's one twist to modifying the <filename "
 37.7560 @@ -8348,7 +7431,7 @@
 37.7561  msgstr ""
 37.7562  
 37.7563  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7564 -#: ../en/ch08-branch.xml:161
 37.7565 +#: ../en/ch07-branch.xml:161
 37.7566  msgid ""
 37.7567  "An unfortunate consequence of this design is that you can't actually verify "
 37.7568  "that your merged <filename role=\"special\">.hgtags</filename> file is "
 37.7569 @@ -8362,12 +7445,12 @@
 37.7570  msgstr ""
 37.7571  
 37.7572  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.7573 -#: ../en/ch08-branch.xml:176
 37.7574 +#: ../en/ch07-branch.xml:176
 37.7575  msgid "Tags and cloning"
 37.7576  msgstr "标签与克隆"
 37.7577  
 37.7578  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7579 -#: ../en/ch08-branch.xml:178
 37.7580 +#: ../en/ch07-branch.xml:178
 37.7581  msgid ""
 37.7582  "You may have noticed that the <command role=\"hg-cmd\">hg clone</command> "
 37.7583  "command has a <option role=\"hg-opt-clone\">-r</option> option that lets you "
 37.7584 @@ -8377,7 +7460,7 @@
 37.7585  msgstr ""
 37.7586  
 37.7587  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7588 -#: ../en/ch08-branch.xml:186
 37.7589 +#: ../en/ch07-branch.xml:186
 37.7590  msgid ""
 37.7591  "Recall that a tag is stored as a revision to the <filename role=\"special\">."
 37.7592  "hgtags</filename> file, so that when you create a tag, the changeset in which "
 37.7593 @@ -8391,12 +7474,12 @@
 37.7594  msgstr ""
 37.7595  
 37.7596  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.7597 -#: ../en/ch08-branch.xml:201
 37.7598 +#: ../en/ch07-branch.xml:201
 37.7599  msgid "When permanent tags are too much"
 37.7600  msgstr "当永久标签太多的时候"
 37.7601  
 37.7602  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7603 -#: ../en/ch08-branch.xml:203
 37.7604 +#: ../en/ch07-branch.xml:203
 37.7605  msgid ""
 37.7606  "Since Mercurial's tags are revision controlled and carried around with a "
 37.7607  "project's history, everyone you work with will see the tags you create.  But "
 37.7608 @@ -8407,7 +7490,7 @@
 37.7609  msgstr ""
 37.7610  
 37.7611  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.7612 -#: ../en/ch08-branch.xml:213
 37.7613 +#: ../en/ch07-branch.xml:213
 37.7614  msgid ""
 37.7615  "For cases like this, what you might want to use are <emphasis>local</"
 37.7616  "emphasis> tags. You can create a local tag with the <option role=\"hg-opt-tag"
 37.7617 @@ -8421,12 +7504,12 @@
 37.7618  msgstr ""
 37.7619  
 37.7620  #. type: Content of: <book><chapter><sect1><title>
 37.7621 -#: ../en/ch08-branch.xml:228
 37.7622 +#: ../en/ch07-branch.xml:228
 37.7623  msgid "The flow of changes&emdash;big picture vs. little"
 37.7624  msgstr "修改流程&emdash;宏观与微观"
 37.7625  
 37.7626  #. type: Content of: <book><chapter><sect1><para>
 37.7627 -#: ../en/ch08-branch.xml:230
 37.7628 +#: ../en/ch07-branch.xml:230
 37.7629  msgid ""
 37.7630  "To return to the outline I sketched at the beginning of a chapter, let's "
 37.7631  "think about a project that has multiple concurrent pieces of work under "
 37.7632 @@ -8434,7 +7517,7 @@
 37.7633  msgstr ""
 37.7634  
 37.7635  #. type: Content of: <book><chapter><sect1><para>
 37.7636 -#: ../en/ch08-branch.xml:234
 37.7637 +#: ../en/ch07-branch.xml:234
 37.7638  msgid ""
 37.7639  "There might be a push for a new <quote>main</quote> release; a new minor "
 37.7640  "bugfix release to the last main release; and an unexpected <quote>hot fix</"
 37.7641 @@ -8442,7 +7525,7 @@
 37.7642  msgstr ""
 37.7643  
 37.7644  #. type: Content of: <book><chapter><sect1><para>
 37.7645 -#: ../en/ch08-branch.xml:239
 37.7646 +#: ../en/ch07-branch.xml:239
 37.7647  msgid ""
 37.7648  "The usual way people refer to these different concurrent directions of "
 37.7649  "development is as <quote>branches</quote>.  However, we've already seen "
 37.7650 @@ -8452,14 +7535,14 @@
 37.7651  msgstr ""
 37.7652  
 37.7653  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.7654 -#: ../en/ch08-branch.xml:246
 37.7655 +#: ../en/ch07-branch.xml:246
 37.7656  msgid ""
 37.7657  "<quote>Big picture</quote> branches represent the sweep of a project's "
 37.7658  "evolution; people give them names, and talk about them in conversation."
 37.7659  msgstr ""
 37.7660  
 37.7661  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.7662 -#: ../en/ch08-branch.xml:250
 37.7663 +#: ../en/ch07-branch.xml:250
 37.7664  msgid ""
 37.7665  "<quote>Little picture</quote> branches are artefacts of the day-to-day "
 37.7666  "activity of developing and merging changes.  They expose the narrative of how "
 37.7667 @@ -8467,12 +7550,12 @@
 37.7668  msgstr ""
 37.7669  
 37.7670  #. type: Content of: <book><chapter><sect1><title>
 37.7671 -#: ../en/ch08-branch.xml:258
 37.7672 +#: ../en/ch07-branch.xml:258
 37.7673  msgid "Managing big-picture branches in repositories"
 37.7674  msgstr "在版本库中管理分支"
 37.7675  
 37.7676  #. type: Content of: <book><chapter><sect1><para>
 37.7677 -#: ../en/ch08-branch.xml:260
 37.7678 +#: ../en/ch07-branch.xml:260
 37.7679  msgid ""
 37.7680  "The easiest way to isolate a <quote>big picture</quote> branch in Mercurial "
 37.7681  "is in a dedicated repository.  If you have an existing shared "
 37.7682 @@ -8483,14 +7566,14 @@
 37.7683  msgstr ""
 37.7684  
 37.7685  #. type: Content of: <book><chapter><sect1><para>
 37.7686 -#: ../en/ch08-branch.xml:270
 37.7687 +#: ../en/ch07-branch.xml:270
 37.7688  msgid ""
 37.7689  "You can then clone a new shared <literal>myproject-1.0.1</literal> repository "
 37.7690  "as of that tag."
 37.7691  msgstr ""
 37.7692  
 37.7693  #. type: Content of: <book><chapter><sect1><para>
 37.7694 -#: ../en/ch08-branch.xml:276
 37.7695 +#: ../en/ch07-branch.xml:276
 37.7696  msgid ""
 37.7697  "Afterwards, if someone needs to work on a bug fix that ought to go into an "
 37.7698  "upcoming 1.0.1 minor release, they clone the <literal>myproject-1.0.1</"
 37.7699 @@ -8498,19 +7581,19 @@
 37.7700  msgstr ""
 37.7701  
 37.7702  #. type: Content of: <book><chapter><sect1><para>
 37.7703 -#: ../en/ch08-branch.xml:283
 37.7704 +#: ../en/ch07-branch.xml:283
 37.7705  msgid ""
 37.7706  "Meanwhile, development for the next major release can continue, isolated and "
 37.7707  "unabated, in the <literal>myproject</literal> repository."
 37.7708  msgstr ""
 37.7709  
 37.7710  #. type: Content of: <book><chapter><sect1><title>
 37.7711 -#: ../en/ch08-branch.xml:291
 37.7712 +#: ../en/ch07-branch.xml:291
 37.7713  msgid "Don't repeat yourself: merging across branches"
 37.7714  msgstr "不要重复劳动:在分支间合并"
 37.7715  
 37.7716  #. type: Content of: <book><chapter><sect1><para>
 37.7717 -#: ../en/ch08-branch.xml:293
 37.7718 +#: ../en/ch07-branch.xml:293
 37.7719  msgid ""
 37.7720  "In many cases, if you have a bug to fix on a maintenance branch, the chances "
 37.7721  "are good that the bug exists on your project's main branch (and possibly "
 37.7722 @@ -8520,26 +7603,26 @@
 37.7723  msgstr ""
 37.7724  
 37.7725  #. type: Content of: <book><chapter><sect1><para>
 37.7726 -#: ../en/ch08-branch.xml:301
 37.7727 +#: ../en/ch07-branch.xml:301
 37.7728  msgid ""
 37.7729  "In the simplest instance, all you need to do is pull changes from your "
 37.7730  "maintenance branch into your local clone of the target branch."
 37.7731  msgstr ""
 37.7732  
 37.7733  #. type: Content of: <book><chapter><sect1><para>
 37.7734 -#: ../en/ch08-branch.xml:307
 37.7735 +#: ../en/ch07-branch.xml:307
 37.7736  msgid ""
 37.7737  "You'll then need to merge the heads of the two branches, and push back to the "
 37.7738  "main branch."
 37.7739  msgstr ""
 37.7740  
 37.7741  #. type: Content of: <book><chapter><sect1><title>
 37.7742 -#: ../en/ch08-branch.xml:314
 37.7743 +#: ../en/ch07-branch.xml:314
 37.7744  msgid "Naming branches within one repository"
 37.7745  msgstr "版本库中的命名分支"
 37.7746  
 37.7747  #. type: Content of: <book><chapter><sect1><para>
 37.7748 -#: ../en/ch08-branch.xml:316
 37.7749 +#: ../en/ch07-branch.xml:316
 37.7750  msgid ""
 37.7751  "In most instances, isolating branches in repositories is the right approach.  "
 37.7752  "Its simplicity makes it easy to understand; and so it's hard to make "
 37.7753 @@ -8549,7 +7632,7 @@
 37.7754  msgstr ""
 37.7755  
 37.7756  #. type: Content of: <book><chapter><sect1><para>
 37.7757 -#: ../en/ch08-branch.xml:323
 37.7758 +#: ../en/ch07-branch.xml:323
 37.7759  msgid ""
 37.7760  "If you're more in the <quote>power user</quote> category (<emphasis>and</"
 37.7761  "emphasis> your collaborators are too), there is an alternative way of "
 37.7762 @@ -8562,7 +7645,7 @@
 37.7763  msgstr ""
 37.7764  
 37.7765  #. type: Content of: <book><chapter><sect1><para>
 37.7766 -#: ../en/ch08-branch.xml:334
 37.7767 +#: ../en/ch07-branch.xml:334
 37.7768  msgid ""
 37.7769  "The key to working this way is that Mercurial lets you assign a persistent "
 37.7770  "<emphasis>name</emphasis> to a branch.  There always exists a branch named "
 37.7771 @@ -8572,7 +7655,7 @@
 37.7772  msgstr ""
 37.7773  
 37.7774  #. type: Content of: <book><chapter><sect1><para>
 37.7775 -#: ../en/ch08-branch.xml:341
 37.7776 +#: ../en/ch07-branch.xml:341
 37.7777  msgid ""
 37.7778  "As an example, when you run the <command role=\"hg-cmd\">hg commit</command> "
 37.7779  "command, and it pops up your editor so that you can enter a commit message, "
 37.7780 @@ -8582,7 +7665,7 @@
 37.7781  msgstr ""
 37.7782  
 37.7783  #. type: Content of: <book><chapter><sect1><para>
 37.7784 -#: ../en/ch08-branch.xml:348
 37.7785 +#: ../en/ch07-branch.xml:348
 37.7786  msgid ""
 37.7787  "To start working with named branches, use the <command role=\"hg-cmd\">hg "
 37.7788  "branches</command> command.  This command lists the named branches already "
 37.7789 @@ -8590,14 +7673,14 @@
 37.7790  msgstr ""
 37.7791  
 37.7792  #. type: Content of: <book><chapter><sect1><para>
 37.7793 -#: ../en/ch08-branch.xml:355
 37.7794 +#: ../en/ch07-branch.xml:355
 37.7795  msgid ""
 37.7796  "Since you haven't created any named branches yet, the only one that exists is "
 37.7797  "<literal>default</literal>."
 37.7798  msgstr ""
 37.7799  
 37.7800  #. type: Content of: <book><chapter><sect1><para>
 37.7801 -#: ../en/ch08-branch.xml:358
 37.7802 +#: ../en/ch07-branch.xml:358
 37.7803  msgid ""
 37.7804  "To find out what the <quote>current</quote> branch is, run the <command role="
 37.7805  "\"hg-cmd\">hg branch</command> command, giving it no arguments.  This tells "
 37.7806 @@ -8606,7 +7689,7 @@
 37.7807  
 37.7808  #
 37.7809  #. type: Content of: <book><chapter><sect1><para>
 37.7810 -#: ../en/ch08-branch.xml:365
 37.7811 +#: ../en/ch07-branch.xml:365
 37.7812  msgid ""
 37.7813  "To create a new branch, run the <command role=\"hg-cmd\">hg branch</command> "
 37.7814  "command again.  This time, give it one argument: the name of the branch you "
 37.7815 @@ -8614,7 +7697,7 @@
 37.7816  msgstr ""
 37.7817  
 37.7818  #. type: Content of: <book><chapter><sect1><para>
 37.7819 -#: ../en/ch08-branch.xml:371
 37.7820 +#: ../en/ch07-branch.xml:371
 37.7821  msgid ""
 37.7822  "After you've created a branch, you might wonder what effect the <command role="
 37.7823  "\"hg-cmd\">hg branch</command> command has had.  What do the <command role="
 37.7824 @@ -8623,7 +7706,7 @@
 37.7825  msgstr ""
 37.7826  
 37.7827  #. type: Content of: <book><chapter><sect1><para>
 37.7828 -#: ../en/ch08-branch.xml:378
 37.7829 +#: ../en/ch07-branch.xml:378
 37.7830  msgid ""
 37.7831  "Nothing has changed in the working directory, and there's been no new history "
 37.7832  "created.  As this suggests, running the <command role=\"hg-cmd\">hg branch</"
 37.7833 @@ -8632,7 +7715,7 @@
 37.7834  msgstr ""
 37.7835  
 37.7836  #. type: Content of: <book><chapter><sect1><para>
 37.7837 -#: ../en/ch08-branch.xml:385
 37.7838 +#: ../en/ch07-branch.xml:385
 37.7839  msgid ""
 37.7840  "When you commit a change, Mercurial records the name of the branch on which "
 37.7841  "you committed.  Once you've switched from the <literal>default</literal> "
 37.7842 @@ -8643,7 +7726,7 @@
 37.7843  msgstr ""
 37.7844  
 37.7845  #. type: Content of: <book><chapter><sect1><para>
 37.7846 -#: ../en/ch08-branch.xml:395
 37.7847 +#: ../en/ch07-branch.xml:395
 37.7848  msgid ""
 37.7849  "The <command role=\"hg-cmd\">hg log</command>-like commands will print the "
 37.7850  "branch name of every changeset that's not on the <literal>default</literal> "
 37.7851 @@ -8652,7 +7735,7 @@
 37.7852  msgstr ""
 37.7853  
 37.7854  #. type: Content of: <book><chapter><sect1><para>
 37.7855 -#: ../en/ch08-branch.xml:400
 37.7856 +#: ../en/ch07-branch.xml:400
 37.7857  msgid ""
 37.7858  "Once you've named a branch and committed a change with that name, every "
 37.7859  "subsequent commit that descends from that change will inherit the same branch "
 37.7860 @@ -8661,19 +7744,19 @@
 37.7861  msgstr ""
 37.7862  
 37.7863  #. type: Content of: <book><chapter><sect1><para>
 37.7864 -#: ../en/ch08-branch.xml:408
 37.7865 +#: ../en/ch07-branch.xml:408
 37.7866  msgid ""
 37.7867  "In practice, this is something you won't do very often, as branch names tend "
 37.7868  "to have fairly long lifetimes.  (This isn't a rule, just an observation.)"
 37.7869  msgstr ""
 37.7870  
 37.7871  #. type: Content of: <book><chapter><sect1><title>
 37.7872 -#: ../en/ch08-branch.xml:414
 37.7873 +#: ../en/ch07-branch.xml:414
 37.7874  msgid "Dealing with multiple named branches in a repository"
 37.7875  msgstr "在版本库中处理多个命名分支"
 37.7876  
 37.7877  #. type: Content of: <book><chapter><sect1><para>
 37.7878 -#: ../en/ch08-branch.xml:417
 37.7879 +#: ../en/ch07-branch.xml:417
 37.7880  msgid ""
 37.7881  "If you have more than one named branch in a repository, Mercurial will "
 37.7882  "remember the branch that your working directory on when you start a command "
 37.7883 @@ -8686,7 +7769,7 @@
 37.7884  msgstr ""
 37.7885  
 37.7886  #. type: Content of: <book><chapter><sect1><para>
 37.7887 -#: ../en/ch08-branch.xml:427
 37.7888 +#: ../en/ch07-branch.xml:427
 37.7889  msgid ""
 37.7890  "This behaviour is a little subtle, so let's see it in action.  First, let's "
 37.7891  "remind ourselves what branch we're currently on, and what branches are in our "
 37.7892 @@ -8694,14 +7777,14 @@
 37.7893  msgstr ""
 37.7894  
 37.7895  #. type: Content of: <book><chapter><sect1><para>
 37.7896 -#: ../en/ch08-branch.xml:433
 37.7897 +#: ../en/ch07-branch.xml:433
 37.7898  msgid ""
 37.7899  "We're on the <literal>bar</literal> branch, but there also exists an older "
 37.7900  "<command role=\"hg-cmd\">hg foo</command> branch."
 37.7901  msgstr ""
 37.7902  
 37.7903  #. type: Content of: <book><chapter><sect1><para>
 37.7904 -#: ../en/ch08-branch.xml:437
 37.7905 +#: ../en/ch07-branch.xml:437
 37.7906  msgid ""
 37.7907  "We can <command role=\"hg-cmd\">hg update</command> back and forth between "
 37.7908  "the tips of the <literal>foo</literal> and <literal>bar</literal> branches "
 37.7909 @@ -8712,7 +7795,7 @@
 37.7910  
 37.7911  #
 37.7912  #. type: Content of: <book><chapter><sect1><para>
 37.7913 -#: ../en/ch08-branch.xml:446
 37.7914 +#: ../en/ch07-branch.xml:446
 37.7915  msgid ""
 37.7916  "If we go back to the <literal>foo</literal> branch and then run <command role="
 37.7917  "\"hg-cmd\">hg update</command>, it will keep us on <literal>foo</literal>, "
 37.7918 @@ -8721,19 +7804,19 @@
 37.7919  
 37.7920  #
 37.7921  #. type: Content of: <book><chapter><sect1><para>
 37.7922 -#: ../en/ch08-branch.xml:453
 37.7923 +#: ../en/ch07-branch.xml:453
 37.7924  msgid ""
 37.7925  "Committing a new change on the <literal>foo</literal> branch introduces a new "
 37.7926  "head."
 37.7927  msgstr ""
 37.7928  
 37.7929  #. type: Content of: <book><chapter><sect1><title>
 37.7930 -#: ../en/ch08-branch.xml:460
 37.7931 +#: ../en/ch07-branch.xml:460
 37.7932  msgid "Branch names and merging"
 37.7933  msgstr "分支名称与合并"
 37.7934  
 37.7935  #. type: Content of: <book><chapter><sect1><para>
 37.7936 -#: ../en/ch08-branch.xml:462
 37.7937 +#: ../en/ch07-branch.xml:462
 37.7938  msgid ""
 37.7939  "As you've probably noticed, merges in Mercurial are not symmetrical. Let's "
 37.7940  "say our repository has two heads, 17 and 23.  If I <command role=\"hg-cmd"
 37.7941 @@ -8745,7 +7828,7 @@
 37.7942  msgstr ""
 37.7943  
 37.7944  #. type: Content of: <book><chapter><sect1><para>
 37.7945 -#: ../en/ch08-branch.xml:472
 37.7946 +#: ../en/ch07-branch.xml:472
 37.7947  msgid ""
 37.7948  "This affects Mercurial's choice of branch name when you merge.  After a "
 37.7949  "merge, Mercurial will retain the branch name of the first parent when you "
 37.7950 @@ -8755,7 +7838,7 @@
 37.7951  msgstr ""
 37.7952  
 37.7953  #. type: Content of: <book><chapter><sect1><para>
 37.7954 -#: ../en/ch08-branch.xml:479
 37.7955 +#: ../en/ch07-branch.xml:479
 37.7956  msgid ""
 37.7957  "It's not unusual for a repository to contain multiple heads, each with the "
 37.7958  "same branch name.  Let's say I'm working on the <literal>foo</literal> "
 37.7959 @@ -8767,7 +7850,7 @@
 37.7960  
 37.7961  #
 37.7962  #. type: Content of: <book><chapter><sect1><para>
 37.7963 -#: ../en/ch08-branch.xml:487
 37.7964 +#: ../en/ch07-branch.xml:487
 37.7965  msgid ""
 37.7966  "But if I'm working on the <literal>bar</literal> branch, and I merge work "
 37.7967  "from the <literal>foo</literal> branch, the result will remain on the "
 37.7968 @@ -8775,7 +7858,7 @@
 37.7969  msgstr ""
 37.7970  
 37.7971  #. type: Content of: <book><chapter><sect1><para>
 37.7972 -#: ../en/ch08-branch.xml:493
 37.7973 +#: ../en/ch07-branch.xml:493
 37.7974  msgid ""
 37.7975  "To give a more concrete example, if I'm working on the <literal>bleeding-"
 37.7976  "edge</literal> branch, and I want to bring in the latest fixes from the "
 37.7977 @@ -8785,12 +7868,12 @@
 37.7978  msgstr ""
 37.7979  
 37.7980  #. type: Content of: <book><chapter><sect1><title>
 37.7981 -#: ../en/ch08-branch.xml:502
 37.7982 +#: ../en/ch07-branch.xml:502
 37.7983  msgid "Branch naming is generally useful"
 37.7984  msgstr "分支名称通常都很有用"
 37.7985  
 37.7986  #. type: Content of: <book><chapter><sect1><para>
 37.7987 -#: ../en/ch08-branch.xml:504
 37.7988 +#: ../en/ch07-branch.xml:504
 37.7989  msgid ""
 37.7990  "You shouldn't think of named branches as applicable only to situations where "
 37.7991  "you have multiple long-lived branches cohabiting in a single repository.  "
 37.7992 @@ -8798,7 +7881,7 @@
 37.7993  msgstr ""
 37.7994  
 37.7995  #. type: Content of: <book><chapter><sect1><para>
 37.7996 -#: ../en/ch08-branch.xml:509
 37.7997 +#: ../en/ch07-branch.xml:509
 37.7998  msgid ""
 37.7999  "In the simplest case, giving a name to each branch gives you a permanent "
 37.8000  "record of which branch a changeset originated on.  This gives you more "
 37.8001 @@ -8807,7 +7890,7 @@
 37.8002  msgstr ""
 37.8003  
 37.8004  #. type: Content of: <book><chapter><sect1><para>
 37.8005 -#: ../en/ch08-branch.xml:514
 37.8006 +#: ../en/ch07-branch.xml:514
 37.8007  msgid ""
 37.8008  "If you're working with shared repositories, you can set up a <literal role="
 37.8009  "\"hook\">pretxnchangegroup</literal> hook on each that will block incoming "
 37.8010 @@ -8819,12 +7902,12 @@
 37.8011  msgstr ""
 37.8012  
 37.8013  #. type: Content of: <book><chapter><title>
 37.8014 -#: ../en/ch09-undo.xml:5
 37.8015 +#: ../en/ch08-undo.xml:5
 37.8016  msgid "Finding and fixing mistakes"
 37.8017  msgstr "查找和修改错误"
 37.8018  
 37.8019  #. type: Content of: <book><chapter><para>
 37.8020 -#: ../en/ch09-undo.xml:7
 37.8021 +#: ../en/ch08-undo.xml:7
 37.8022  msgid ""
 37.8023  "To err might be human, but to really handle the consequences well takes a top-"
 37.8024  "notch revision control system.  In this chapter, we'll discuss some of the "
 37.8025 @@ -8834,17 +7917,17 @@
 37.8026  msgstr ""
 37.8027  
 37.8028  #. type: Content of: <book><chapter><sect1><title>
 37.8029 -#: ../en/ch09-undo.xml:15
 37.8030 +#: ../en/ch08-undo.xml:15
 37.8031  msgid "Erasing local history"
 37.8032  msgstr "销毁本地历史"
 37.8033  
 37.8034  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.8035 -#: ../en/ch09-undo.xml:18
 37.8036 +#: ../en/ch08-undo.xml:18
 37.8037  msgid "The accidental commit"
 37.8038  msgstr "意外的提交"
 37.8039  
 37.8040  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8041 -#: ../en/ch09-undo.xml:20
 37.8042 +#: ../en/ch08-undo.xml:20
 37.8043  msgid ""
 37.8044  "I have the occasional but persistent problem of typing rather more quickly "
 37.8045  "than I can think, which sometimes results in me committing a changeset that "
 37.8046 @@ -8855,12 +7938,12 @@
 37.8047  msgstr ""
 37.8048  
 37.8049  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.8050 -#: ../en/ch09-undo.xml:31
 37.8051 +#: ../en/ch08-undo.xml:31
 37.8052  msgid "Rolling back a transaction"
 37.8053  msgstr "回滚一个事务"
 37.8054  
 37.8055  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8056 -#: ../en/ch09-undo.xml:33
 37.8057 +#: ../en/ch08-undo.xml:33
 37.8058  msgid ""
 37.8059  "In section <xref linkend=\"sec.concepts.txn\"/>, I mentioned that Mercurial "
 37.8060  "treats each modification of a repository as a <emphasis>transaction</"
 37.8061 @@ -8873,7 +7956,7 @@
 37.8062  msgstr ""
 37.8063  
 37.8064  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8065 -#: ../en/ch09-undo.xml:43
 37.8066 +#: ../en/ch08-undo.xml:43
 37.8067  msgid ""
 37.8068  "Here's a mistake that I often find myself making: committing a change in "
 37.8069  "which I've created a new file, but forgotten to <command role=\"hg-cmd\">hg "
 37.8070 @@ -8881,14 +7964,14 @@
 37.8071  msgstr ""
 37.8072  
 37.8073  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8074 -#: ../en/ch09-undo.xml:50
 37.8075 +#: ../en/ch08-undo.xml:50
 37.8076  msgid ""
 37.8077  "Looking at the output of <command role=\"hg-cmd\">hg status</command> after "
 37.8078  "the commit immediately confirms the error."
 37.8079  msgstr ""
 37.8080  
 37.8081  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8082 -#: ../en/ch09-undo.xml:56
 37.8083 +#: ../en/ch08-undo.xml:56
 37.8084  msgid ""
 37.8085  "The commit captured the changes to the file <filename>a</filename>, but not "
 37.8086  "the new file <filename>b</filename>.  If I were to push this changeset to a "
 37.8087 @@ -8899,7 +7982,7 @@
 37.8088  msgstr ""
 37.8089  
 37.8090  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8091 -#: ../en/ch09-undo.xml:65
 37.8092 +#: ../en/ch08-undo.xml:65
 37.8093  msgid ""
 37.8094  "However, luck is with me&emdash;I've caught my error before I pushed the "
 37.8095  "changeset.  I use the <command role=\"hg-cmd\">hg rollback</command> command, "
 37.8096 @@ -8907,7 +7990,7 @@
 37.8097  msgstr ""
 37.8098  
 37.8099  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8100 -#: ../en/ch09-undo.xml:72
 37.8101 +#: ../en/ch08-undo.xml:72
 37.8102  msgid ""
 37.8103  "Notice that the changeset is no longer present in the repository's history, "
 37.8104  "and the working directory once again thinks that the file <filename>a</"
 37.8105 @@ -8918,12 +8001,12 @@
 37.8106  msgstr ""
 37.8107  
 37.8108  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.8109 -#: ../en/ch09-undo.xml:85
 37.8110 +#: ../en/ch08-undo.xml:85
 37.8111  msgid "The erroneous pull"
 37.8112  msgstr "错误的抓取"
 37.8113  
 37.8114  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8115 -#: ../en/ch09-undo.xml:87
 37.8116 +#: ../en/ch08-undo.xml:87
 37.8117  msgid ""
 37.8118  "It's common practice with Mercurial to maintain separate development branches "
 37.8119  "of a project in different repositories.  Your development team might have one "
 37.8120 @@ -8932,7 +8015,7 @@
 37.8121  msgstr ""
 37.8122  
 37.8123  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8124 -#: ../en/ch09-undo.xml:94
 37.8125 +#: ../en/ch08-undo.xml:94
 37.8126  msgid ""
 37.8127  "Given this, you can imagine that the consequences could be messy if you had a "
 37.8128  "local <quote>0.9</quote> repository, and accidentally pulled changes from the "
 37.8129 @@ -8945,7 +8028,7 @@
 37.8130  msgstr ""
 37.8131  
 37.8132  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8133 -#: ../en/ch09-undo.xml:106
 37.8134 +#: ../en/ch08-undo.xml:106
 37.8135  msgid ""
 37.8136  "The <command role=\"hg-cmd\">hg rollback</command> command will work nicely "
 37.8137  "to expunge all of the changesets that you just pulled.  Mercurial groups all "
 37.8138 @@ -8955,12 +8038,12 @@
 37.8139  msgstr ""
 37.8140  
 37.8141  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.8142 -#: ../en/ch09-undo.xml:115
 37.8143 +#: ../en/ch08-undo.xml:115
 37.8144  msgid "Rolling back is useless once you've pushed"
 37.8145  msgstr "当完成推送后,回滚是无效的"
 37.8146  
 37.8147  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8148 -#: ../en/ch09-undo.xml:117
 37.8149 +#: ../en/ch08-undo.xml:117
 37.8150  msgid ""
 37.8151  "The value of the <command role=\"hg-cmd\">hg rollback</command> command drops "
 37.8152  "to zero once you've pushed your changes to another repository.  Rolling back "
 37.8153 @@ -8971,7 +8054,7 @@
 37.8154  msgstr ""
 37.8155  
 37.8156  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8157 -#: ../en/ch09-undo.xml:126
 37.8158 +#: ../en/ch08-undo.xml:126
 37.8159  msgid ""
 37.8160  "If you've pushed a change to another repository&emdash;particularly if it's a "
 37.8161  "shared repository&emdash;it has essentially <quote>escaped into the wild,</"
 37.8162 @@ -8982,7 +8065,7 @@
 37.8163  msgstr ""
 37.8164  
 37.8165  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8166 -#: ../en/ch09-undo.xml:135
 37.8167 +#: ../en/ch08-undo.xml:135
 37.8168  msgid ""
 37.8169  "(If you absolutely know for sure that the change you want to roll back is the "
 37.8170  "most recent change in the repository that you pushed to, <emphasis>and</"
 37.8171 @@ -8994,12 +8077,12 @@
 37.8172  msgstr ""
 37.8173  
 37.8174  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.8175 -#: ../en/ch09-undo.xml:147
 37.8176 +#: ../en/ch08-undo.xml:147
 37.8177  msgid "You can only roll back once"
 37.8178  msgstr "你只能回滚一次"
 37.8179  
 37.8180  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8181 -#: ../en/ch09-undo.xml:149
 37.8182 +#: ../en/ch08-undo.xml:149
 37.8183  msgid ""
 37.8184  "Mercurial stores exactly one transaction in its transaction log; that "
 37.8185  "transaction is the most recent one that occurred in the repository. This "
 37.8186 @@ -9009,19 +8092,19 @@
 37.8187  msgstr ""
 37.8188  
 37.8189  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8190 -#: ../en/ch09-undo.xml:158
 37.8191 +#: ../en/ch08-undo.xml:158
 37.8192  msgid ""
 37.8193  "Once you've rolled back one transaction in a repository, you can't roll back "
 37.8194  "again in that repository until you perform another commit or pull."
 37.8195  msgstr ""
 37.8196  
 37.8197  #. type: Content of: <book><chapter><sect1><title>
 37.8198 -#: ../en/ch09-undo.xml:165
 37.8199 +#: ../en/ch08-undo.xml:165
 37.8200  msgid "Reverting the mistaken change"
 37.8201  msgstr "撤销错误的修改"
 37.8202  
 37.8203  #. type: Content of: <book><chapter><sect1><para>
 37.8204 -#: ../en/ch09-undo.xml:167
 37.8205 +#: ../en/ch08-undo.xml:167
 37.8206  msgid ""
 37.8207  "If you make a modification to a file, and decide that you really didn't want "
 37.8208  "to change the file at all, and you haven't yet committed your changes, the "
 37.8209 @@ -9033,7 +8116,7 @@
 37.8210  msgstr ""
 37.8211  
 37.8212  #. type: Content of: <book><chapter><sect1><para>
 37.8213 -#: ../en/ch09-undo.xml:176
 37.8214 +#: ../en/ch08-undo.xml:176
 37.8215  msgid ""
 37.8216  "Let's illustrate how the <command role=\"hg-cmd\">hg revert</command> command "
 37.8217  "works with yet another small example.  We'll begin by modifying a file that "
 37.8218 @@ -9041,14 +8124,14 @@
 37.8219  msgstr ""
 37.8220  
 37.8221  #. type: Content of: <book><chapter><sect1><para>
 37.8222 -#: ../en/ch09-undo.xml:183
 37.8223 +#: ../en/ch08-undo.xml:183
 37.8224  msgid ""
 37.8225  "If we don't want that change, we can simply <command role=\"hg-cmd\">hg "
 37.8226  "revert</command> the file."
 37.8227  msgstr ""
 37.8228  
 37.8229  #. type: Content of: <book><chapter><sect1><para>
 37.8230 -#: ../en/ch09-undo.xml:189
 37.8231 +#: ../en/ch08-undo.xml:189
 37.8232  msgid ""
 37.8233  "The <command role=\"hg-cmd\">hg revert</command> command provides us with an "
 37.8234  "extra degree of safety by saving our modified file with a <filename>.orig</"
 37.8235 @@ -9056,7 +8139,7 @@
 37.8236  msgstr ""
 37.8237  
 37.8238  #. type: Content of: <book><chapter><sect1><para>
 37.8239 -#: ../en/ch09-undo.xml:196
 37.8240 +#: ../en/ch08-undo.xml:196
 37.8241  msgid ""
 37.8242  "Here is a summary of the cases that the <command role=\"hg-cmd\">hg revert</"
 37.8243  "command> command can deal with.  We will describe each of these in more "
 37.8244 @@ -9064,26 +8147,26 @@
 37.8245  msgstr ""
 37.8246  
 37.8247  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.8248 -#: ../en/ch09-undo.xml:201
 37.8249 +#: ../en/ch08-undo.xml:201
 37.8250  msgid "If you modify a file, it will restore the file to its unmodified state."
 37.8251  msgstr ""
 37.8252  
 37.8253  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.8254 -#: ../en/ch09-undo.xml:204
 37.8255 +#: ../en/ch08-undo.xml:204
 37.8256  msgid ""
 37.8257  "If you <command role=\"hg-cmd\">hg add</command> a file, it will undo the "
 37.8258  "<quote>added</quote> state of the file, but leave the file itself untouched."
 37.8259  msgstr ""
 37.8260  
 37.8261  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.8262 -#: ../en/ch09-undo.xml:208
 37.8263 +#: ../en/ch08-undo.xml:208
 37.8264  msgid ""
 37.8265  "If you delete a file without telling Mercurial, it will restore the file to "
 37.8266  "its unmodified contents."
 37.8267  msgstr ""
 37.8268  
 37.8269  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.8270 -#: ../en/ch09-undo.xml:211
 37.8271 +#: ../en/ch08-undo.xml:211
 37.8272  msgid ""
 37.8273  "If you use the <command role=\"hg-cmd\">hg remove</command> command to remove "
 37.8274  "a file, it will undo the <quote>removed</quote> state of the file, and "
 37.8275 @@ -9091,12 +8174,12 @@
 37.8276  msgstr ""
 37.8277  
 37.8278  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.8279 -#: ../en/ch09-undo.xml:218
 37.8280 +#: ../en/ch08-undo.xml:218
 37.8281  msgid "File management errors"
 37.8282  msgstr "文件管理错误"
 37.8283  
 37.8284  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8285 -#: ../en/ch09-undo.xml:220
 37.8286 +#: ../en/ch08-undo.xml:220
 37.8287  msgid ""
 37.8288  "The <command role=\"hg-cmd\">hg revert</command> command is useful for more "
 37.8289  "than just modified files.  It lets you reverse the results of all of "
 37.8290 @@ -9106,7 +8189,7 @@
 37.8291  
 37.8292  #
 37.8293  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8294 -#: ../en/ch09-undo.xml:226
 37.8295 +#: ../en/ch08-undo.xml:226
 37.8296  msgid ""
 37.8297  "If you <command role=\"hg-cmd\">hg add</command> a file, then decide that in "
 37.8298  "fact you don't want Mercurial to track it, use <command role=\"hg-cmd\">hg "
 37.8299 @@ -9115,7 +8198,7 @@
 37.8300  msgstr ""
 37.8301  
 37.8302  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8303 -#: ../en/ch09-undo.xml:234
 37.8304 +#: ../en/ch08-undo.xml:234
 37.8305  msgid ""
 37.8306  "Similarly, if you ask Mercurial to <command role=\"hg-cmd\">hg remove</"
 37.8307  "command> a file, you can use <command role=\"hg-cmd\">hg revert</command> to "
 37.8308 @@ -9127,7 +8210,7 @@
 37.8309  
 37.8310  #
 37.8311  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8312 -#: ../en/ch09-undo.xml:245
 37.8313 +#: ../en/ch08-undo.xml:245
 37.8314  msgid ""
 37.8315  "If you revert a <command role=\"hg-cmd\">hg copy</command>, the copied-to "
 37.8316  "file remains in your working directory afterwards, untracked.  Since a copy "
 37.8317 @@ -9136,12 +8219,12 @@
 37.8318  msgstr ""
 37.8319  
 37.8320  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
 37.8321 -#: ../en/ch09-undo.xml:254
 37.8322 +#: ../en/ch08-undo.xml:254
 37.8323  msgid "A slightly special case: reverting a rename"
 37.8324  msgstr "一个稍微特别的案例:撤销改名"
 37.8325  
 37.8326  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.8327 -#: ../en/ch09-undo.xml:256
 37.8328 +#: ../en/ch08-undo.xml:256
 37.8329  msgid ""
 37.8330  "If you <command role=\"hg-cmd\">hg rename</command> a file, there is one "
 37.8331  "small detail that you should remember.  When you <command role=\"hg-cmd\">hg "
 37.8332 @@ -9150,7 +8233,7 @@
 37.8333  msgstr ""
 37.8334  
 37.8335  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.8336 -#: ../en/ch09-undo.xml:264
 37.8337 +#: ../en/ch08-undo.xml:264
 37.8338  msgid ""
 37.8339  "As you can see from the output of <command role=\"hg-cmd\">hg status</"
 37.8340  "command>, the renamed-to file is no longer identified as added, but the "
 37.8341 @@ -9159,19 +8242,19 @@
 37.8342  msgstr ""
 37.8343  
 37.8344  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.8345 -#: ../en/ch09-undo.xml:273
 37.8346 +#: ../en/ch08-undo.xml:273
 37.8347  msgid ""
 37.8348  "So remember, to revert a <command role=\"hg-cmd\">hg rename</command>, you "
 37.8349  "must provide <emphasis>both</emphasis> the source and destination names."
 37.8350  msgstr ""
 37.8351  
 37.8352  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.8353 -#: ../en/ch09-undo.xml:278
 37.8354 +#: ../en/ch08-undo.xml:278
 37.8355  msgid "% TODO: the output doesn't look like it will be removed!"
 37.8356  msgstr ""
 37.8357  
 37.8358  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.8359 -#: ../en/ch09-undo.xml:281
 37.8360 +#: ../en/ch08-undo.xml:281
 37.8361  msgid ""
 37.8362  "(By the way, if you rename a file, then modify the renamed-to file, then "
 37.8363  "revert both components of the rename, when Mercurial restores the file that "
 37.8364 @@ -9181,19 +8264,19 @@
 37.8365  msgstr ""
 37.8366  
 37.8367  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.8368 -#: ../en/ch09-undo.xml:288
 37.8369 +#: ../en/ch08-undo.xml:288
 37.8370  msgid ""
 37.8371  "These fiddly aspects of reverting a rename arguably constitute a small bug in "
 37.8372  "Mercurial."
 37.8373  msgstr ""
 37.8374  
 37.8375  #. type: Content of: <book><chapter><sect1><title>
 37.8376 -#: ../en/ch09-undo.xml:295
 37.8377 +#: ../en/ch08-undo.xml:295
 37.8378  msgid "Dealing with committed changes"
 37.8379  msgstr "处理已经提交的修改"
 37.8380  
 37.8381  #. type: Content of: <book><chapter><sect1><para>
 37.8382 -#: ../en/ch09-undo.xml:297
 37.8383 +#: ../en/ch08-undo.xml:297
 37.8384  msgid ""
 37.8385  "Consider a case where you have committed a change $a$, and another change $b$ "
 37.8386  "on top of it; you then realise that change $a$ was incorrect.  Mercurial lets "
 37.8387 @@ -9202,7 +8285,7 @@
 37.8388  msgstr ""
 37.8389  
 37.8390  #. type: Content of: <book><chapter><sect1><para>
 37.8391 -#: ../en/ch09-undo.xml:303
 37.8392 +#: ../en/ch08-undo.xml:303
 37.8393  msgid ""
 37.8394  "Before you read this section, here's something to keep in mind: the <command "
 37.8395  "role=\"hg-cmd\">hg backout</command> command undoes changes by "
 37.8396 @@ -9213,12 +8296,12 @@
 37.8397  msgstr ""
 37.8398  
 37.8399  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.8400 -#: ../en/ch09-undo.xml:312
 37.8401 +#: ../en/ch08-undo.xml:312
 37.8402  msgid "Backing out a changeset"
 37.8403  msgstr "恢复一个修改集"
 37.8404  
 37.8405  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8406 -#: ../en/ch09-undo.xml:314
 37.8407 +#: ../en/ch08-undo.xml:314
 37.8408  msgid ""
 37.8409  "The <command role=\"hg-cmd\">hg backout</command> command lets you "
 37.8410  "<quote>undo</quote> the effects of an entire changeset in an automated "
 37.8411 @@ -9230,7 +8313,7 @@
 37.8412  
 37.8413  #
 37.8414  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8415 -#: ../en/ch09-undo.xml:323
 37.8416 +#: ../en/ch08-undo.xml:323
 37.8417  msgid ""
 37.8418  "The operation of the <command role=\"hg-cmd\">hg backout</command> command is "
 37.8419  "a little intricate, so let's illustrate it with some examples.  First, we'll "
 37.8420 @@ -9238,7 +8321,7 @@
 37.8421  msgstr ""
 37.8422  
 37.8423  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8424 -#: ../en/ch09-undo.xml:330
 37.8425 +#: ../en/ch08-undo.xml:330
 37.8426  msgid ""
 37.8427  "The <command role=\"hg-cmd\">hg backout</command> command takes a single "
 37.8428  "changeset ID as its argument; this is the changeset to back out.  Normally, "
 37.8429 @@ -9249,17 +8332,17 @@
 37.8430  msgstr ""
 37.8431  
 37.8432  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.8433 -#: ../en/ch09-undo.xml:341
 37.8434 +#: ../en/ch08-undo.xml:341
 37.8435  msgid "Backing out the tip changeset"
 37.8436  msgstr "恢复顶点修改集"
 37.8437  
 37.8438  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8439 -#: ../en/ch09-undo.xml:343
 37.8440 +#: ../en/ch08-undo.xml:343
 37.8441  msgid "We're going to start by backing out the last changeset we committed."
 37.8442  msgstr ""
 37.8443  
 37.8444  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8445 -#: ../en/ch09-undo.xml:348
 37.8446 +#: ../en/ch08-undo.xml:348
 37.8447  msgid ""
 37.8448  "You can see that the second line from <filename>myfile</filename> is no "
 37.8449  "longer present.  Taking a look at the output of <command role=\"hg-cmd\">hg "
 37.8450 @@ -9273,25 +8356,25 @@
 37.8451  msgstr ""
 37.8452  
 37.8453  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
 37.8454 -#: ../en/ch09-undo.xml:364
 37.8455 +#: ../en/ch08-undo.xml:364
 37.8456  msgid ""
 37.8457  "<imageobject><imagedata fileref=\"images/undo-simple.png\"/> </imageobject>"
 37.8458  msgstr ""
 37.8459  
 37.8460  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
 37.8461 -#: ../en/ch09-undo.xml:367 ../en/ch09-undo.xml:486
 37.8462 +#: ../en/ch08-undo.xml:367 ../en/ch08-undo.xml:486
 37.8463  msgid ""
 37.8464  "Backing out a change using the <command role=\"hg-cmd\">hg backout</command> "
 37.8465  "command"
 37.8466  msgstr ""
 37.8467  
 37.8468  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.8469 -#: ../en/ch09-undo.xml:376
 37.8470 +#: ../en/ch08-undo.xml:376
 37.8471  msgid "Backing out a non-tip change"
 37.8472  msgstr "恢复非顶点的修改"
 37.8473  
 37.8474  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8475 -#: ../en/ch09-undo.xml:378
 37.8476 +#: ../en/ch08-undo.xml:378
 37.8477  msgid ""
 37.8478  "If you want to back out a change other than the last one you committed, pass "
 37.8479  "the <option role=\"hg-opt-backout\">--merge</option> option to the <command "
 37.8480 @@ -9299,14 +8382,14 @@
 37.8481  msgstr ""
 37.8482  
 37.8483  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8484 -#: ../en/ch09-undo.xml:385
 37.8485 +#: ../en/ch08-undo.xml:385
 37.8486  msgid ""
 37.8487  "This makes backing out any changeset a <quote>one-shot</quote> operation "
 37.8488  "that's usually simple and fast."
 37.8489  msgstr ""
 37.8490  
 37.8491  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8492 -#: ../en/ch09-undo.xml:391
 37.8493 +#: ../en/ch08-undo.xml:391
 37.8494  msgid ""
 37.8495  "If you take a look at the contents of <filename>myfile</filename> after the "
 37.8496  "backout finishes, you'll see that the first and third changes are present, "
 37.8497 @@ -9314,7 +8397,7 @@
 37.8498  msgstr ""
 37.8499  
 37.8500  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8501 -#: ../en/ch09-undo.xml:398
 37.8502 +#: ../en/ch08-undo.xml:398
 37.8503  msgid ""
 37.8504  "As the graphical history in figure <xref endterm=\"fig.undo.backout-non-tip."
 37.8505  "caption\" linkend=\"fig.undo.backout-non-tip\"/> illustrates, Mercurial "
 37.8506 @@ -9327,27 +8410,27 @@
 37.8507  msgstr ""
 37.8508  
 37.8509  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8510 -#: ../en/ch09-undo.xml:410
 37.8511 +#: ../en/ch08-undo.xml:410
 37.8512  msgid ""
 37.8513  "% TODO: to me it looks like mercurial doesn't commit the second merge "
 37.8514  "automatically!"
 37.8515  msgstr ""
 37.8516  
 37.8517  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
 37.8518 -#: ../en/ch09-undo.xml:415
 37.8519 +#: ../en/ch08-undo.xml:415
 37.8520  msgid ""
 37.8521  "<imageobject><imagedata fileref=\"images/undo-non-tip.png\"/> </imageobject>"
 37.8522  msgstr ""
 37.8523  
 37.8524  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
 37.8525 -#: ../en/ch09-undo.xml:418
 37.8526 +#: ../en/ch08-undo.xml:418
 37.8527  msgid ""
 37.8528  "Automated backout of a non-tip change using the <command role=\"hg-cmd\">hg "
 37.8529  "backout</command> command"
 37.8530  msgstr ""
 37.8531  
 37.8532  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8533 -#: ../en/ch09-undo.xml:424
 37.8534 +#: ../en/ch08-undo.xml:424
 37.8535  msgid ""
 37.8536  "The result is that you end up <quote>back where you were</quote>, only with "
 37.8537  "some extra history that undoes the effect of the changeset you wanted to back "
 37.8538 @@ -9355,12 +8438,12 @@
 37.8539  msgstr ""
 37.8540  
 37.8541  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
 37.8542 -#: ../en/ch09-undo.xml:429
 37.8543 +#: ../en/ch08-undo.xml:429
 37.8544  msgid "Always use the <option role=\"hg-opt-backout\">--merge</option> option"
 37.8545  msgstr "始终使用选项 <option role=\"hg-opt-backout\">--merge</option>"
 37.8546  
 37.8547  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
 37.8548 -#: ../en/ch09-undo.xml:432
 37.8549 +#: ../en/ch08-undo.xml:432
 37.8550  msgid ""
 37.8551  "In fact, since the <option role=\"hg-opt-backout\">--merge</option> option "
 37.8552  "will do the <quote>right thing</quote> whether or not the changeset you're "
 37.8553 @@ -9370,12 +8453,12 @@
 37.8554  msgstr ""
 37.8555  
 37.8556  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.8557 -#: ../en/ch09-undo.xml:443
 37.8558 +#: ../en/ch08-undo.xml:443
 37.8559  msgid "Gaining more control of the backout process"
 37.8560  msgstr "在恢复处理中获得更多控制"
 37.8561  
 37.8562  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8563 -#: ../en/ch09-undo.xml:445
 37.8564 +#: ../en/ch08-undo.xml:445
 37.8565  msgid ""
 37.8566  "While I've recommended that you always use the <option role=\"hg-opt-backout"
 37.8567  "\">--merge</option> option when backing out a change, the <command role=\"hg-"
 37.8568 @@ -9388,14 +8471,14 @@
 37.8569  msgstr ""
 37.8570  
 37.8571  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8572 -#: ../en/ch09-undo.xml:458
 37.8573 +#: ../en/ch08-undo.xml:458
 37.8574  msgid ""
 37.8575  "As with our earlier example, We'll commit a third changeset, then back out "
 37.8576  "its parent, and see what happens."
 37.8577  msgstr ""
 37.8578  
 37.8579  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8580 -#: ../en/ch09-undo.xml:464
 37.8581 +#: ../en/ch08-undo.xml:464
 37.8582  msgid ""
 37.8583  "Our new changeset is again a descendant of the changeset we backout out; it's "
 37.8584  "thus a new head, <emphasis>not</emphasis> a descendant of the changeset that "
 37.8585 @@ -9404,7 +8487,7 @@
 37.8586  msgstr ""
 37.8587  
 37.8588  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8589 -#: ../en/ch09-undo.xml:472
 37.8590 +#: ../en/ch08-undo.xml:472
 37.8591  msgid ""
 37.8592  "Again, it's easier to see what has happened by looking at a graph of the "
 37.8593  "revision history, in figure <xref endterm=\"fig.undo.backout-manual.caption\" "
 37.8594 @@ -9415,13 +8498,13 @@
 37.8595  msgstr ""
 37.8596  
 37.8597  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
 37.8598 -#: ../en/ch09-undo.xml:483
 37.8599 +#: ../en/ch08-undo.xml:483
 37.8600  msgid ""
 37.8601  "<imageobject><imagedata fileref=\"images/undo-manual.png\"/> </imageobject>"
 37.8602  msgstr ""
 37.8603  
 37.8604  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8605 -#: ../en/ch09-undo.xml:492
 37.8606 +#: ../en/ch08-undo.xml:492
 37.8607  msgid ""
 37.8608  "After the <command role=\"hg-cmd\">hg backout</command> command has "
 37.8609  "completed, it leaves the new <quote>backout</quote> changeset as the parent "
 37.8610 @@ -9429,12 +8512,12 @@
 37.8611  msgstr ""
 37.8612  
 37.8613  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8614 -#: ../en/ch09-undo.xml:499
 37.8615 +#: ../en/ch08-undo.xml:499
 37.8616  msgid "Now we have two isolated sets of changes."
 37.8617  msgstr ""
 37.8618  
 37.8619  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8620 -#: ../en/ch09-undo.xml:503
 37.8621 +#: ../en/ch08-undo.xml:503
 37.8622  msgid ""
 37.8623  "Let's think about what we expect to see as the contents of <filename>myfile</"
 37.8624  "filename> now.  The first change should be present, because we've never "
 37.8625 @@ -9445,14 +8528,14 @@
 37.8626  msgstr ""
 37.8627  
 37.8628  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8629 -#: ../en/ch09-undo.xml:513
 37.8630 +#: ../en/ch08-undo.xml:513
 37.8631  msgid ""
 37.8632  "To get the third change back into the file, we just do a normal merge of our "
 37.8633  "two heads."
 37.8634  msgstr ""
 37.8635  
 37.8636  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8637 -#: ../en/ch09-undo.xml:518
 37.8638 +#: ../en/ch08-undo.xml:518
 37.8639  msgid ""
 37.8640  "Afterwards, the graphical history of our repository looks like figure <xref "
 37.8641  "endterm=\"fig.undo.backout-manual-merge.caption\" linkend=\"fig.undo.backout-"
 37.8642 @@ -9460,45 +8543,45 @@
 37.8643  msgstr ""
 37.8644  
 37.8645  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
 37.8646 -#: ../en/ch09-undo.xml:525
 37.8647 +#: ../en/ch08-undo.xml:525
 37.8648  msgid ""
 37.8649  "<imageobject><imagedata fileref=\"images/undo-manual-merge.png\"/> </"
 37.8650  "imageobject>"
 37.8651  msgstr ""
 37.8652  
 37.8653  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
 37.8654 -#: ../en/ch09-undo.xml:528
 37.8655 +#: ../en/ch08-undo.xml:528
 37.8656  msgid "Manually merging a backout change"
 37.8657  msgstr ""
 37.8658  
 37.8659  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.8660 -#: ../en/ch09-undo.xml:535
 37.8661 +#: ../en/ch08-undo.xml:535
 37.8662  msgid "Why <command role=\"hg-cmd\">hg backout</command> works as it does"
 37.8663  msgstr "<command role=\"hg-cmd\">hg backout</command> 的内幕"
 37.8664  
 37.8665  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8666 -#: ../en/ch09-undo.xml:538
 37.8667 +#: ../en/ch08-undo.xml:538
 37.8668  msgid ""
 37.8669  "Here's a brief description of how the <command role=\"hg-cmd\">hg backout</"
 37.8670  "command> command works."
 37.8671  msgstr ""
 37.8672  
 37.8673  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.8674 -#: ../en/ch09-undo.xml:541
 37.8675 +#: ../en/ch08-undo.xml:541
 37.8676  msgid ""
 37.8677  "It ensures that the working directory is <quote>clean</quote>, i.e. that the "
 37.8678  "output of <command role=\"hg-cmd\">hg status</command> would be empty."
 37.8679  msgstr ""
 37.8680  
 37.8681  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.8682 -#: ../en/ch09-undo.xml:545
 37.8683 +#: ../en/ch08-undo.xml:545
 37.8684  msgid ""
 37.8685  "It remembers the current parent of the working directory.  Let's call this "
 37.8686  "changeset <literal>orig</literal>"
 37.8687  msgstr ""
 37.8688  
 37.8689  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.8690 -#: ../en/ch09-undo.xml:549
 37.8691 +#: ../en/ch08-undo.xml:549
 37.8692  msgid ""
 37.8693  "It does the equivalent of a <command role=\"hg-cmd\">hg update</command> to "
 37.8694  "sync the working directory to the changeset you want to back out.  Let's call "
 37.8695 @@ -9506,14 +8589,14 @@
 37.8696  msgstr ""
 37.8697  
 37.8698  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.8699 -#: ../en/ch09-undo.xml:554
 37.8700 +#: ../en/ch08-undo.xml:554
 37.8701  msgid ""
 37.8702  "It finds the parent of that changeset.  Let's call that changeset "
 37.8703  "<literal>parent</literal>."
 37.8704  msgstr ""
 37.8705  
 37.8706  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.8707 -#: ../en/ch09-undo.xml:557
 37.8708 +#: ../en/ch08-undo.xml:557
 37.8709  msgid ""
 37.8710  "For each file that the <literal>backout</literal> changeset affected, it does "
 37.8711  "the equivalent of a <command role=\"hg-cmd\">hg revert -r parent</command> on "
 37.8712 @@ -9522,14 +8605,14 @@
 37.8713  msgstr ""
 37.8714  
 37.8715  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.8716 -#: ../en/ch09-undo.xml:564
 37.8717 +#: ../en/ch08-undo.xml:564
 37.8718  msgid ""
 37.8719  "It commits the result as a new changeset.  This changeset has "
 37.8720  "<literal>backout</literal> as its parent."
 37.8721  msgstr ""
 37.8722  
 37.8723  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.8724 -#: ../en/ch09-undo.xml:568
 37.8725 +#: ../en/ch08-undo.xml:568
 37.8726  msgid ""
 37.8727  "If you specify <option role=\"hg-opt-backout\">--merge</option> on the "
 37.8728  "command line, it merges with <literal>orig</literal>, and commits the result "
 37.8729 @@ -9537,7 +8620,7 @@
 37.8730  msgstr ""
 37.8731  
 37.8732  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8733 -#: ../en/ch09-undo.xml:574
 37.8734 +#: ../en/ch08-undo.xml:574
 37.8735  msgid ""
 37.8736  "An alternative way to implement the <command role=\"hg-cmd\">hg backout</"
 37.8737  "command> command would be to <command role=\"hg-cmd\">hg export</command> the "
 37.8738 @@ -9548,7 +8631,7 @@
 37.8739  msgstr ""
 37.8740  
 37.8741  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8742 -#: ../en/ch09-undo.xml:584
 37.8743 +#: ../en/ch08-undo.xml:584
 37.8744  msgid ""
 37.8745  "The reason that <command role=\"hg-cmd\">hg backout</command> does an update, "
 37.8746  "a commit, a merge, and another commit is to give the merge machinery the best "
 37.8747 @@ -9557,7 +8640,7 @@
 37.8748  msgstr ""
 37.8749  
 37.8750  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8751 -#: ../en/ch09-undo.xml:591
 37.8752 +#: ../en/ch08-undo.xml:591
 37.8753  msgid ""
 37.8754  "If you're backing out a changeset that's 100 revisions back in your project's "
 37.8755  "history, the chances that the <command>patch</command> command will be able "
 37.8756 @@ -9572,12 +8655,12 @@
 37.8757  msgstr ""
 37.8758  
 37.8759  #. type: Content of: <book><chapter><sect1><title>
 37.8760 -#: ../en/ch09-undo.xml:608
 37.8761 +#: ../en/ch08-undo.xml:608
 37.8762  msgid "Changes that should never have been"
 37.8763  msgstr "不该发生的修改"
 37.8764  
 37.8765  #. type: Content of: <book><chapter><sect1><para>
 37.8766 -#: ../en/ch09-undo.xml:610
 37.8767 +#: ../en/ch08-undo.xml:610
 37.8768  msgid ""
 37.8769  "Most of the time, the <command role=\"hg-cmd\">hg backout</command> command "
 37.8770  "is exactly what you need if you want to undo the effects of a change.  It "
 37.8771 @@ -9586,7 +8669,7 @@
 37.8772  msgstr ""
 37.8773  
 37.8774  #. type: Content of: <book><chapter><sect1><para>
 37.8775 -#: ../en/ch09-undo.xml:616
 37.8776 +#: ../en/ch08-undo.xml:616
 37.8777  msgid ""
 37.8778  "On rare occasions, though, you may find that you've committed a change that "
 37.8779  "really should not be present in the repository at all.  For example, it would "
 37.8780 @@ -9598,7 +8681,7 @@
 37.8781  msgstr ""
 37.8782  
 37.8783  #. type: Content of: <book><chapter><sect1><para>
 37.8784 -#: ../en/ch09-undo.xml:625
 37.8785 +#: ../en/ch08-undo.xml:625
 37.8786  msgid ""
 37.8787  "Before I discuss the options that you have if you commit a <quote>brown paper "
 37.8788  "bag</quote> change (the kind that's so bad that you want to pull a brown "
 37.8789 @@ -9607,7 +8690,7 @@
 37.8790  msgstr ""
 37.8791  
 37.8792  #. type: Content of: <book><chapter><sect1><para>
 37.8793 -#: ../en/ch09-undo.xml:630
 37.8794 +#: ../en/ch08-undo.xml:630
 37.8795  msgid ""
 37.8796  "Since Mercurial treats history as accumulative&emdash;every change builds on "
 37.8797  "top of all changes that preceded it&emdash;you generally can't just make "
 37.8798 @@ -9619,7 +8702,7 @@
 37.8799  msgstr ""
 37.8800  
 37.8801  #. type: Content of: <book><chapter><sect1><para>
 37.8802 -#: ../en/ch09-undo.xml:639
 37.8803 +#: ../en/ch08-undo.xml:639
 37.8804  msgid ""
 37.8805  "After you've pushed a bad change to another repository, you <emphasis>could</"
 37.8806  "emphasis> still use <command role=\"hg-cmd\">hg rollback</command> to make "
 37.8807 @@ -9629,7 +8712,7 @@
 37.8808  msgstr ""
 37.8809  
 37.8810  #. type: Content of: <book><chapter><sect1><para>
 37.8811 -#: ../en/ch09-undo.xml:647
 37.8812 +#: ../en/ch08-undo.xml:647
 37.8813  msgid ""
 37.8814  "If a situation like this arises, and you know which repositories your bad "
 37.8815  "change has propagated into, you can <emphasis>try</emphasis> to get rid of "
 37.8816 @@ -9640,7 +8723,7 @@
 37.8817  msgstr ""
 37.8818  
 37.8819  #. type: Content of: <book><chapter><sect1><para>
 37.8820 -#: ../en/ch09-undo.xml:655
 37.8821 +#: ../en/ch08-undo.xml:655
 37.8822  msgid ""
 37.8823  "If you've committed one or more changes <emphasis>after</emphasis> the change "
 37.8824  "that you'd like to see disappear, your options are further reduced. Mercurial "
 37.8825 @@ -9649,7 +8732,7 @@
 37.8826  msgstr ""
 37.8827  
 37.8828  #. type: Content of: <book><chapter><sect1><para>
 37.8829 -#: ../en/ch09-undo.xml:661
 37.8830 +#: ../en/ch08-undo.xml:661
 37.8831  msgid ""
 37.8832  "XXX This needs filling out.  The <literal>hg-replay</literal> script in the "
 37.8833  "<literal>examples</literal> directory works, but doesn't handle merge "
 37.8834 @@ -9657,12 +8740,12 @@
 37.8835  msgstr ""
 37.8836  
 37.8837  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.8838 -#: ../en/ch09-undo.xml:667
 37.8839 +#: ../en/ch08-undo.xml:667
 37.8840  msgid "Protect yourself from <quote>escaped</quote> changes"
 37.8841  msgstr "使用<quote>校验</quote>修改来保护你自己"
 37.8842  
 37.8843  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8844 -#: ../en/ch09-undo.xml:670
 37.8845 +#: ../en/ch08-undo.xml:670
 37.8846  msgid ""
 37.8847  "If you've committed some changes to your local repository and they've been "
 37.8848  "pushed or pulled somewhere else, this isn't necessarily a disaster.  You can "
 37.8849 @@ -9672,7 +8755,7 @@
 37.8850  msgstr ""
 37.8851  
 37.8852  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8853 -#: ../en/ch09-undo.xml:677
 37.8854 +#: ../en/ch08-undo.xml:677
 37.8855  msgid ""
 37.8856  "By configuring some hooks on that repository to validate incoming changesets "
 37.8857  "(see chapter <xref linkend=\"chap.hook\"/>), you can automatically prevent "
 37.8858 @@ -9684,7 +8767,7 @@
 37.8859  msgstr ""
 37.8860  
 37.8861  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8862 -#: ../en/ch09-undo.xml:687
 37.8863 +#: ../en/ch08-undo.xml:687
 37.8864  msgid ""
 37.8865  "For instance, an incoming change hook that verifies that a changeset will "
 37.8866  "actually compile can prevent people from inadvertantly <quote>breaking the "
 37.8867 @@ -9692,12 +8775,12 @@
 37.8868  msgstr ""
 37.8869  
 37.8870  #. type: Content of: <book><chapter><sect1><title>
 37.8871 -#: ../en/ch09-undo.xml:694
 37.8872 +#: ../en/ch08-undo.xml:694
 37.8873  msgid "Finding the source of a bug"
 37.8874  msgstr "查找问题的根源"
 37.8875  
 37.8876  #. type: Content of: <book><chapter><sect1><para>
 37.8877 -#: ../en/ch09-undo.xml:696
 37.8878 +#: ../en/ch08-undo.xml:696
 37.8879  msgid ""
 37.8880  "While it's all very well to be able to back out a changeset that introduced a "
 37.8881  "bug, this requires that you know which changeset to back out.  Mercurial "
 37.8882 @@ -9707,7 +8790,7 @@
 37.8883  msgstr ""
 37.8884  
 37.8885  #. type: Content of: <book><chapter><sect1><para>
 37.8886 -#: ../en/ch09-undo.xml:703
 37.8887 +#: ../en/ch08-undo.xml:703
 37.8888  msgid ""
 37.8889  "The idea behind the <command role=\"hg-cmd\">hg bisect</command> command is "
 37.8890  "that a changeset has introduced some change of behaviour that you can "
 37.8891 @@ -9719,14 +8802,14 @@
 37.8892  msgstr ""
 37.8893  
 37.8894  #. type: Content of: <book><chapter><sect1><para>
 37.8895 -#: ../en/ch09-undo.xml:712
 37.8896 +#: ../en/ch08-undo.xml:712
 37.8897  msgid ""
 37.8898  "Here are a few scenarios to help you understand how you might apply this "
 37.8899  "command."
 37.8900  msgstr ""
 37.8901  
 37.8902  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.8903 -#: ../en/ch09-undo.xml:715
 37.8904 +#: ../en/ch08-undo.xml:715
 37.8905  msgid ""
 37.8906  "The most recent version of your software has a bug that you remember wasn't "
 37.8907  "present a few weeks ago, but you don't know when it was introduced.  Here, "
 37.8908 @@ -9734,7 +8817,7 @@
 37.8909  msgstr ""
 37.8910  
 37.8911  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.8912 -#: ../en/ch09-undo.xml:720
 37.8913 +#: ../en/ch08-undo.xml:720
 37.8914  msgid ""
 37.8915  "You fixed a bug in a rush, and now it's time to close the entry in your "
 37.8916  "team's bug database.  The bug database requires a changeset ID when you close "
 37.8917 @@ -9743,7 +8826,7 @@
 37.8918  msgstr ""
 37.8919  
 37.8920  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.8921 -#: ../en/ch09-undo.xml:727
 37.8922 +#: ../en/ch08-undo.xml:727
 37.8923  msgid ""
 37.8924  "Your software works correctly, but runs 15% slower than the last time you "
 37.8925  "measured it.  You want to know which changeset introduced the performance "
 37.8926 @@ -9752,14 +8835,14 @@
 37.8927  msgstr ""
 37.8928  
 37.8929  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.8930 -#: ../en/ch09-undo.xml:734
 37.8931 +#: ../en/ch08-undo.xml:734
 37.8932  msgid ""
 37.8933  "The sizes of the components of your project that you ship exploded recently, "
 37.8934  "and you suspect that something changed in the way you build your project."
 37.8935  msgstr ""
 37.8936  
 37.8937  #. type: Content of: <book><chapter><sect1><para>
 37.8938 -#: ../en/ch09-undo.xml:739
 37.8939 +#: ../en/ch08-undo.xml:739
 37.8940  msgid ""
 37.8941  "From these examples, it should be clear that the <command role=\"hg-cmd\">hg "
 37.8942  "bisect</command> command is not useful only for finding the sources of bugs.  "
 37.8943 @@ -9769,7 +8852,7 @@
 37.8944  msgstr ""
 37.8945  
 37.8946  #. type: Content of: <book><chapter><sect1><para>
 37.8947 -#: ../en/ch09-undo.xml:746
 37.8948 +#: ../en/ch08-undo.xml:746
 37.8949  msgid ""
 37.8950  "We'll introduce a little bit of terminology here, just to make it clear which "
 37.8951  "parts of the search process are your responsibility, and which are "
 37.8952 @@ -9783,7 +8866,7 @@
 37.8953  msgstr ""
 37.8954  
 37.8955  #. type: Content of: <book><chapter><sect1><para>
 37.8956 -#: ../en/ch09-undo.xml:759
 37.8957 +#: ../en/ch08-undo.xml:759
 37.8958  msgid ""
 37.8959  "One simple way to automate the searching process would be simply to probe "
 37.8960  "every changeset.  However, this scales poorly.  If it took ten minutes to "
 37.8961 @@ -9796,7 +8879,7 @@
 37.8962  msgstr ""
 37.8963  
 37.8964  #. type: Content of: <book><chapter><sect1><para>
 37.8965 -#: ../en/ch09-undo.xml:769
 37.8966 +#: ../en/ch08-undo.xml:769
 37.8967  msgid ""
 37.8968  "What the <command role=\"hg-cmd\">hg bisect</command> command does is use its "
 37.8969  "knowledge of the <quote>shape</quote> of your project's revision history to "
 37.8970 @@ -9809,7 +8892,7 @@
 37.8971  msgstr ""
 37.8972  
 37.8973  #. type: Content of: <book><chapter><sect1><para>
 37.8974 -#: ../en/ch09-undo.xml:780
 37.8975 +#: ../en/ch08-undo.xml:780
 37.8976  msgid ""
 37.8977  "The <command role=\"hg-cmd\">hg bisect</command> command is aware of the "
 37.8978  "<quote>branchy</quote> nature of a Mercurial project's revision history, so "
 37.8979 @@ -9819,18 +8902,18 @@
 37.8980  msgstr ""
 37.8981  
 37.8982  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.8983 -#: ../en/ch09-undo.xml:788
 37.8984 +#: ../en/ch08-undo.xml:788
 37.8985  msgid "Using the <command role=\"hg-cmd\">hg bisect</command> command"
 37.8986  msgstr "使用命令 <command role=\"hg-cmd\">hg bisect</command>"
 37.8987  
 37.8988  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.8989 -#: ../en/ch09-undo.xml:791
 37.8990 +#: ../en/ch08-undo.xml:791
 37.8991  msgid ""
 37.8992  "Here's an example of <command role=\"hg-cmd\">hg bisect</command> in action."
 37.8993  msgstr ""
 37.8994  
 37.8995  #. type: Content of: <book><chapter><sect1><sect2><note><para>
 37.8996 -#: ../en/ch09-undo.xml:795
 37.8997 +#: ../en/ch08-undo.xml:795
 37.8998  msgid ""
 37.8999  "In versions 0.9.5 and earlier of Mercurial, <command role=\"hg-cmd\">hg "
 37.9000  "bisect</command> was not a core command: it was distributed with Mercurial as "
 37.9001 @@ -9839,14 +8922,14 @@
 37.9002  msgstr ""
 37.9003  
 37.9004  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9005 -#: ../en/ch09-undo.xml:802
 37.9006 +#: ../en/ch08-undo.xml:802
 37.9007  msgid ""
 37.9008  "Now let's create a repository, so that we can try out the <command role=\"hg-"
 37.9009  "cmd\">hg bisect</command> command in isolation."
 37.9010  msgstr ""
 37.9011  
 37.9012  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9013 -#: ../en/ch09-undo.xml:808
 37.9014 +#: ../en/ch08-undo.xml:808
 37.9015  msgid ""
 37.9016  "We'll simulate a project that has a bug in it in a simple-minded way: create "
 37.9017  "trivial changes in a loop, and nominate one specific change that will have "
 37.9018 @@ -9856,7 +8939,7 @@
 37.9019  msgstr ""
 37.9020  
 37.9021  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9022 -#: ../en/ch09-undo.xml:818
 37.9023 +#: ../en/ch08-undo.xml:818
 37.9024  msgid ""
 37.9025  "The next thing that we'd like to do is figure out how to use the <command "
 37.9026  "role=\"hg-cmd\">hg bisect</command> command.  We can use Mercurial's normal "
 37.9027 @@ -9864,46 +8947,46 @@
 37.9028  msgstr ""
 37.9029  
 37.9030  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9031 -#: ../en/ch09-undo.xml:825
 37.9032 +#: ../en/ch08-undo.xml:825
 37.9033  msgid ""
 37.9034  "The <command role=\"hg-cmd\">hg bisect</command> command works in steps.  "
 37.9035  "Each step proceeds as follows."
 37.9036  msgstr ""
 37.9037  
 37.9038  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.9039 -#: ../en/ch09-undo.xml:828
 37.9040 +#: ../en/ch08-undo.xml:828
 37.9041  msgid "You run your binary test."
 37.9042  msgstr ""
 37.9043  
 37.9044  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><itemizedlist><listitem><para>
 37.9045 -#: ../en/ch09-undo.xml:830
 37.9046 +#: ../en/ch08-undo.xml:830
 37.9047  msgid ""
 37.9048  "If the test succeeded, you tell <command role=\"hg-cmd\">hg bisect</command> "
 37.9049  "by running the <command role=\"hg-cmd\">hg bisect good</command> command."
 37.9050  msgstr ""
 37.9051  
 37.9052  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><itemizedlist><listitem><para>
 37.9053 -#: ../en/ch09-undo.xml:835
 37.9054 +#: ../en/ch08-undo.xml:835
 37.9055  msgid ""
 37.9056  "If it failed, run the <command role=\"hg-cmd\">hg bisect bad</command> "
 37.9057  "command."
 37.9058  msgstr ""
 37.9059  
 37.9060  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.9061 -#: ../en/ch09-undo.xml:839
 37.9062 +#: ../en/ch08-undo.xml:839
 37.9063  msgid ""
 37.9064  "The command uses your information to decide which changeset to test next."
 37.9065  msgstr ""
 37.9066  
 37.9067  #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
 37.9068 -#: ../en/ch09-undo.xml:842
 37.9069 +#: ../en/ch08-undo.xml:842
 37.9070  msgid ""
 37.9071  "It updates the working directory to that changeset, and the process begins "
 37.9072  "again."
 37.9073  msgstr ""
 37.9074  
 37.9075  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9076 -#: ../en/ch09-undo.xml:845
 37.9077 +#: ../en/ch08-undo.xml:845
 37.9078  msgid ""
 37.9079  "The process ends when <command role=\"hg-cmd\">hg bisect</command> identifies "
 37.9080  "a unique changeset that marks the point where your test transitioned from "
 37.9081 @@ -9912,14 +8995,14 @@
 37.9082  
 37.9083  #
 37.9084  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9085 -#: ../en/ch09-undo.xml:850
 37.9086 +#: ../en/ch08-undo.xml:850
 37.9087  msgid ""
 37.9088  "To start the search, we must run the <command role=\"hg-cmd\">hg bisect --"
 37.9089  "reset</command> command."
 37.9090  msgstr ""
 37.9091  
 37.9092  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9093 -#: ../en/ch09-undo.xml:855
 37.9094 +#: ../en/ch08-undo.xml:855
 37.9095  msgid ""
 37.9096  "In our case, the binary test we use is simple: we check to see if any file in "
 37.9097  "the repository contains the string <quote>i have a gub</quote>.  If it does, "
 37.9098 @@ -9929,7 +9012,7 @@
 37.9099  msgstr ""
 37.9100  
 37.9101  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9102 -#: ../en/ch09-undo.xml:863
 37.9103 +#: ../en/ch08-undo.xml:863
 37.9104  msgid ""
 37.9105  "Most of the time, the revision to which the working directory is synced "
 37.9106  "(usually the tip) already exhibits the problem introduced by the buggy "
 37.9107 @@ -9938,7 +9021,7 @@
 37.9108  
 37.9109  #
 37.9110  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9111 -#: ../en/ch09-undo.xml:870
 37.9112 +#: ../en/ch08-undo.xml:870
 37.9113  msgid ""
 37.9114  "Our next task is to nominate a changeset that we know <emphasis>doesn't</"
 37.9115  "emphasis> have the bug; the <command role=\"hg-cmd\">hg bisect</command> "
 37.9116 @@ -9949,26 +9032,26 @@
 37.9117  msgstr ""
 37.9118  
 37.9119  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9120 -#: ../en/ch09-undo.xml:880
 37.9121 +#: ../en/ch08-undo.xml:880
 37.9122  msgid "Notice that this command printed some output."
 37.9123  msgstr ""
 37.9124  
 37.9125  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.9126 -#: ../en/ch09-undo.xml:882
 37.9127 +#: ../en/ch08-undo.xml:882
 37.9128  msgid ""
 37.9129  "It told us how many changesets it must consider before it can identify the "
 37.9130  "one that introduced the bug, and how many tests that will require."
 37.9131  msgstr ""
 37.9132  
 37.9133  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.9134 -#: ../en/ch09-undo.xml:886
 37.9135 +#: ../en/ch08-undo.xml:886
 37.9136  msgid ""
 37.9137  "It updated the working directory to the next changeset to test, and told us "
 37.9138  "which changeset it's testing."
 37.9139  msgstr ""
 37.9140  
 37.9141  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9142 -#: ../en/ch09-undo.xml:891
 37.9143 +#: ../en/ch08-undo.xml:891
 37.9144  msgid ""
 37.9145  "We now run our test in the working directory.  We use the <command>grep</"
 37.9146  "command> command to see if our <quote>bad</quote> file is present in the "
 37.9147 @@ -9977,26 +9060,26 @@
 37.9148  msgstr ""
 37.9149  
 37.9150  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9151 -#: ../en/ch09-undo.xml:897
 37.9152 +#: ../en/ch08-undo.xml:897
 37.9153  msgid ""
 37.9154  "This test looks like a perfect candidate for automation, so let's turn it "
 37.9155  "into a shell function."
 37.9156  msgstr ""
 37.9157  
 37.9158  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9159 -#: ../en/ch09-undo.xml:901
 37.9160 +#: ../en/ch08-undo.xml:901
 37.9161  msgid ""
 37.9162  "We can now run an entire test step with a single command, <literal>mytest</"
 37.9163  "literal>."
 37.9164  msgstr ""
 37.9165  
 37.9166  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9167 -#: ../en/ch09-undo.xml:906
 37.9168 +#: ../en/ch08-undo.xml:906
 37.9169  msgid "A few more invocations of our canned test step command, and we're done."
 37.9170  msgstr ""
 37.9171  
 37.9172  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9173 -#: ../en/ch09-undo.xml:911
 37.9174 +#: ../en/ch08-undo.xml:911
 37.9175  msgid ""
 37.9176  "Even though we had 40 changesets to search through, the <command role=\"hg-cmd"
 37.9177  "\">hg bisect</command> command let us find the changeset that introduced our "
 37.9178 @@ -10008,13 +9091,13 @@
 37.9179  msgstr ""
 37.9180  
 37.9181  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.9182 -#: ../en/ch09-undo.xml:922
 37.9183 +#: ../en/ch08-undo.xml:922
 37.9184  msgid "Cleaning up after your search"
 37.9185  msgstr "搜索后的清理"
 37.9186  
 37.9187  #
 37.9188  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9189 -#: ../en/ch09-undo.xml:924
 37.9190 +#: ../en/ch08-undo.xml:924
 37.9191  msgid ""
 37.9192  "When you're finished using the <command role=\"hg-cmd\">hg bisect</command> "
 37.9193  "command in a repository, you can use the <command role=\"hg-cmd\">hg bisect "
 37.9194 @@ -10026,17 +9109,17 @@
 37.9195  msgstr ""
 37.9196  
 37.9197  #. type: Content of: <book><chapter><sect1><title>
 37.9198 -#: ../en/ch09-undo.xml:939
 37.9199 +#: ../en/ch08-undo.xml:939
 37.9200  msgid "Tips for finding bugs effectively"
 37.9201  msgstr "有效查找问题的技巧"
 37.9202  
 37.9203  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.9204 -#: ../en/ch09-undo.xml:942
 37.9205 +#: ../en/ch08-undo.xml:942
 37.9206  msgid "Give consistent input"
 37.9207  msgstr "给出一致的输入"
 37.9208  
 37.9209  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9210 -#: ../en/ch09-undo.xml:944
 37.9211 +#: ../en/ch08-undo.xml:944
 37.9212  msgid ""
 37.9213  "The <command role=\"hg-cmd\">hg bisect</command> command requires that you "
 37.9214  "correctly report the result of every test you perform.  If you tell it that a "
 37.9215 @@ -10048,12 +9131,12 @@
 37.9216  msgstr ""
 37.9217  
 37.9218  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.9219 -#: ../en/ch09-undo.xml:956
 37.9220 +#: ../en/ch08-undo.xml:956
 37.9221  msgid "Automate as much as possible"
 37.9222  msgstr "尽量自动"
 37.9223  
 37.9224  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9225 -#: ../en/ch09-undo.xml:958
 37.9226 +#: ../en/ch08-undo.xml:958
 37.9227  msgid ""
 37.9228  "When I started using the <command role=\"hg-cmd\">hg bisect</command> "
 37.9229  "command, I tried a few times to run my tests by hand, on the command line.  "
 37.9230 @@ -10063,7 +9146,7 @@
 37.9231  msgstr ""
 37.9232  
 37.9233  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9234 -#: ../en/ch09-undo.xml:966
 37.9235 +#: ../en/ch08-undo.xml:966
 37.9236  msgid ""
 37.9237  "My initial problems with driving the <command role=\"hg-cmd\">hg bisect</"
 37.9238  "command> command by hand occurred even with simple searches on small "
 37.9239 @@ -10074,24 +9157,24 @@
 37.9240  msgstr ""
 37.9241  
 37.9242  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9243 -#: ../en/ch09-undo.xml:975
 37.9244 +#: ../en/ch08-undo.xml:975
 37.9245  msgid "The key to automated testing is twofold:"
 37.9246  msgstr ""
 37.9247  
 37.9248  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.9249 -#: ../en/ch09-undo.xml:977
 37.9250 +#: ../en/ch08-undo.xml:977
 37.9251  msgid "always test for the same symptom, and"
 37.9252  msgstr ""
 37.9253  
 37.9254  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.9255 -#: ../en/ch09-undo.xml:979
 37.9256 +#: ../en/ch08-undo.xml:979
 37.9257  msgid ""
 37.9258  "always feed consistent input to the <command role=\"hg-cmd\">hg bisect</"
 37.9259  "command> command."
 37.9260  msgstr ""
 37.9261  
 37.9262  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9263 -#: ../en/ch09-undo.xml:982
 37.9264 +#: ../en/ch08-undo.xml:982
 37.9265  msgid ""
 37.9266  "In my tutorial example above, the <command>grep</command> command tests for "
 37.9267  "the symptom, and the <literal>if</literal> statement takes the result of this "
 37.9268 @@ -10102,12 +9185,12 @@
 37.9269  msgstr ""
 37.9270  
 37.9271  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.9272 -#: ../en/ch09-undo.xml:992
 37.9273 +#: ../en/ch08-undo.xml:992
 37.9274  msgid "Check your results"
 37.9275  msgstr "检查你的结果"
 37.9276  
 37.9277  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9278 -#: ../en/ch09-undo.xml:994
 37.9279 +#: ../en/ch08-undo.xml:994
 37.9280  msgid ""
 37.9281  "Because the output of a <command role=\"hg-cmd\">hg bisect</command> search "
 37.9282  "is only as good as the input you give it, don't take the changeset it reports "
 37.9283 @@ -10116,32 +9199,32 @@
 37.9284  msgstr ""
 37.9285  
 37.9286  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.9287 -#: ../en/ch09-undo.xml:1000
 37.9288 +#: ../en/ch08-undo.xml:1000
 37.9289  msgid ""
 37.9290  "The changeset that it reports as the first bad revision.  Your test should "
 37.9291  "still report this as bad."
 37.9292  msgstr ""
 37.9293  
 37.9294  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.9295 -#: ../en/ch09-undo.xml:1004
 37.9296 +#: ../en/ch08-undo.xml:1004
 37.9297  msgid ""
 37.9298  "The parent of that changeset (either parent, if it's a merge). Your test "
 37.9299  "should report this changeset as good."
 37.9300  msgstr ""
 37.9301  
 37.9302  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
 37.9303 -#: ../en/ch09-undo.xml:1008
 37.9304 +#: ../en/ch08-undo.xml:1008
 37.9305  msgid ""
 37.9306  "A child of that changeset.  Your test should report this changeset as bad."
 37.9307  msgstr ""
 37.9308  
 37.9309  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.9310 -#: ../en/ch09-undo.xml:1014
 37.9311 +#: ../en/ch08-undo.xml:1014
 37.9312  msgid "Beware interference between bugs"
 37.9313  msgstr "谨防问题之间的冲突"
 37.9314  
 37.9315  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9316 -#: ../en/ch09-undo.xml:1016
 37.9317 +#: ../en/ch08-undo.xml:1016
 37.9318  msgid ""
 37.9319  "It's possible that your search for one bug could be disrupted by the presence "
 37.9320  "of another.  For example, let's say your software crashes at revision 100, "
 37.9321 @@ -10151,7 +9234,7 @@
 37.9322  msgstr ""
 37.9323  
 37.9324  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9325 -#: ../en/ch09-undo.xml:1024
 37.9326 +#: ../en/ch08-undo.xml:1024
 37.9327  msgid ""
 37.9328  "It is possible that this other bug completely <quote>masks</quote> yours, "
 37.9329  "which is to say that it occurs before your bug has a chance to manifest "
 37.9330 @@ -10163,7 +9246,7 @@
 37.9331  msgstr ""
 37.9332  
 37.9333  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9334 -#: ../en/ch09-undo.xml:1034
 37.9335 +#: ../en/ch08-undo.xml:1034
 37.9336  msgid ""
 37.9337  "A different problem could arise if your test for a bug's presence is not "
 37.9338  "specific enough.  If you check for <quote>my program crashes</quote>, then "
 37.9339 @@ -10172,7 +9255,7 @@
 37.9340  msgstr ""
 37.9341  
 37.9342  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9343 -#: ../en/ch09-undo.xml:1041
 37.9344 +#: ../en/ch08-undo.xml:1041
 37.9345  msgid ""
 37.9346  "Another useful situation in which to use <command role=\"hg-cmd\">hg bisect --"
 37.9347  "skip</command> is if you can't test a revision because your project was in a "
 37.9348 @@ -10181,12 +9264,12 @@
 37.9349  msgstr ""
 37.9350  
 37.9351  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.9352 -#: ../en/ch09-undo.xml:1050
 37.9353 +#: ../en/ch08-undo.xml:1050
 37.9354  msgid "Bracket your search lazily"
 37.9355  msgstr "减少你的查找工作"
 37.9356  
 37.9357  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9358 -#: ../en/ch09-undo.xml:1052
 37.9359 +#: ../en/ch08-undo.xml:1052
 37.9360  msgid ""
 37.9361  "Choosing the first <quote>good</quote> and <quote>bad</quote> changesets that "
 37.9362  "will mark the end points of your search is often easy, but it bears a little "
 37.9363 @@ -10196,7 +9279,7 @@
 37.9364  msgstr ""
 37.9365  
 37.9366  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9367 -#: ../en/ch09-undo.xml:1060
 37.9368 +#: ../en/ch08-undo.xml:1060
 37.9369  msgid ""
 37.9370  "If you're having trouble remembering when a suitable <quote>good</quote> "
 37.9371  "change was, so that you can tell <command role=\"hg-cmd\">hg bisect</"
 37.9372 @@ -10207,7 +9290,7 @@
 37.9373  msgstr ""
 37.9374  
 37.9375  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9376 -#: ../en/ch09-undo.xml:1069
 37.9377 +#: ../en/ch08-undo.xml:1069
 37.9378  msgid ""
 37.9379  "Even if you end up <quote>early</quote> by thousands of changesets or months "
 37.9380  "of history, you will only add a handful of tests to the total number that "
 37.9381 @@ -10216,12 +9299,12 @@
 37.9382  msgstr ""
 37.9383  
 37.9384  #. type: Content of: <book><chapter><title>
 37.9385 -#: ../en/ch10-hook.xml:5
 37.9386 +#: ../en/ch09-hook.xml:5
 37.9387  msgid "Handling repository events with hooks"
 37.9388  msgstr "使用钩子处理版本库事件"
 37.9389  
 37.9390  #. type: Content of: <book><chapter><para>
 37.9391 -#: ../en/ch10-hook.xml:7
 37.9392 +#: ../en/ch09-hook.xml:7
 37.9393  msgid ""
 37.9394  "Mercurial offers a powerful mechanism to let you perform automated actions in "
 37.9395  "response to events that occur in a repository.  In some cases, you can even "
 37.9396 @@ -10229,7 +9312,7 @@
 37.9397  msgstr ""
 37.9398  
 37.9399  #. type: Content of: <book><chapter><para>
 37.9400 -#: ../en/ch10-hook.xml:12
 37.9401 +#: ../en/ch09-hook.xml:12
 37.9402  msgid ""
 37.9403  "The name Mercurial uses for one of these actions is a <emphasis>hook</"
 37.9404  "emphasis>. Hooks are called <quote>triggers</quote> in some revision control "
 37.9405 @@ -10237,12 +9320,12 @@
 37.9406  msgstr ""
 37.9407  
 37.9408  #. type: Content of: <book><chapter><sect1><title>
 37.9409 -#: ../en/ch10-hook.xml:18
 37.9410 +#: ../en/ch09-hook.xml:18
 37.9411  msgid "An overview of hooks in Mercurial"
 37.9412  msgstr "Mercurial 钩子概述"
 37.9413  
 37.9414  #. type: Content of: <book><chapter><sect1><para>
 37.9415 -#: ../en/ch10-hook.xml:20
 37.9416 +#: ../en/ch09-hook.xml:20
 37.9417  msgid ""
 37.9418  "Here is a brief list of the hooks that Mercurial supports.  We will revisit "
 37.9419  "each of these hooks in more detail later, in section <xref linkend=\"sec.hook."
 37.9420 @@ -10250,21 +9333,21 @@
 37.9421  msgstr ""
 37.9422  
 37.9423  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.9424 -#: ../en/ch10-hook.xml:25
 37.9425 +#: ../en/ch09-hook.xml:25
 37.9426  msgid ""
 37.9427  "<literal role=\"hook\">changegroup</literal>: This is run after a group of "
 37.9428  "changesets has been brought into the repository from elsewhere."
 37.9429  msgstr ""
 37.9430  
 37.9431  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.9432 -#: ../en/ch10-hook.xml:29
 37.9433 +#: ../en/ch09-hook.xml:29
 37.9434  msgid ""
 37.9435  "<literal role=\"hook\">commit</literal>: This is run after a new changeset "
 37.9436  "has been created in the local repository."
 37.9437  msgstr ""
 37.9438  
 37.9439  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.9440 -#: ../en/ch10-hook.xml:33
 37.9441 +#: ../en/ch09-hook.xml:33
 37.9442  msgid ""
 37.9443  "<literal role=\"hook\">incoming</literal>: This is run once for each new "
 37.9444  "changeset that is brought into the repository from elsewhere.  Notice the "
 37.9445 @@ -10273,42 +9356,42 @@
 37.9446  msgstr ""
 37.9447  
 37.9448  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.9449 -#: ../en/ch10-hook.xml:40
 37.9450 +#: ../en/ch09-hook.xml:40
 37.9451  msgid ""
 37.9452  "<literal role=\"hook\">outgoing</literal>: This is run after a group of "
 37.9453  "changesets has been transmitted from this repository."
 37.9454  msgstr ""
 37.9455  
 37.9456  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.9457 -#: ../en/ch10-hook.xml:44
 37.9458 +#: ../en/ch09-hook.xml:44
 37.9459  msgid ""
 37.9460  "<literal role=\"hook\">prechangegroup</literal>: This is run before starting "
 37.9461  "to bring a group of changesets into the repository."
 37.9462  msgstr ""
 37.9463  
 37.9464  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.9465 -#: ../en/ch10-hook.xml:49
 37.9466 +#: ../en/ch09-hook.xml:49
 37.9467  msgid ""
 37.9468  "<literal role=\"hook\">precommit</literal>: Controlling. This is run before "
 37.9469  "starting a commit."
 37.9470  msgstr ""
 37.9471  
 37.9472  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.9473 -#: ../en/ch10-hook.xml:53
 37.9474 +#: ../en/ch09-hook.xml:53
 37.9475  msgid ""
 37.9476  "<literal role=\"hook\">preoutgoing</literal>: Controlling. This is run before "
 37.9477  "starting to transmit a group of changesets from this repository."
 37.9478  msgstr ""
 37.9479  
 37.9480  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.9481 -#: ../en/ch10-hook.xml:58
 37.9482 +#: ../en/ch09-hook.xml:58
 37.9483  msgid ""
 37.9484  "<literal role=\"hook\">pretag</literal>: Controlling. This is run before "
 37.9485  "creating a tag."
 37.9486  msgstr ""
 37.9487  
 37.9488  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.9489 -#: ../en/ch10-hook.xml:62
 37.9490 +#: ../en/ch09-hook.xml:62
 37.9491  msgid ""
 37.9492  "<literal role=\"hook\">pretxnchangegroup</literal>: Controlling. This is run "
 37.9493  "after a group of changesets has been brought into the local repository from "
 37.9494 @@ -10317,7 +9400,7 @@
 37.9495  msgstr ""
 37.9496  
 37.9497  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.9498 -#: ../en/ch10-hook.xml:70
 37.9499 +#: ../en/ch09-hook.xml:70
 37.9500  msgid ""
 37.9501  "<literal role=\"hook\">pretxncommit</literal>: Controlling. This is run after "
 37.9502  "a new changeset has been created in the local repository, but before the "
 37.9503 @@ -10325,27 +9408,27 @@
 37.9504  msgstr ""
 37.9505  
 37.9506  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.9507 -#: ../en/ch10-hook.xml:76
 37.9508 +#: ../en/ch09-hook.xml:76
 37.9509  msgid ""
 37.9510  "<literal role=\"hook\">preupdate</literal>: Controlling. This is run before "
 37.9511  "starting an update or merge of the working directory."
 37.9512  msgstr ""
 37.9513  
 37.9514  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.9515 -#: ../en/ch10-hook.xml:81
 37.9516 +#: ../en/ch09-hook.xml:81
 37.9517  msgid ""
 37.9518  "<literal role=\"hook\">tag</literal>: This is run after a tag is created."
 37.9519  msgstr ""
 37.9520  
 37.9521  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
 37.9522 -#: ../en/ch10-hook.xml:85
 37.9523 +#: ../en/ch09-hook.xml:85
 37.9524  msgid ""
 37.9525  "<literal role=\"hook\">update</literal>: This is run after an update or merge "
 37.9526  "of the working directory has finished."
 37.9527  msgstr ""
 37.9528  
 37.9529  #. type: Content of: <book><chapter><sect1><para>
 37.9530 -#: ../en/ch10-hook.xml:90
 37.9531 +#: ../en/ch09-hook.xml:90
 37.9532  msgid ""
 37.9533  "Each of the hooks whose description begins with the word <quote>Controlling</"
 37.9534  "quote> has the ability to determine whether an activity can proceed.  If the "
 37.9535 @@ -10354,17 +9437,17 @@
 37.9536  msgstr ""
 37.9537  
 37.9538  #. type: Content of: <book><chapter><sect1><title>
 37.9539 -#: ../en/ch10-hook.xml:99
 37.9540 +#: ../en/ch09-hook.xml:99
 37.9541  msgid "Hooks and security"
 37.9542  msgstr "钩子与安全性"
 37.9543  
 37.9544  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.9545 -#: ../en/ch10-hook.xml:102
 37.9546 +#: ../en/ch09-hook.xml:102
 37.9547  msgid "Hooks are run with your privileges"
 37.9548  msgstr "钩子以你的特权执行"
 37.9549  
 37.9550  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9551 -#: ../en/ch10-hook.xml:104
 37.9552 +#: ../en/ch09-hook.xml:104
 37.9553  msgid ""
 37.9554  "When you run a Mercurial command in a repository, and the command causes a "
 37.9555  "hook to run, that hook runs on <emphasis>your</emphasis> system, under "
 37.9556 @@ -10375,16 +9458,16 @@
 37.9557  msgstr ""
 37.9558  
 37.9559  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9560 -#: ../en/ch10-hook.xml:115
 37.9561 +#: ../en/ch09-hook.xml:115
 37.9562  msgid ""
 37.9563  "In some cases, you may be exposed to hooks that you did not install "
 37.9564  "yourself.  If you work with Mercurial on an unfamiliar system, Mercurial will "
 37.9565 -"run hooks defined in that system's global <filename role=\"special\"> /.hgrc</"
 37.9566 -"filename>\\ file."
 37.9567 -msgstr ""
 37.9568 -
 37.9569 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.9570 -#: ../en/ch10-hook.xml:122
 37.9571 +"run hooks defined in that system's global <filename role=\"special\">~/.hgrc</"
 37.9572 +"filename> file."
 37.9573 +msgstr ""
 37.9574 +
 37.9575 +#. type: Content of: <book><chapter><sect1><sect2><para>
 37.9576 +#: ../en/ch09-hook.xml:122
 37.9577  msgid ""
 37.9578  "If you are working with a repository owned by another user, Mercurial can run "
 37.9579  "hooks defined in that user's repository, but it will still run them as "
 37.9580 @@ -10396,7 +9479,7 @@
 37.9581  msgstr ""
 37.9582  
 37.9583  #. type: Content of: <book><chapter><sect1><sect2><note><para>
 37.9584 -#: ../en/ch10-hook.xml:134
 37.9585 +#: ../en/ch09-hook.xml:134
 37.9586  msgid ""
 37.9587  "This only applies if you are pulling from a repository on a local or network "
 37.9588  "filesystem.  If you're pulling over http or ssh, any <literal role=\"hook"
 37.9589 @@ -10405,7 +9488,7 @@
 37.9590  msgstr ""
 37.9591  
 37.9592  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9593 -#: ../en/ch10-hook.xml:142
 37.9594 +#: ../en/ch09-hook.xml:142
 37.9595  msgid ""
 37.9596  "XXX To see what hooks are defined in a repository, use the <command role=\"hg-"
 37.9597  "cmd\">hg config hooks</command> command.  If you are working in one "
 37.9598 @@ -10416,12 +9499,12 @@
 37.9599  msgstr ""
 37.9600  
 37.9601  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.9602 -#: ../en/ch10-hook.xml:153
 37.9603 +#: ../en/ch09-hook.xml:153
 37.9604  msgid "Hooks do not propagate"
 37.9605  msgstr "钩子不会传播"
 37.9606  
 37.9607  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9608 -#: ../en/ch10-hook.xml:155
 37.9609 +#: ../en/ch09-hook.xml:155
 37.9610  msgid ""
 37.9611  "In Mercurial, hooks are not revision controlled, and do not propagate when "
 37.9612  "you clone, or pull from, a repository.  The reason for this is simple: a hook "
 37.9613 @@ -10430,7 +9513,7 @@
 37.9614  msgstr ""
 37.9615  
 37.9616  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9617 -#: ../en/ch10-hook.xml:162
 37.9618 +#: ../en/ch09-hook.xml:162
 37.9619  msgid ""
 37.9620  "It would be extremely reckless for any distributed revision control system to "
 37.9621  "implement revision-controlled hooks, as this would offer an easily "
 37.9622 @@ -10439,7 +9522,7 @@
 37.9623  msgstr ""
 37.9624  
 37.9625  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9626 -#: ../en/ch10-hook.xml:168
 37.9627 +#: ../en/ch09-hook.xml:168
 37.9628  msgid ""
 37.9629  "Since Mercurial does not propagate hooks, if you are collaborating with other "
 37.9630  "people on a common project, you should not assume that they are using the "
 37.9631 @@ -10448,22 +9531,22 @@
 37.9632  msgstr ""
 37.9633  
 37.9634  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9635 -#: ../en/ch10-hook.xml:175
 37.9636 +#: ../en/ch09-hook.xml:175
 37.9637  msgid ""
 37.9638  "In a corporate intranet, this is somewhat easier to control, as you can for "
 37.9639  "example provide a <quote>standard</quote> installation of Mercurial on an NFS "
 37.9640 -"filesystem, and use a site-wide <filename role=\"special\"> /.hgrc</filename>"
 37.9641 -"\\ file to define hooks that all users will see.  However, this too has its "
 37.9642 +"filesystem, and use a site-wide <filename role=\"special\">~/.hgrc</filename> "
 37.9643 +"file to define hooks that all users will see.  However, this too has its "
 37.9644  "limits; see below."
 37.9645  msgstr ""
 37.9646  
 37.9647  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.9648 -#: ../en/ch10-hook.xml:185
 37.9649 +#: ../en/ch09-hook.xml:184
 37.9650  msgid "Hooks can be overridden"
 37.9651  msgstr "钩子可以被覆盖"
 37.9652  
 37.9653  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9654 -#: ../en/ch10-hook.xml:187
 37.9655 +#: ../en/ch09-hook.xml:186
 37.9656  msgid ""
 37.9657  "Mercurial allows you to override a hook definition by redefining the hook.  "
 37.9658  "You can disable it by setting its value to the empty string, or change its "
 37.9659 @@ -10471,31 +9554,31 @@
 37.9660  msgstr ""
 37.9661  
 37.9662  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9663 -#: ../en/ch10-hook.xml:192
 37.9664 -msgid ""
 37.9665 -"If you deploy a system- or site-wide <filename role=\"special\"> /.hgrc</"
 37.9666 -"filename>\\ file that defines some hooks, you should thus understand that "
 37.9667 -"your users can disable or override those hooks."
 37.9668 -msgstr ""
 37.9669 -
 37.9670 -#. type: Content of: <book><chapter><sect1><sect2><title>
 37.9671 -#: ../en/ch10-hook.xml:200
 37.9672 +#: ../en/ch09-hook.xml:191
 37.9673 +msgid ""
 37.9674 +"If you deploy a system- or site-wide <filename role=\"special\">~/.hgrc</"
 37.9675 +"filename> file that defines some hooks, you should thus understand that your "
 37.9676 +"users can disable or override those hooks."
 37.9677 +msgstr ""
 37.9678 +
 37.9679 +#. type: Content of: <book><chapter><sect1><sect2><title>
 37.9680 +#: ../en/ch09-hook.xml:199
 37.9681  msgid "Ensuring that critical hooks are run"
 37.9682  msgstr "确保关键钩子的执行"
 37.9683  
 37.9684  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9685 -#: ../en/ch10-hook.xml:202
 37.9686 +#: ../en/ch09-hook.xml:201
 37.9687  msgid ""
 37.9688  "Sometimes you may want to enforce a policy that you do not want others to be "
 37.9689  "able to work around.  For example, you may have a requirement that every "
 37.9690  "changeset must pass a rigorous set of tests.  Defining this requirement via a "
 37.9691 -"hook in a site-wide <filename role=\"special\"> /.hgrc</filename>\\ won't "
 37.9692 -"work for remote users on laptops, and of course local users can subvert it at "
 37.9693 -"will by overriding the hook."
 37.9694 -msgstr ""
 37.9695 -
 37.9696 -#. type: Content of: <book><chapter><sect1><sect2><para>
 37.9697 -#: ../en/ch10-hook.xml:211
 37.9698 +"hook in a site-wide <filename role=\"special\">~/.hgrc</filename> won't work "
 37.9699 +"for remote users on laptops, and of course local users can subvert it at will "
 37.9700 +"by overriding the hook."
 37.9701 +msgstr ""
 37.9702 +
 37.9703 +#. type: Content of: <book><chapter><sect1><sect2><para>
 37.9704 +#: ../en/ch09-hook.xml:210
 37.9705  msgid ""
 37.9706  "Instead, you can set up your policies for use of Mercurial so that people are "
 37.9707  "expected to propagate changes through a well-known <quote>canonical</quote> "
 37.9708 @@ -10503,7 +9586,7 @@
 37.9709  msgstr ""
 37.9710  
 37.9711  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9712 -#: ../en/ch10-hook.xml:217
 37.9713 +#: ../en/ch09-hook.xml:216
 37.9714  msgid ""
 37.9715  "One way to do this is via a combination of social engineering and "
 37.9716  "technology.  Set up a restricted-access account; users can push changes over "
 37.9717 @@ -10513,7 +9596,7 @@
 37.9718  msgstr ""
 37.9719  
 37.9720  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9721 -#: ../en/ch10-hook.xml:226
 37.9722 +#: ../en/ch09-hook.xml:225
 37.9723  msgid ""
 37.9724  "When someone pushes a changeset to the server that everyone pulls from, the "
 37.9725  "server will test the changeset before it accepts it as permanent, and reject "
 37.9726 @@ -10523,12 +9606,12 @@
 37.9727  msgstr ""
 37.9728  
 37.9729  #. type: Content of: <book><chapter><sect1><title>
 37.9730 -#: ../en/ch10-hook.xml:237
 37.9731 +#: ../en/ch09-hook.xml:236
 37.9732  msgid "Care with <literal>pretxn</literal> hooks in a shared-access repository"
 37.9733  msgstr "在共享版本库中注意 <literal>pretxn</literal> 钩子"
 37.9734  
 37.9735  #. type: Content of: <book><chapter><sect1><para>
 37.9736 -#: ../en/ch10-hook.xml:240
 37.9737 +#: ../en/ch09-hook.xml:239
 37.9738  msgid ""
 37.9739  "If you want to use hooks to do some automated work in a repository that a "
 37.9740  "number of people have shared access to, you need to be careful in how you do "
 37.9741 @@ -10536,7 +9619,7 @@
 37.9742  msgstr ""
 37.9743  
 37.9744  #. type: Content of: <book><chapter><sect1><para>
 37.9745 -#: ../en/ch10-hook.xml:245
 37.9746 +#: ../en/ch09-hook.xml:244
 37.9747  msgid ""
 37.9748  "Mercurial only locks a repository when it is writing to the repository, and "
 37.9749  "only the parts of Mercurial that write to the repository pay attention to "
 37.9750 @@ -10545,7 +9628,7 @@
 37.9751  msgstr ""
 37.9752  
 37.9753  #. type: Content of: <book><chapter><sect1><para>
 37.9754 -#: ../en/ch10-hook.xml:252
 37.9755 +#: ../en/ch09-hook.xml:251
 37.9756  msgid ""
 37.9757  "Because Mercurial is careful with the order in which it reads and writes "
 37.9758  "data, it does not need to acquire a lock when it wants to read data from the "
 37.9759 @@ -10555,7 +9638,7 @@
 37.9760  msgstr ""
 37.9761  
 37.9762  #. type: Content of: <book><chapter><sect1><para>
 37.9763 -#: ../en/ch10-hook.xml:260
 37.9764 +#: ../en/ch09-hook.xml:259
 37.9765  msgid ""
 37.9766  "With great performance comes a trade-off, though, one which has the potential "
 37.9767  "to cause you trouble unless you're aware of it.  To describe this requires a "
 37.9768 @@ -10564,7 +9647,7 @@
 37.9769  msgstr ""
 37.9770  
 37.9771  #. type: Content of: <book><chapter><sect1><para>
 37.9772 -#: ../en/ch10-hook.xml:267
 37.9773 +#: ../en/ch09-hook.xml:266
 37.9774  msgid ""
 37.9775  "When Mercurial <emphasis>writes</emphasis> metadata, it writes it straight "
 37.9776  "into the destination file.  It writes file data first, then manifest data "
 37.9777 @@ -10576,7 +9659,7 @@
 37.9778  msgstr ""
 37.9779  
 37.9780  #. type: Content of: <book><chapter><sect1><para>
 37.9781 -#: ../en/ch10-hook.xml:278
 37.9782 +#: ../en/ch09-hook.xml:277
 37.9783  msgid ""
 37.9784  "When Mercurial <emphasis>reads</emphasis> metadata, it reads the changelog "
 37.9785  "first, then everything else.  Since a reader will only access parts of the "
 37.9786 @@ -10585,7 +9668,7 @@
 37.9787  msgstr ""
 37.9788  
 37.9789  #. type: Content of: <book><chapter><sect1><para>
 37.9790 -#: ../en/ch10-hook.xml:284
 37.9791 +#: ../en/ch09-hook.xml:283
 37.9792  msgid ""
 37.9793  "Some controlling hooks (<literal role=\"hook\">pretxncommit</literal> and "
 37.9794  "<literal role=\"hook\">pretxnchangegroup</literal>) run when a transaction is "
 37.9795 @@ -10594,7 +9677,7 @@
 37.9796  msgstr ""
 37.9797  
 37.9798  #. type: Content of: <book><chapter><sect1><para>
 37.9799 -#: ../en/ch10-hook.xml:292
 37.9800 +#: ../en/ch09-hook.xml:291
 37.9801  msgid ""
 37.9802  "If one of these hooks runs for long, it opens a window of time during which a "
 37.9803  "reader can see the metadata for changesets that are not yet permanent, and "
 37.9804 @@ -10603,12 +9686,12 @@
 37.9805  msgstr ""
 37.9806  
 37.9807  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.9808 -#: ../en/ch10-hook.xml:300
 37.9809 +#: ../en/ch09-hook.xml:299
 37.9810  msgid "The problem illustrated"
 37.9811  msgstr "问题的演示"
 37.9812  
 37.9813  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9814 -#: ../en/ch10-hook.xml:302
 37.9815 +#: ../en/ch09-hook.xml:301
 37.9816  msgid ""
 37.9817  "In principle, a good use for the <literal role=\"hook\">pretxnchangegroup</"
 37.9818  "literal> hook would be to automatically build and test incoming changes "
 37.9819 @@ -10620,7 +9703,7 @@
 37.9820  msgstr ""
 37.9821  
 37.9822  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9823 -#: ../en/ch10-hook.xml:313
 37.9824 +#: ../en/ch09-hook.xml:312
 37.9825  msgid ""
 37.9826  "The safest technological answer to this challenge is to set up such a "
 37.9827  "<quote>gatekeeper</quote> repository as <emphasis>unidirectional</emphasis>.  "
 37.9828 @@ -10633,7 +9716,7 @@
 37.9829  msgstr ""
 37.9830  
 37.9831  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9832 -#: ../en/ch10-hook.xml:325
 37.9833 +#: ../en/ch09-hook.xml:324
 37.9834  msgid ""
 37.9835  "In practice, putting a centralised bottleneck like this in place is not often "
 37.9836  "a good idea, and transaction visibility has nothing to do with the problem.  "
 37.9837 @@ -10645,7 +9728,7 @@
 37.9838  msgstr ""
 37.9839  
 37.9840  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9841 -#: ../en/ch10-hook.xml:336
 37.9842 +#: ../en/ch09-hook.xml:335
 37.9843  msgid ""
 37.9844  "An approach that scales better is to get people to build and test before they "
 37.9845  "push, then run automated builds and tests centrally <emphasis>after</"
 37.9846 @@ -10655,12 +9738,12 @@
 37.9847  msgstr ""
 37.9848  
 37.9849  #. type: Content of: <book><chapter><sect1><title>
 37.9850 -#: ../en/ch10-hook.xml:347
 37.9851 +#: ../en/ch09-hook.xml:346
 37.9852  msgid "A short tutorial on using hooks"
 37.9853  msgstr "使用钩子的简短指南"
 37.9854  
 37.9855  #. type: Content of: <book><chapter><sect1><para>
 37.9856 -#: ../en/ch10-hook.xml:349
 37.9857 +#: ../en/ch09-hook.xml:348
 37.9858  msgid ""
 37.9859  "It is easy to write a Mercurial hook.  Let's start with a hook that runs when "
 37.9860  "you finish a <command role=\"hg-cmd\">hg commit</command>, and simply prints "
 37.9861 @@ -10669,15 +9752,15 @@
 37.9862  msgstr ""
 37.9863  
 37.9864  #. type: Content of: <book><chapter><sect1><para>
 37.9865 -#: ../en/ch10-hook.xml:356
 37.9866 +#: ../en/ch09-hook.xml:355
 37.9867  msgid "All hooks follow the pattern in this example."
 37.9868  msgstr ""
 37.9869  
 37.9870  #. type: Content of: <book><chapter><sect1><para>
 37.9871 -#: ../en/ch10-hook.xml:360
 37.9872 +#: ../en/ch09-hook.xml:359
 37.9873  msgid ""
 37.9874  "You add an entry to the <literal role=\"rc-hooks\">hooks</literal> section of "
 37.9875 -"your <filename role=\"special\"> /.hgrc</filename>.  On the left is the name "
 37.9876 +"your <filename role=\"special\">~/.hgrc</filename>.  On the left is the name "
 37.9877  "of the event to trigger on; on the right is the action to take.  As you can "
 37.9878  "see, you can run an arbitrary shell command in a hook.  Mercurial passes "
 37.9879  "extra information to the hook using environment variables (look for "
 37.9880 @@ -10685,19 +9768,19 @@
 37.9881  msgstr ""
 37.9882  
 37.9883  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.9884 -#: ../en/ch10-hook.xml:370
 37.9885 +#: ../en/ch09-hook.xml:369
 37.9886  msgid "Performing multiple actions per event"
 37.9887  msgstr "每个事件执行多个操作"
 37.9888  
 37.9889  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9890 -#: ../en/ch10-hook.xml:372
 37.9891 +#: ../en/ch09-hook.xml:371
 37.9892  msgid ""
 37.9893  "Quite often, you will want to define more than one hook for a particular kind "
 37.9894  "of event, as shown below."
 37.9895  msgstr ""
 37.9896  
 37.9897  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9898 -#: ../en/ch10-hook.xml:377
 37.9899 +#: ../en/ch09-hook.xml:376
 37.9900  msgid ""
 37.9901  "Mercurial lets you do this by adding an <emphasis>extension</emphasis> to the "
 37.9902  "end of a hook's name.  You extend a hook's name by giving the name of the "
 37.9903 @@ -10708,7 +9791,7 @@
 37.9904  msgstr ""
 37.9905  
 37.9906  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9907 -#: ../en/ch10-hook.xml:388
 37.9908 +#: ../en/ch09-hook.xml:387
 37.9909  msgid ""
 37.9910  "To give a well-defined order of execution when there are multiple hooks "
 37.9911  "defined for an event, Mercurial sorts hooks by extension, and executes the "
 37.9912 @@ -10718,7 +9801,7 @@
 37.9913  msgstr ""
 37.9914  
 37.9915  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9916 -#: ../en/ch10-hook.xml:397
 37.9917 +#: ../en/ch09-hook.xml:396
 37.9918  msgid ""
 37.9919  "It is a good idea to use a somewhat descriptive extension when you define a "
 37.9920  "new hook.  This will help you to remember what the hook was for.  If the hook "
 37.9921 @@ -10729,12 +9812,12 @@
 37.9922  msgstr ""
 37.9923  
 37.9924  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.9925 -#: ../en/ch10-hook.xml:408
 37.9926 +#: ../en/ch09-hook.xml:407
 37.9927  msgid "Controlling whether an activity can proceed"
 37.9928  msgstr "控制处理的活动"
 37.9929  
 37.9930  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9931 -#: ../en/ch10-hook.xml:410
 37.9932 +#: ../en/ch09-hook.xml:409
 37.9933  msgid ""
 37.9934  "In our earlier examples, we used the <literal role=\"hook\">commit</literal> "
 37.9935  "hook, which is run after a commit has completed.  This is one of several "
 37.9936 @@ -10743,7 +9826,7 @@
 37.9937  msgstr ""
 37.9938  
 37.9939  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9940 -#: ../en/ch10-hook.xml:417
 37.9941 +#: ../en/ch09-hook.xml:416
 37.9942  msgid ""
 37.9943  "Mercurial defines a number of events that occur before an activity starts; or "
 37.9944  "after it starts, but before it finishes.  Hooks that trigger on these events "
 37.9945 @@ -10752,7 +9835,7 @@
 37.9946  msgstr ""
 37.9947  
 37.9948  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9949 -#: ../en/ch10-hook.xml:423
 37.9950 +#: ../en/ch09-hook.xml:422
 37.9951  msgid ""
 37.9952  "The <literal role=\"hook\">pretxncommit</literal> hook runs after a commit "
 37.9953  "has all but completed.  In other words, the metadata representing the "
 37.9954 @@ -10763,7 +9846,7 @@
 37.9955  msgstr ""
 37.9956  
 37.9957  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9958 -#: ../en/ch10-hook.xml:432
 37.9959 +#: ../en/ch09-hook.xml:431
 37.9960  msgid ""
 37.9961  "If the <literal role=\"hook\">pretxncommit</literal> hook exits with a status "
 37.9962  "code of zero, the transaction is allowed to complete; the commit finishes; "
 37.9963 @@ -10774,19 +9857,19 @@
 37.9964  msgstr ""
 37.9965  
 37.9966  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9967 -#: ../en/ch10-hook.xml:444
 37.9968 +#: ../en/ch09-hook.xml:443
 37.9969  msgid ""
 37.9970  "The hook in the example above checks that a commit comment contains a bug "
 37.9971  "ID.  If it does, the commit can complete.  If not, the commit is rolled back."
 37.9972  msgstr ""
 37.9973  
 37.9974  #. type: Content of: <book><chapter><sect1><title>
 37.9975 -#: ../en/ch10-hook.xml:452
 37.9976 +#: ../en/ch09-hook.xml:451
 37.9977  msgid "Writing your own hooks"
 37.9978  msgstr "编写钩子"
 37.9979  
 37.9980  #. type: Content of: <book><chapter><sect1><para>
 37.9981 -#: ../en/ch10-hook.xml:454
 37.9982 +#: ../en/ch09-hook.xml:453
 37.9983  msgid ""
 37.9984  "When you are writing a hook, you might find it useful to run Mercurial either "
 37.9985  "with the <option role=\"hg-opt-global\">-v</option> option, or the <envar "
 37.9986 @@ -10795,12 +9878,12 @@
 37.9987  msgstr ""
 37.9988  
 37.9989  #. type: Content of: <book><chapter><sect1><sect2><title>
 37.9990 -#: ../en/ch10-hook.xml:463
 37.9991 +#: ../en/ch09-hook.xml:462
 37.9992  msgid "Choosing how your hook should run"
 37.9993  msgstr "选择钩子的执行方式"
 37.9994  
 37.9995  #. type: Content of: <book><chapter><sect1><sect2><para>
 37.9996 -#: ../en/ch10-hook.xml:465
 37.9997 +#: ../en/ch09-hook.xml:464
 37.9998  msgid ""
 37.9999  "You can write a hook either as a normal program&emdash;typically a shell "
37.10000  "script&emdash;or as a Python function that is executed within the Mercurial "
37.10001 @@ -10808,7 +9891,7 @@
37.10002  msgstr ""
37.10003  
37.10004  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10005 -#: ../en/ch10-hook.xml:470
37.10006 +#: ../en/ch09-hook.xml:469
37.10007  msgid ""
37.10008  "Writing a hook as an external program has the advantage that it requires no "
37.10009  "knowledge of Mercurial's internals.  You can call normal Mercurial commands "
37.10010 @@ -10817,7 +9900,7 @@
37.10011  msgstr ""
37.10012  
37.10013  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10014 -#: ../en/ch10-hook.xml:477
37.10015 +#: ../en/ch09-hook.xml:476
37.10016  msgid ""
37.10017  "An in-process Python hook has complete access to the Mercurial API, and does "
37.10018  "not <quote>shell out</quote> to another process, so it is inherently faster "
37.10019 @@ -10827,7 +9910,7 @@
37.10020  msgstr ""
37.10021  
37.10022  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10023 -#: ../en/ch10-hook.xml:485
37.10024 +#: ../en/ch09-hook.xml:484
37.10025  msgid ""
37.10026  "If you are comfortable with Python, or require high performance, writing your "
37.10027  "hooks in Python may be a good choice.  However, when you have a "
37.10028 @@ -10836,12 +9919,12 @@
37.10029  msgstr ""
37.10030  
37.10031  #. type: Content of: <book><chapter><sect1><sect2><title>
37.10032 -#: ../en/ch10-hook.xml:494
37.10033 +#: ../en/ch09-hook.xml:493
37.10034  msgid "Hook parameters"
37.10035  msgstr "钩子的参数"
37.10036  
37.10037  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10038 -#: ../en/ch10-hook.xml:496
37.10039 +#: ../en/ch09-hook.xml:495
37.10040  msgid ""
37.10041  "Mercurial calls each hook with a set of well-defined parameters.  In Python, "
37.10042  "a parameter is passed as a keyword argument to your hook function.  For an "
37.10043 @@ -10849,7 +9932,7 @@
37.10044  msgstr ""
37.10045  
37.10046  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10047 -#: ../en/ch10-hook.xml:502
37.10048 +#: ../en/ch09-hook.xml:501
37.10049  msgid ""
37.10050  "Whether your hook is written in Python or as a shell script, the hook-"
37.10051  "specific parameter names and values will be the same.  A boolean parameter "
37.10052 @@ -10862,12 +9945,12 @@
37.10053  msgstr ""
37.10054  
37.10055  #. type: Content of: <book><chapter><sect1><sect2><title>
37.10056 -#: ../en/ch10-hook.xml:516
37.10057 +#: ../en/ch09-hook.xml:515
37.10058  msgid "Hook return values and activity control"
37.10059  msgstr "钩子的返回值与活动控制"
37.10060  
37.10061  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10062 -#: ../en/ch10-hook.xml:518
37.10063 +#: ../en/ch09-hook.xml:517
37.10064  msgid ""
37.10065  "A hook that executes successfully must exit with a status of zero if "
37.10066  "external, or return boolean <quote>false</quote> if in-process.  Failure is "
37.10067 @@ -10877,35 +9960,35 @@
37.10068  msgstr ""
37.10069  
37.10070  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10071 -#: ../en/ch10-hook.xml:526
37.10072 +#: ../en/ch09-hook.xml:525
37.10073  msgid ""
37.10074  "For a hook that controls whether an activity can proceed, zero/false means "
37.10075  "<quote>allow</quote>, while non-zero/true/exception means <quote>deny</quote>."
37.10076  msgstr ""
37.10077  
37.10078  #. type: Content of: <book><chapter><sect1><sect2><title>
37.10079 -#: ../en/ch10-hook.xml:533
37.10080 +#: ../en/ch09-hook.xml:532
37.10081  msgid "Writing an external hook"
37.10082  msgstr "编写外部钩子"
37.10083  
37.10084  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10085 -#: ../en/ch10-hook.xml:535
37.10086 -msgid ""
37.10087 -"When you define an external hook in your <filename role=\"special\"> /.hgrc</"
37.10088 -"filename>\\ and the hook is run, its value is passed to your shell, which "
37.10089 +#: ../en/ch09-hook.xml:534
37.10090 +msgid ""
37.10091 +"When you define an external hook in your <filename role=\"special\">~/.hgrc</"
37.10092 +"filename> and the hook is run, its value is passed to your shell, which "
37.10093  "interprets it.  This means that you can use normal shell constructs in the "
37.10094  "body of the hook."
37.10095  msgstr ""
37.10096  
37.10097  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10098 -#: ../en/ch10-hook.xml:542
37.10099 +#: ../en/ch09-hook.xml:541
37.10100  msgid ""
37.10101  "An executable hook is always run with its current directory set to a "
37.10102  "repository's root directory."
37.10103  msgstr ""
37.10104  
37.10105  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10106 -#: ../en/ch10-hook.xml:546
37.10107 +#: ../en/ch09-hook.xml:545
37.10108  msgid ""
37.10109  "Each hook parameter is passed in as an environment variable; the name is "
37.10110  "upper-cased, and prefixed with the string <quote><literal>HG_</literal></"
37.10111 @@ -10913,7 +9996,7 @@
37.10112  msgstr ""
37.10113  
37.10114  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10115 -#: ../en/ch10-hook.xml:551
37.10116 +#: ../en/ch09-hook.xml:550
37.10117  msgid ""
37.10118  "With the exception of hook parameters, Mercurial does not set or modify any "
37.10119  "environment variables when running a hook.  This is useful to remember if you "
37.10120 @@ -10924,14 +10007,14 @@
37.10121  msgstr ""
37.10122  
37.10123  #. type: Content of: <book><chapter><sect1><sect2><title>
37.10124 -#: ../en/ch10-hook.xml:562
37.10125 +#: ../en/ch09-hook.xml:561
37.10126  msgid "Telling Mercurial to use an in-process hook"
37.10127  msgstr "让 Mercurial 使用进程内钩子"
37.10128  
37.10129  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10130 -#: ../en/ch10-hook.xml:564
37.10131 -msgid ""
37.10132 -"The <filename role=\"special\"> /.hgrc</filename>\\ syntax for defining an in-"
37.10133 +#: ../en/ch09-hook.xml:563
37.10134 +msgid ""
37.10135 +"The <filename role=\"special\">~/.hgrc</filename> syntax for defining an in-"
37.10136  "process hook is slightly different than for an executable hook.  The value of "
37.10137  "the hook must start with the text <quote><literal>python:</literal></quote>, "
37.10138  "and continue with the fully-qualified name of a callable object to use as the "
37.10139 @@ -10939,7 +10022,7 @@
37.10140  msgstr ""
37.10141  
37.10142  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10143 -#: ../en/ch10-hook.xml:572
37.10144 +#: ../en/ch09-hook.xml:571
37.10145  msgid ""
37.10146  "The module in which a hook lives is automatically imported when a hook is "
37.10147  "run.  So long as you have the module name and <envar>PYTHONPATH</envar> "
37.10148 @@ -10947,14 +10030,14 @@
37.10149  msgstr ""
37.10150  
37.10151  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10152 -#: ../en/ch10-hook.xml:578
37.10153 -msgid ""
37.10154 -"The following <filename role=\"special\"> /.hgrc</filename>\\ example snippet "
37.10155 +#: ../en/ch09-hook.xml:577
37.10156 +msgid ""
37.10157 +"The following <filename role=\"special\">~/.hgrc</filename> example snippet "
37.10158  "illustrates the syntax and meaning of the notions we just described."
37.10159  msgstr ""
37.10160  
37.10161  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10162 -#: ../en/ch10-hook.xml:584
37.10163 +#: ../en/ch09-hook.xml:583
37.10164  msgid ""
37.10165  "When Mercurial runs the <literal>commit.example</literal> hook, it imports "
37.10166  "<literal>mymodule.submodule</literal>, looks for the callable object named "
37.10167 @@ -10962,19 +10045,19 @@
37.10168  msgstr ""
37.10169  
37.10170  #. type: Content of: <book><chapter><sect1><sect2><title>
37.10171 -#: ../en/ch10-hook.xml:592
37.10172 +#: ../en/ch09-hook.xml:591
37.10173  msgid "Writing an in-process hook"
37.10174  msgstr "编写进程内钩子"
37.10175  
37.10176  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10177 -#: ../en/ch10-hook.xml:594
37.10178 +#: ../en/ch09-hook.xml:593
37.10179  msgid ""
37.10180  "The simplest in-process hook does nothing, but illustrates the basic shape of "
37.10181  "the hook API:"
37.10182  msgstr ""
37.10183  
37.10184  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10185 -#: ../en/ch10-hook.xml:599
37.10186 +#: ../en/ch09-hook.xml:598
37.10187  msgid ""
37.10188  "The first argument to a Python hook is always a <literal role=\"py-mod-"
37.10189  "mercurial.ui\">ui</literal> object.  The second is a repository object; at "
37.10190 @@ -10986,17 +10069,17 @@
37.10191  msgstr ""
37.10192  
37.10193  #. type: Content of: <book><chapter><sect1><title>
37.10194 -#: ../en/ch10-hook.xml:614
37.10195 +#: ../en/ch09-hook.xml:613
37.10196  msgid "Some hook examples"
37.10197  msgstr "钩子样例"
37.10198  
37.10199  #. type: Content of: <book><chapter><sect1><sect2><title>
37.10200 -#: ../en/ch10-hook.xml:617
37.10201 +#: ../en/ch09-hook.xml:616
37.10202  msgid "Writing meaningful commit messages"
37.10203  msgstr "编写有意义的提交日志"
37.10204  
37.10205  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10206 -#: ../en/ch10-hook.xml:619
37.10207 +#: ../en/ch09-hook.xml:618
37.10208  msgid ""
37.10209  "It's hard to imagine a useful commit message being very short. The simple "
37.10210  "<literal role=\"hook\">pretxncommit</literal> hook of the example below will "
37.10211 @@ -11005,12 +10088,12 @@
37.10212  msgstr ""
37.10213  
37.10214  #. type: Content of: <book><chapter><sect1><sect2><title>
37.10215 -#: ../en/ch10-hook.xml:629
37.10216 +#: ../en/ch09-hook.xml:628
37.10217  msgid "Checking for trailing whitespace"
37.10218  msgstr "检查行尾空格"
37.10219  
37.10220  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10221 -#: ../en/ch10-hook.xml:631
37.10222 +#: ../en/ch09-hook.xml:630
37.10223  msgid ""
37.10224  "An interesting use of a commit-related hook is to help you to write cleaner "
37.10225  "code.  A simple example of <quote>cleaner code</quote> is the dictum that a "
37.10226 @@ -11022,7 +10105,7 @@
37.10227  msgstr ""
37.10228  
37.10229  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10230 -#: ../en/ch10-hook.xml:642
37.10231 +#: ../en/ch09-hook.xml:641
37.10232  msgid ""
37.10233  "You can use either the <literal role=\"hook\">precommit</literal> or <literal "
37.10234  "role=\"hook\">pretxncommit</literal> hook to tell whether you have a trailing "
37.10235 @@ -11037,7 +10120,7 @@
37.10236  msgstr ""
37.10237  
37.10238  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10239 -#: ../en/ch10-hook.xml:658
37.10240 +#: ../en/ch09-hook.xml:657
37.10241  msgid ""
37.10242  "Should you choose the <literal role=\"hook\">pretxncommit</literal> hook, the "
37.10243  "check won't occur until just before the transaction for the commit "
37.10244 @@ -11049,7 +10132,7 @@
37.10245  msgstr ""
37.10246  
37.10247  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10248 -#: ../en/ch10-hook.xml:671
37.10249 +#: ../en/ch09-hook.xml:670
37.10250  msgid ""
37.10251  "In this example, we introduce a simple <literal role=\"hook\">pretxncommit</"
37.10252  "literal> hook that checks for trailing whitespace.  This hook is short, but "
37.10253 @@ -11061,7 +10144,7 @@
37.10254  msgstr ""
37.10255  
37.10256  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10257 -#: ../en/ch10-hook.xml:682
37.10258 +#: ../en/ch09-hook.xml:681
37.10259  msgid ""
37.10260  "The above version is much more complex, but also more useful.  It parses a "
37.10261  "unified diff to see if any lines add trailing whitespace, and prints the name "
37.10262 @@ -11074,7 +10157,7 @@
37.10263  msgstr ""
37.10264  
37.10265  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10266 -#: ../en/ch10-hook.xml:696
37.10267 +#: ../en/ch09-hook.xml:695
37.10268  msgid ""
37.10269  "As a final aside, note in the example above the use of <command>perl</"
37.10270  "command>'s in-place editing feature to get rid of trailing whitespace from a "
37.10271 @@ -11082,12 +10165,12 @@
37.10272  msgstr ""
37.10273  
37.10274  #. type: Content of: <book><chapter><sect1><title>
37.10275 -#: ../en/ch10-hook.xml:706
37.10276 +#: ../en/ch09-hook.xml:705
37.10277  msgid "Bundled hooks"
37.10278  msgstr "内置的钩子"
37.10279  
37.10280  #. type: Content of: <book><chapter><sect1><para>
37.10281 -#: ../en/ch10-hook.xml:708
37.10282 +#: ../en/ch09-hook.xml:707
37.10283  msgid ""
37.10284  "Mercurial ships with several bundled hooks.  You can find them in the "
37.10285  "<filename class=\"directory\">hgext</filename> directory of a Mercurial "
37.10286 @@ -11097,14 +10180,14 @@
37.10287  msgstr ""
37.10288  
37.10289  #. type: Content of: <book><chapter><sect1><sect2><title>
37.10290 -#: ../en/ch10-hook.xml:717
37.10291 +#: ../en/ch09-hook.xml:716
37.10292  msgid ""
37.10293  "<literal role=\"hg-ext\">acl</literal>&emdash;access control for parts of a "
37.10294  "repository"
37.10295  msgstr "<literal role=\"hg-ext\">acl</literal>&emdash;版本库的访问控制"
37.10296  
37.10297  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10298 -#: ../en/ch10-hook.xml:720
37.10299 +#: ../en/ch09-hook.xml:719
37.10300  msgid ""
37.10301  "The <literal role=\"hg-ext\">acl</literal> extension lets you control which "
37.10302  "remote users are allowed to push changesets to a networked server.  You can "
37.10303 @@ -11114,7 +10197,7 @@
37.10304  msgstr ""
37.10305  
37.10306  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10307 -#: ../en/ch10-hook.xml:728
37.10308 +#: ../en/ch09-hook.xml:727
37.10309  msgid ""
37.10310  "This extension implements access control based on the identity of the user "
37.10311  "performing a push, <emphasis>not</emphasis> on who committed the changesets "
37.10312 @@ -11124,12 +10207,12 @@
37.10313  msgstr ""
37.10314  
37.10315  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
37.10316 -#: ../en/ch10-hook.xml:738
37.10317 +#: ../en/ch09-hook.xml:737
37.10318  msgid "Configuring the <literal role=\"hook\">acl</literal> hook"
37.10319  msgstr "配置 <literal role=\"hook\">acl</literal> 钩子"
37.10320  
37.10321  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10322 -#: ../en/ch10-hook.xml:741
37.10323 +#: ../en/ch09-hook.xml:740
37.10324  msgid ""
37.10325  "In order to manage incoming changesets, the <literal role=\"hg-ext\">acl</"
37.10326  "literal> hook must be used as a <literal role=\"hook\">pretxnchangegroup</"
37.10327 @@ -11139,14 +10222,14 @@
37.10328  msgstr ""
37.10329  
37.10330  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10331 -#: ../en/ch10-hook.xml:751
37.10332 +#: ../en/ch09-hook.xml:750
37.10333  msgid ""
37.10334  "The <literal role=\"hg-ext\">acl</literal> extension is configured using "
37.10335  "three sections."
37.10336  msgstr ""
37.10337  
37.10338  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10339 -#: ../en/ch10-hook.xml:755
37.10340 +#: ../en/ch09-hook.xml:754
37.10341  msgid ""
37.10342  "The <literal role=\"rc-acl\">acl</literal> section has only one entry, <envar "
37.10343  "role=\"rc-item-acl\">sources</envar>, which lists the sources of incoming "
37.10344 @@ -11155,7 +10238,7 @@
37.10345  msgstr ""
37.10346  
37.10347  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.10348 -#: ../en/ch10-hook.xml:762
37.10349 +#: ../en/ch09-hook.xml:761
37.10350  msgid ""
37.10351  "<envar role=\"rc-item-acl\">serve</envar>: Control incoming changesets that "
37.10352  "are arriving from a remote repository over http or ssh.  This is the default "
37.10353 @@ -11164,28 +10247,28 @@
37.10354  msgstr ""
37.10355  
37.10356  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.10357 -#: ../en/ch10-hook.xml:770
37.10358 +#: ../en/ch09-hook.xml:769
37.10359  msgid ""
37.10360  "<envar role=\"rc-item-acl\">pull</envar>: Control incoming changesets that "
37.10361  "are arriving via a pull from a local repository."
37.10362  msgstr ""
37.10363  
37.10364  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.10365 -#: ../en/ch10-hook.xml:775
37.10366 +#: ../en/ch09-hook.xml:774
37.10367  msgid ""
37.10368  "<envar role=\"rc-item-acl\">push</envar>: Control incoming changesets that "
37.10369  "are arriving via a push from a local repository."
37.10370  msgstr ""
37.10371  
37.10372  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.10373 -#: ../en/ch10-hook.xml:780
37.10374 +#: ../en/ch09-hook.xml:779
37.10375  msgid ""
37.10376  "<envar role=\"rc-item-acl\">bundle</envar>: Control incoming changesets that "
37.10377  "are arriving from another repository via a bundle."
37.10378  msgstr ""
37.10379  
37.10380  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10381 -#: ../en/ch10-hook.xml:786
37.10382 +#: ../en/ch09-hook.xml:785
37.10383  msgid ""
37.10384  "The <literal role=\"rc-acl.allow\">acl.allow</literal> section controls the "
37.10385  "users that are allowed to add changesets to the repository.  If this section "
37.10386 @@ -11195,7 +10278,7 @@
37.10387  msgstr ""
37.10388  
37.10389  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10390 -#: ../en/ch10-hook.xml:795
37.10391 +#: ../en/ch09-hook.xml:794
37.10392  msgid ""
37.10393  "The <literal role=\"rc-acl.deny\">acl.deny</literal> section determines which "
37.10394  "users are denied from adding changesets to the repository.  If this section "
37.10395 @@ -11203,7 +10286,7 @@
37.10396  msgstr ""
37.10397  
37.10398  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10399 -#: ../en/ch10-hook.xml:801
37.10400 +#: ../en/ch09-hook.xml:800
37.10401  msgid ""
37.10402  "The syntaxes for the <literal role=\"rc-acl.allow\">acl.allow</literal> and "
37.10403  "<literal role=\"rc-acl.deny\">acl.deny</literal> sections are identical.  On "
37.10404 @@ -11212,7 +10295,7 @@
37.10405  msgstr ""
37.10406  
37.10407  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10408 -#: ../en/ch10-hook.xml:809
37.10409 +#: ../en/ch09-hook.xml:808
37.10410  msgid ""
37.10411  "In the following example, the user <literal>docwriter</literal> can only push "
37.10412  "changes to the <filename class=\"directory\">docs</filename> subtree of the "
37.10413 @@ -11221,23 +10304,23 @@
37.10414  msgstr ""
37.10415  
37.10416  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
37.10417 -#: ../en/ch10-hook.xml:821 ../en/ch10-hook.xml:1095 ../en/ch10-hook.xml:1308
37.10418 +#: ../en/ch09-hook.xml:822 ../en/ch09-hook.xml:1089 ../en/ch09-hook.xml:1280
37.10419  msgid "Testing and troubleshooting"
37.10420  msgstr "测试与问题处理"
37.10421  
37.10422  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10423 -#: ../en/ch10-hook.xml:823
37.10424 +#: ../en/ch09-hook.xml:824
37.10425  msgid ""
37.10426  "If you want to test the <literal role=\"hg-ext\">acl</literal> hook, run it "
37.10427  "with Mercurial's debugging output enabled.  Since you'll probably be running "
37.10428  "it on a server where it's not convenient (or sometimes possible) to pass in "
37.10429  "the <option role=\"hg-opt-global\">--debug</option> option, don't forget that "
37.10430 -"you can enable debugging output in your <filename role=\"special\"> /.hgrc</"
37.10431 +"you can enable debugging output in your <filename role=\"special\">~/.hgrc</"
37.10432  "filename>:"
37.10433  msgstr ""
37.10434  
37.10435  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10436 -#: ../en/ch10-hook.xml:833
37.10437 +#: ../en/ch09-hook.xml:835
37.10438  msgid ""
37.10439  "With this enabled, the <literal role=\"hg-ext\">acl</literal> hook will print "
37.10440  "enough information to let you figure out why it is allowing or forbidding "
37.10441 @@ -11245,13 +10328,13 @@
37.10442  msgstr ""
37.10443  
37.10444  #. type: Content of: <book><chapter><sect1><sect2><title>
37.10445 -#: ../en/ch10-hook.xml:842
37.10446 +#: ../en/ch09-hook.xml:844
37.10447  msgid ""
37.10448  "<literal role=\"hg-ext\">bugzilla</literal>&emdash;integration with Bugzilla"
37.10449  msgstr "<literal role=\"hg-ext\">bugzilla</literal>&emdash;与 Bugzilla 的集成"
37.10450  
37.10451  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10452 -#: ../en/ch10-hook.xml:846
37.10453 +#: ../en/ch09-hook.xml:848
37.10454  msgid ""
37.10455  "The <literal role=\"hg-ext\">bugzilla</literal> extension adds a comment to a "
37.10456  "Bugzilla bug whenever it finds a reference to that bug ID in a commit "
37.10457 @@ -11260,14 +10343,14 @@
37.10458  msgstr ""
37.10459  
37.10460  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10461 -#: ../en/ch10-hook.xml:853
37.10462 +#: ../en/ch09-hook.xml:855
37.10463  msgid ""
37.10464  "It adds a comment to the bug that looks like this (you can configure the "
37.10465  "contents of the comment&emdash;see below):"
37.10466  msgstr ""
37.10467  
37.10468  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10469 -#: ../en/ch10-hook.xml:862
37.10470 +#: ../en/ch09-hook.xml:864
37.10471  msgid ""
37.10472  "The value of this hook is that it automates the process of updating a bug any "
37.10473  "time a changeset refers to it.  If you configure the hook properly, it makes "
37.10474 @@ -11276,14 +10359,14 @@
37.10475  msgstr ""
37.10476  
37.10477  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10478 -#: ../en/ch10-hook.xml:869
37.10479 +#: ../en/ch09-hook.xml:871
37.10480  msgid ""
37.10481  "You can use the code in this hook as a starting point for some more exotic "
37.10482  "Bugzilla integration recipes.  Here are a few possibilities:"
37.10483  msgstr ""
37.10484  
37.10485  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.10486 -#: ../en/ch10-hook.xml:874
37.10487 +#: ../en/ch09-hook.xml:876
37.10488  msgid ""
37.10489  "Require that every changeset pushed to the server have a valid bug ID in its "
37.10490  "commit comment.  In this case, you'd want to configure the hook as a <literal "
37.10491 @@ -11292,7 +10375,7 @@
37.10492  msgstr ""
37.10493  
37.10494  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.10495 -#: ../en/ch10-hook.xml:882
37.10496 +#: ../en/ch09-hook.xml:884
37.10497  msgid ""
37.10498  "Allow incoming changesets to automatically modify the <emphasis>state</"
37.10499  "emphasis> of a bug, as well as simply adding a comment.  For example, the "
37.10500 @@ -11302,20 +10385,23 @@
37.10501  msgstr ""
37.10502  
37.10503  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
37.10504 -#: ../en/ch10-hook.xml:892
37.10505 +#: ../en/ch09-hook.xml:894
37.10506  msgid "Configuring the <literal role=\"hook\">bugzilla</literal> hook"
37.10507  msgstr "配置 <literal role=\"hook\">bugzilla</literal> 钩子"
37.10508  
37.10509  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10510 -#: ../en/ch10-hook.xml:895
37.10511 -msgid ""
37.10512 -"You should configure this hook in your server's <filename role=\"special\"> /."
37.10513 -"hgrc</filename>\\ as an <literal role=\"hook\">incoming</literal> hook, for "
37.10514 +#: ../en/ch09-hook.xml:897
37.10515 +#, fuzzy
37.10516 +msgid ""
37.10517 +"You should configure this hook in your server's <filename role=\"special\">~/."
37.10518 +"hgrc</filename> as an <literal role=\"hook\">incoming</literal> hook, for "
37.10519  "example as follows:"
37.10520  msgstr ""
37.10521 +"选择正确的 <filename role=\"special\"> /.hgrc</filename> 文件增加到 <literal "
37.10522 +"role=\"rc-web\">web</literal> 条目"
37.10523  
37.10524  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10525 -#: ../en/ch10-hook.xml:903
37.10526 +#: ../en/ch09-hook.xml:905
37.10527  msgid ""
37.10528  "Because of the specialised nature of this hook, and because Bugzilla was not "
37.10529  "written with this kind of integration in mind, configuring this hook is a "
37.10530 @@ -11323,7 +10409,7 @@
37.10531  msgstr ""
37.10532  
37.10533  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10534 -#: ../en/ch10-hook.xml:909
37.10535 +#: ../en/ch09-hook.xml:911
37.10536  msgid ""
37.10537  "Before you begin, you must install the MySQL bindings for Python on the host"
37.10538  "(s) where you'll be running the hook.  If this is not available as a binary "
37.10539 @@ -11332,15 +10418,15 @@
37.10540  msgstr ""
37.10541  
37.10542  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10543 -#: ../en/ch10-hook.xml:916
37.10544 +#: ../en/ch09-hook.xml:918
37.10545  msgid ""
37.10546  "Configuration information for this hook lives in the <literal role=\"rc-"
37.10547 -"bugzilla\">bugzilla</literal> section of your <filename role=\"special\"> /."
37.10548 +"bugzilla\">bugzilla</literal> section of your <filename role=\"special\">~/."
37.10549  "hgrc</filename>."
37.10550  msgstr ""
37.10551  
37.10552  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.10553 -#: ../en/ch10-hook.xml:921
37.10554 +#: ../en/ch09-hook.xml:923
37.10555  msgid ""
37.10556  "<envar role=\"rc-item-bugzilla\">version</envar>: The version of Bugzilla "
37.10557  "installed on the server.  The database schema that Bugzilla uses changes "
37.10558 @@ -11349,7 +10435,7 @@
37.10559  msgstr ""
37.10560  
37.10561  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.10562 -#: ../en/ch10-hook.xml:930
37.10563 +#: ../en/ch09-hook.xml:932
37.10564  msgid ""
37.10565  "<envar role=\"rc-item-bugzilla\">host</envar>: The hostname of the MySQL "
37.10566  "server that stores your Bugzilla data.  The database must be configured to "
37.10567 @@ -11358,7 +10444,7 @@
37.10568  msgstr ""
37.10569  
37.10570  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.10571 -#: ../en/ch10-hook.xml:937
37.10572 +#: ../en/ch09-hook.xml:939
37.10573  msgid ""
37.10574  "<envar role=\"rc-item-bugzilla\">user</envar>: The username with which to "
37.10575  "connect to the MySQL server.  The database must be configured to allow this "
37.10576 @@ -11369,16 +10455,16 @@
37.10577  msgstr ""
37.10578  
37.10579  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.10580 -#: ../en/ch10-hook.xml:948
37.10581 +#: ../en/ch09-hook.xml:950
37.10582  msgid ""
37.10583  "<envar role=\"rc-item-bugzilla\">password</envar>: The MySQL password for the "
37.10584  "user you configured above.  This is stored as plain text, so you should make "
37.10585 -"sure that unauthorised users cannot read the <filename role=\"special\"> /."
37.10586 -"hgrc</filename>\\ file where you store this information."
37.10587 +"sure that unauthorised users cannot read the <filename role=\"special\">~/."
37.10588 +"hgrc</filename> file where you store this information."
37.10589  msgstr ""
37.10590  
37.10591  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.10592 -#: ../en/ch10-hook.xml:957
37.10593 +#: ../en/ch09-hook.xml:959
37.10594  msgid ""
37.10595  "<envar role=\"rc-item-bugzilla\">db</envar>: The name of the Bugzilla "
37.10596  "database on the MySQL server.  The default value of this item is "
37.10597 @@ -11387,7 +10473,7 @@
37.10598  msgstr ""
37.10599  
37.10600  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.10601 -#: ../en/ch10-hook.xml:964
37.10602 +#: ../en/ch09-hook.xml:966
37.10603  msgid ""
37.10604  "<envar role=\"rc-item-bugzilla\">notify</envar>: If you want Bugzilla to send "
37.10605  "out a notification email to subscribers after this hook has added a comment "
37.10606 @@ -11398,7 +10484,7 @@
37.10607  msgstr ""
37.10608  
37.10609  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.10610 -#: ../en/ch10-hook.xml:977
37.10611 +#: ../en/ch09-hook.xml:979
37.10612  msgid ""
37.10613  "The Bugzilla <literal>processmail</literal> program expects to be given a bug "
37.10614  "ID (the hook replaces <quote><literal>%s</literal></quote> with the bug ID)  "
37.10615 @@ -11409,12 +10495,12 @@
37.10616  msgstr ""
37.10617  
37.10618  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
37.10619 -#: ../en/ch10-hook.xml:992
37.10620 +#: ../en/ch09-hook.xml:994
37.10621  msgid "Mapping committer names to Bugzilla user names"
37.10622  msgstr "提交者的名称与 Bugzilla 用户名称的映射"
37.10623  
37.10624  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10625 -#: ../en/ch10-hook.xml:994
37.10626 +#: ../en/ch09-hook.xml:996
37.10627  msgid ""
37.10628  "By default, the <literal role=\"hg-ext\">bugzilla</literal> hook tries to use "
37.10629  "the email address of a changeset's committer as the Bugzilla user name with "
37.10630 @@ -11424,14 +10510,14 @@
37.10631  msgstr ""
37.10632  
37.10633  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10634 -#: ../en/ch10-hook.xml:1003
37.10635 +#: ../en/ch09-hook.xml:1005
37.10636  msgid ""
37.10637  "Each item in the <literal role=\"rc-usermap\">usermap</literal> section "
37.10638  "contains an email address on the left, and a Bugzilla user name on the right."
37.10639  msgstr ""
37.10640  
37.10641  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10642 -#: ../en/ch10-hook.xml:1010
37.10643 +#: ../en/ch09-hook.xml:1012
37.10644  msgid ""
37.10645  "You can either keep the <literal role=\"rc-usermap\">usermap</literal> data "
37.10646  "in a normal <filename role=\"special\">~/.hgrc</filename>, or tell the "
37.10647 @@ -11440,32 +10526,32 @@
37.10648  "store <filename>usermap</filename> data by itself in (for example)  a user-"
37.10649  "modifiable repository.  This makes it possible to let your users maintain "
37.10650  "their own <envar role=\"rc-item-bugzilla\">usermap</envar> entries.  The main "
37.10651 -"<filename role=\"special\"> /.hgrc</filename>\\ file might look like this:"
37.10652 +"<filename role=\"special\">~/.hgrc</filename> file might look like this:"
37.10653  msgstr ""
37.10654  
37.10655  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10656 -#: ../en/ch10-hook.xml:1026
37.10657 +#: ../en/ch09-hook.xml:1028
37.10658  msgid ""
37.10659  "While the <filename>usermap</filename> file that it refers to might look like "
37.10660  "this:"
37.10661  msgstr ""
37.10662  
37.10663  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
37.10664 -#: ../en/ch10-hook.xml:1035
37.10665 +#: ../en/ch09-hook.xml:1036
37.10666  msgid "Configuring the text that gets added to a bug"
37.10667  msgstr "配置增加到问题中的正文"
37.10668  
37.10669  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10670 -#: ../en/ch10-hook.xml:1037
37.10671 +#: ../en/ch09-hook.xml:1038
37.10672  msgid ""
37.10673  "You can configure the text that this hook adds as a comment; you specify it "
37.10674 -"in the form of a Mercurial template.  Several <filename role=\"special\"> /."
37.10675 -"hgrc</filename>\\ entries (still in the <literal role=\"rc-bugzilla"
37.10676 -"\">bugzilla</literal> section) control this behaviour."
37.10677 +"in the form of a Mercurial template.  Several <filename role=\"special\">~/."
37.10678 +"hgrc</filename> entries (still in the <literal role=\"rc-bugzilla\">bugzilla</"
37.10679 +"literal> section) control this behaviour."
37.10680  msgstr ""
37.10681  
37.10682  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.10683 -#: ../en/ch10-hook.xml:1044
37.10684 +#: ../en/ch09-hook.xml:1045
37.10685  msgid ""
37.10686  "<literal>strip</literal>: The number of leading path elements to strip from a "
37.10687  "repository's path name to construct a partial path for a URL. For example, if "
37.10688 @@ -11479,7 +10565,7 @@
37.10689  msgstr ""
37.10690  
37.10691  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.10692 -#: ../en/ch10-hook.xml:1058
37.10693 +#: ../en/ch09-hook.xml:1059
37.10694  msgid ""
37.10695  "<literal>template</literal>: The text of the template to use.  In addition to "
37.10696  "the usual changeset-related variables, this template can use <literal>hgweb</"
37.10697 @@ -11489,25 +10575,25 @@
37.10698  msgstr ""
37.10699  
37.10700  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10701 -#: ../en/ch10-hook.xml:1068
37.10702 +#: ../en/ch09-hook.xml:1069
37.10703  msgid ""
37.10704  "In addition, you can add a <envar role=\"rc-item-web\">baseurl</envar> item "
37.10705  "to the <literal role=\"rc-web\">web</literal> section of your <filename role="
37.10706 -"\"special\"> /.hgrc</filename>.  The <literal role=\"hg-ext\">bugzilla</"
37.10707 +"\"special\">~/.hgrc</filename>.  The <literal role=\"hg-ext\">bugzilla</"
37.10708  "literal> hook will make this available when expanding a template, as the base "
37.10709  "string to use when constructing a URL that will let users browse from a "
37.10710  "Bugzilla comment to view a changeset.  Example:"
37.10711  msgstr ""
37.10712  
37.10713  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10714 -#: ../en/ch10-hook.xml:1080
37.10715 +#: ../en/ch09-hook.xml:1081
37.10716  msgid ""
37.10717  "Here is an example set of <literal role=\"hg-ext\">bugzilla</literal> hook "
37.10718  "config information."
37.10719  msgstr ""
37.10720  
37.10721  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10722 -#: ../en/ch10-hook.xml:1097
37.10723 +#: ../en/ch09-hook.xml:1091
37.10724  msgid ""
37.10725  "The most common problems with configuring the <literal role=\"hg-ext"
37.10726  "\">bugzilla</literal> hook relate to running Bugzilla's "
37.10727 @@ -11516,7 +10602,7 @@
37.10728  msgstr ""
37.10729  
37.10730  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10731 -#: ../en/ch10-hook.xml:1103
37.10732 +#: ../en/ch09-hook.xml:1097
37.10733  msgid ""
37.10734  "Recall from section <xref linkend=\"sec.hook.bugzilla.config\"/> above that "
37.10735  "the user that runs the Mercurial process on the server is also the one that "
37.10736 @@ -11527,7 +10613,7 @@
37.10737  msgstr ""
37.10738  
37.10739  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10740 -#: ../en/ch10-hook.xml:1114
37.10741 +#: ../en/ch09-hook.xml:1108
37.10742  msgid ""
37.10743  "You can cause <filename>processmail</filename> to be run with the suitable "
37.10744  "user's identity using the <command>sudo</command> command.  Here is an "
37.10745 @@ -11535,7 +10621,7 @@
37.10746  msgstr ""
37.10747  
37.10748  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10749 -#: ../en/ch10-hook.xml:1122
37.10750 +#: ../en/ch09-hook.xml:1115
37.10751  msgid ""
37.10752  "This allows the <literal>hg_user</literal> user to run a "
37.10753  "<filename>processmail-wrapper</filename> program under the identity of "
37.10754 @@ -11543,7 +10629,7 @@
37.10755  msgstr ""
37.10756  
37.10757  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10758 -#: ../en/ch10-hook.xml:1127
37.10759 +#: ../en/ch09-hook.xml:1120
37.10760  msgid ""
37.10761  "This indirection through a wrapper script is necessary, because "
37.10762  "<filename>processmail</filename> expects to be run with its current directory "
37.10763 @@ -11553,14 +10639,14 @@
37.10764  msgstr ""
37.10765  
37.10766  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10767 -#: ../en/ch10-hook.xml:1136
37.10768 +#: ../en/ch09-hook.xml:1129
37.10769  msgid ""
37.10770  "It doesn't seem to matter what email address you pass to "
37.10771  "<filename>processmail</filename>."
37.10772  msgstr ""
37.10773  
37.10774  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10775 -#: ../en/ch10-hook.xml:1140
37.10776 +#: ../en/ch09-hook.xml:1133
37.10777  msgid ""
37.10778  "If your <literal role=\"rc-usermap\">usermap</literal> is not set up "
37.10779  "correctly, users will see an error message from the <literal role=\"hg-ext"
37.10780 @@ -11569,7 +10655,7 @@
37.10781  msgstr ""
37.10782  
37.10783  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10784 -#: ../en/ch10-hook.xml:1148
37.10785 +#: ../en/ch09-hook.xml:1140
37.10786  msgid ""
37.10787  "What this means is that the committer's address, <literal>john.q."
37.10788  "public@example.com</literal>, is not a valid Bugzilla user name, nor does it "
37.10789 @@ -11578,13 +10664,13 @@
37.10790  msgstr ""
37.10791  
37.10792  #. type: Content of: <book><chapter><sect1><sect2><title>
37.10793 -#: ../en/ch10-hook.xml:1158
37.10794 +#: ../en/ch09-hook.xml:1150
37.10795  msgid ""
37.10796  "<literal role=\"hg-ext\">notify</literal>&emdash;send email notifications"
37.10797  msgstr "<literal role=\"hg-ext\">notify</literal>&emdash;邮件通知"
37.10798  
37.10799  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10800 -#: ../en/ch10-hook.xml:1161
37.10801 +#: ../en/ch09-hook.xml:1153
37.10802  msgid ""
37.10803  "Although Mercurial's built-in web server provides RSS feeds of changes in "
37.10804  "every repository, many people prefer to receive change notifications via "
37.10805 @@ -11594,7 +10680,7 @@
37.10806  msgstr ""
37.10807  
37.10808  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10809 -#: ../en/ch10-hook.xml:1169
37.10810 +#: ../en/ch09-hook.xml:1161
37.10811  msgid ""
37.10812  "As with the <literal role=\"hg-ext\">bugzilla</literal> hook, the <literal "
37.10813  "role=\"hg-ext\">notify</literal> hook is template-driven, so you can "
37.10814 @@ -11602,7 +10688,7 @@
37.10815  msgstr ""
37.10816  
37.10817  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10818 -#: ../en/ch10-hook.xml:1175
37.10819 +#: ../en/ch09-hook.xml:1167
37.10820  msgid ""
37.10821  "By default, the <literal role=\"hg-ext\">notify</literal> hook includes a "
37.10822  "diff of every changeset that it sends out; you can limit the size of the "
37.10823 @@ -11611,12 +10697,12 @@
37.10824  msgstr ""
37.10825  
37.10826  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
37.10827 -#: ../en/ch10-hook.xml:1183
37.10828 +#: ../en/ch09-hook.xml:1175
37.10829  msgid "Configuring the <literal role=\"hg-ext\">notify</literal> hook"
37.10830  msgstr "配置 <literal role=\"hg-ext\">notify</literal> 钩子"
37.10831  
37.10832  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10833 -#: ../en/ch10-hook.xml:1186
37.10834 +#: ../en/ch09-hook.xml:1178
37.10835  msgid ""
37.10836  "You can set up the <literal role=\"hg-ext\">notify</literal> hook to send one "
37.10837  "email message per incoming changeset, or one per incoming group of changesets "
37.10838 @@ -11624,15 +10710,15 @@
37.10839  msgstr ""
37.10840  
37.10841  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10842 -#: ../en/ch10-hook.xml:1197
37.10843 +#: ../en/ch09-hook.xml:1190
37.10844  msgid ""
37.10845  "Configuration information for this hook lives in the <literal role=\"rc-notify"
37.10846 -"\">notify</literal> section of a <filename role=\"special\"> /.hgrc</filename>"
37.10847 -"\\ file."
37.10848 +"\">notify</literal> section of a <filename role=\"special\">~/.hgrc</"
37.10849 +"filename> file."
37.10850  msgstr ""
37.10851  
37.10852  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.10853 -#: ../en/ch10-hook.xml:1202
37.10854 +#: ../en/ch09-hook.xml:1195
37.10855  msgid ""
37.10856  "<envar role=\"rc-item-notify\">test</envar>: By default, this hook does not "
37.10857  "send out email at all; instead, it prints the message that it "
37.10858 @@ -11644,17 +10730,17 @@
37.10859  msgstr ""
37.10860  
37.10861  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.10862 -#: ../en/ch10-hook.xml:1214
37.10863 +#: ../en/ch09-hook.xml:1207
37.10864  msgid ""
37.10865  "<envar role=\"rc-item-notify\">config</envar>: The path to a configuration "
37.10866  "file that contains subscription information.  This is kept separate from the "
37.10867 -"main <filename role=\"special\"> /.hgrc</filename>\\ so that you can maintain "
37.10868 +"main <filename role=\"special\">~/.hgrc</filename> so that you can maintain "
37.10869  "it in a repository of its own.  People can then clone that repository, update "
37.10870  "their subscriptions, and push the changes back to your server."
37.10871  msgstr ""
37.10872  
37.10873  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.10874 -#: ../en/ch10-hook.xml:1223
37.10875 +#: ../en/ch09-hook.xml:1216
37.10876  msgid ""
37.10877  "<envar role=\"rc-item-notify\">strip</envar>: The number of leading path "
37.10878  "separator characters to strip from a repository's path, when deciding whether "
37.10879 @@ -11669,7 +10755,7 @@
37.10880  msgstr ""
37.10881  
37.10882  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.10883 -#: ../en/ch10-hook.xml:1240
37.10884 +#: ../en/ch09-hook.xml:1233
37.10885  msgid ""
37.10886  "<envar role=\"rc-item-notify\">template</envar>: The template text to use "
37.10887  "when sending messages.  This specifies both the contents of the message "
37.10888 @@ -11677,7 +10763,7 @@
37.10889  msgstr ""
37.10890  
37.10891  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.10892 -#: ../en/ch10-hook.xml:1246
37.10893 +#: ../en/ch09-hook.xml:1239
37.10894  msgid ""
37.10895  "<envar role=\"rc-item-notify\">maxdiff</envar>: The maximum number of lines "
37.10896  "of diff data to append to the end of a message.  If a diff is longer than "
37.10897 @@ -11686,7 +10772,7 @@
37.10898  msgstr ""
37.10899  
37.10900  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.10901 -#: ../en/ch10-hook.xml:1255
37.10902 +#: ../en/ch09-hook.xml:1248
37.10903  msgid ""
37.10904  "<envar role=\"rc-item-notify\">sources</envar>: A list of sources of "
37.10905  "changesets to consider.  This lets you limit <literal role=\"hg-ext\">notify</"
37.10906 @@ -11696,7 +10782,7 @@
37.10907  msgstr ""
37.10908  
37.10909  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10910 -#: ../en/ch10-hook.xml:1267
37.10911 +#: ../en/ch09-hook.xml:1260
37.10912  msgid ""
37.10913  "If you set the <envar role=\"rc-item-web\">baseurl</envar> item in the "
37.10914  "<literal role=\"rc-web\">web</literal> section, you can use it in a template; "
37.10915 @@ -11704,19 +10790,19 @@
37.10916  msgstr ""
37.10917  
37.10918  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10919 -#: ../en/ch10-hook.xml:1273
37.10920 +#: ../en/ch09-hook.xml:1266
37.10921  msgid ""
37.10922  "Here is an example set of <literal role=\"hg-ext\">notify</literal> "
37.10923  "configuration information."
37.10924  msgstr ""
37.10925  
37.10926  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10927 -#: ../en/ch10-hook.xml:1289
37.10928 +#: ../en/ch09-hook.xml:1272
37.10929  msgid "This will produce a message that looks like the following:"
37.10930  msgstr ""
37.10931  
37.10932  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.10933 -#: ../en/ch10-hook.xml:1310
37.10934 +#: ../en/ch09-hook.xml:1282
37.10935  msgid ""
37.10936  "Do not forget that by default, the <literal role=\"hg-ext\">notify</literal> "
37.10937  "extension <emphasis>will not send any mail</emphasis> until you explicitly "
37.10938 @@ -11726,22 +10812,22 @@
37.10939  msgstr ""
37.10940  
37.10941  #. type: Content of: <book><chapter><sect1><title>
37.10942 -#: ../en/ch10-hook.xml:1322
37.10943 +#: ../en/ch09-hook.xml:1294
37.10944  msgid "Information for writers of hooks"
37.10945  msgstr "编写钩子的信息"
37.10946  
37.10947  #. type: Content of: <book><chapter><sect1><sect2><title>
37.10948 -#: ../en/ch10-hook.xml:1325
37.10949 +#: ../en/ch09-hook.xml:1297
37.10950  msgid "In-process hook execution"
37.10951  msgstr "进程内钩子的执行"
37.10952  
37.10953  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10954 -#: ../en/ch10-hook.xml:1327
37.10955 +#: ../en/ch09-hook.xml:1299
37.10956  msgid "An in-process hook is called with arguments of the following form:"
37.10957  msgstr ""
37.10958  
37.10959  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10960 -#: ../en/ch10-hook.xml:1333
37.10961 +#: ../en/ch09-hook.xml:1303
37.10962  msgid ""
37.10963  "The <literal>ui</literal> parameter is a <literal role=\"py-mod-mercurial.ui"
37.10964  "\">ui</literal> object. The <literal>repo</literal> parameter is a <literal "
37.10965 @@ -11751,7 +10837,7 @@
37.10966  msgstr ""
37.10967  
37.10968  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.10969 -#: ../en/ch10-hook.xml:1342
37.10970 +#: ../en/ch09-hook.xml:1312
37.10971  msgid ""
37.10972  "If a parameter is named <literal>node</literal> or <literal>parentN</"
37.10973  "literal>, it will contain a hexadecimal changeset ID. The empty string is "
37.10974 @@ -11760,21 +10846,21 @@
37.10975  msgstr ""
37.10976  
37.10977  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.10978 -#: ../en/ch10-hook.xml:1349
37.10979 +#: ../en/ch09-hook.xml:1319
37.10980  msgid ""
37.10981  "If a parameter is named <literal>url</literal>, it will contain the URL of a "
37.10982  "remote repository, if that can be determined."
37.10983  msgstr ""
37.10984  
37.10985  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.10986 -#: ../en/ch10-hook.xml:1354
37.10987 +#: ../en/ch09-hook.xml:1324
37.10988  msgid ""
37.10989  "Boolean-valued parameters are represented as Python <literal>bool</literal> "
37.10990  "objects."
37.10991  msgstr ""
37.10992  
37.10993  #. type: Content of: <book><chapter><sect1><sect2><para>
37.10994 -#: ../en/ch10-hook.xml:1359
37.10995 +#: ../en/ch09-hook.xml:1329
37.10996  msgid ""
37.10997  "An in-process hook is called without a change to the process's working "
37.10998  "directory (unlike external hooks, which are run in the root of the "
37.10999 @@ -11783,7 +10869,7 @@
37.11000  msgstr ""
37.11001  
37.11002  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11003 -#: ../en/ch10-hook.xml:1366
37.11004 +#: ../en/ch09-hook.xml:1336
37.11005  msgid ""
37.11006  "If a hook returns a boolean <quote>false</quote> value, it is considered to "
37.11007  "have succeeded.  If it returns a boolean <quote>true</quote> value or raises "
37.11008 @@ -11792,20 +10878,20 @@
37.11009  msgstr ""
37.11010  
37.11011  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11012 -#: ../en/ch10-hook.xml:1373
37.11013 +#: ../en/ch09-hook.xml:1343
37.11014  msgid ""
37.11015  "Note that changeset IDs are passed into Python hooks as hexadecimal strings, "
37.11016  "not the binary hashes that Mercurial's APIs normally use.  To convert a hash "
37.11017 -"from hex to binary, use the \\pymodfunc{mercurial.node}{bin} function."
37.11018 -msgstr ""
37.11019 -
37.11020 -#. type: Content of: <book><chapter><sect1><sect2><title>
37.11021 -#: ../en/ch10-hook.xml:1381
37.11022 +"from hex to binary, use the <literal>bin</literal> function."
37.11023 +msgstr ""
37.11024 +
37.11025 +#. type: Content of: <book><chapter><sect1><sect2><title>
37.11026 +#: ../en/ch09-hook.xml:1351
37.11027  msgid "External hook execution"
37.11028  msgstr "外部钩子的执行"
37.11029  
37.11030  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11031 -#: ../en/ch10-hook.xml:1383
37.11032 +#: ../en/ch09-hook.xml:1353
37.11033  msgid ""
37.11034  "An external hook is passed to the shell of the user running Mercurial. "
37.11035  "Features of that shell, such as variable substitution and command "
37.11036 @@ -11815,7 +10901,7 @@
37.11037  msgstr ""
37.11038  
37.11039  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11040 -#: ../en/ch10-hook.xml:1391
37.11041 +#: ../en/ch09-hook.xml:1361
37.11042  msgid ""
37.11043  "Hook parameters are passed to the hook as environment variables.  Each "
37.11044  "environment variable's name is converted in upper case and prefixed with the "
37.11045 @@ -11826,7 +10912,7 @@
37.11046  msgstr ""
37.11047  
37.11048  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11049 -#: ../en/ch10-hook.xml:1400
37.11050 +#: ../en/ch09-hook.xml:1370
37.11051  msgid ""
37.11052  "A boolean parameter is represented as the string <quote><literal>1</literal></"
37.11053  "quote> for <quote>true</quote>, <quote><literal>0</literal></quote> for "
37.11054 @@ -11839,19 +10925,19 @@
37.11055  msgstr ""
37.11056  
37.11057  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11058 -#: ../en/ch10-hook.xml:1412
37.11059 +#: ../en/ch09-hook.xml:1382
37.11060  msgid ""
37.11061  "If a hook exits with a status of zero, it is considered to have succeeded.  "
37.11062  "If it exits with a non-zero status, it is considered to have failed."
37.11063  msgstr ""
37.11064  
37.11065  #. type: Content of: <book><chapter><sect1><sect2><title>
37.11066 -#: ../en/ch10-hook.xml:1419
37.11067 +#: ../en/ch09-hook.xml:1389
37.11068  msgid "Finding out where changesets come from"
37.11069  msgstr "检查修改集来自何处"
37.11070  
37.11071  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11072 -#: ../en/ch10-hook.xml:1421
37.11073 +#: ../en/ch09-hook.xml:1391
37.11074  msgid ""
37.11075  "A hook that involves the transfer of changesets between a local repository "
37.11076  "and another may be able to find out information about the <quote>far side</"
37.11077 @@ -11861,12 +10947,12 @@
37.11078  msgstr ""
37.11079  
37.11080  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
37.11081 -#: ../en/ch10-hook.xml:1430
37.11082 +#: ../en/ch09-hook.xml:1400
37.11083  msgid "Sources of changesets"
37.11084  msgstr "修改集的来源"
37.11085  
37.11086  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.11087 -#: ../en/ch10-hook.xml:1432
37.11088 +#: ../en/ch09-hook.xml:1402
37.11089  msgid ""
37.11090  "Mercurial will tell a hook what means are, or were, used to transfer "
37.11091  "changesets between repositories.  This is provided by Mercurial in a Python "
37.11092 @@ -11875,40 +10961,40 @@
37.11093  msgstr ""
37.11094  
37.11095  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.11096 -#: ../en/ch10-hook.xml:1440
37.11097 +#: ../en/ch09-hook.xml:1410
37.11098  msgid ""
37.11099  "<literal>serve</literal>: Changesets are transferred to or from a remote "
37.11100  "repository over http or ssh."
37.11101  msgstr ""
37.11102  
37.11103  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.11104 -#: ../en/ch10-hook.xml:1445
37.11105 +#: ../en/ch09-hook.xml:1415
37.11106  msgid ""
37.11107  "<literal>pull</literal>: Changesets are being transferred via a pull from one "
37.11108  "repository into another."
37.11109  msgstr ""
37.11110  
37.11111  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.11112 -#: ../en/ch10-hook.xml:1450
37.11113 +#: ../en/ch09-hook.xml:1420
37.11114  msgid ""
37.11115  "<literal>push</literal>: Changesets are being transferred via a push from one "
37.11116  "repository into another."
37.11117  msgstr ""
37.11118  
37.11119  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.11120 -#: ../en/ch10-hook.xml:1455
37.11121 +#: ../en/ch09-hook.xml:1425
37.11122  msgid ""
37.11123  "<literal>bundle</literal>: Changesets are being transferred to or from a "
37.11124  "bundle."
37.11125  msgstr ""
37.11126  
37.11127  #. type: Content of: <book><chapter><sect1><sect2><sect3><title>
37.11128 -#: ../en/ch10-hook.xml:1462
37.11129 +#: ../en/ch09-hook.xml:1432
37.11130  msgid "Where changes are going&emdash;remote repository URLs"
37.11131  msgstr "修改集要到哪里&emdash;远程版本库的地址"
37.11132  
37.11133  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.11134 -#: ../en/ch10-hook.xml:1465
37.11135 +#: ../en/ch09-hook.xml:1435
37.11136  msgid ""
37.11137  "When possible, Mercurial will tell a hook the location of the <quote>far "
37.11138  "side</quote> of an activity that transfers changeset data between "
37.11139 @@ -11918,7 +11004,7 @@
37.11140  msgstr ""
37.11141  
37.11142  #. type: Content of: <book><chapter><sect1><sect2><sect3><para>
37.11143 -#: ../en/ch10-hook.xml:1473
37.11144 +#: ../en/ch09-hook.xml:1443
37.11145  msgid ""
37.11146  "This information is not always known.  If a hook is invoked in a repository "
37.11147  "that is being served via http or ssh, Mercurial cannot tell where the remote "
37.11148 @@ -11927,14 +11013,14 @@
37.11149  msgstr ""
37.11150  
37.11151  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.11152 -#: ../en/ch10-hook.xml:1480
37.11153 +#: ../en/ch09-hook.xml:1450
37.11154  msgid ""
37.11155  "<literal>remote:ssh:1.2.3.4</literal>&emdash;remote ssh client, at the IP "
37.11156  "address <literal>1.2.3.4</literal>."
37.11157  msgstr ""
37.11158  
37.11159  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.11160 -#: ../en/ch10-hook.xml:1485
37.11161 +#: ../en/ch09-hook.xml:1455
37.11162  msgid ""
37.11163  "<literal>remote:http:1.2.3.4</literal>&emdash;remote http client, at the IP "
37.11164  "address <literal>1.2.3.4</literal>.  If the client is using SSL, this will be "
37.11165 @@ -11942,24 +11028,24 @@
37.11166  msgstr ""
37.11167  
37.11168  #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
37.11169 -#: ../en/ch10-hook.xml:1492
37.11170 +#: ../en/ch09-hook.xml:1462
37.11171  msgid "Empty&emdash;no information could be discovered about the remote client."
37.11172  msgstr ""
37.11173  
37.11174  #. type: Content of: <book><chapter><sect1><title>
37.11175 -#: ../en/ch10-hook.xml:1501
37.11176 +#: ../en/ch09-hook.xml:1471
37.11177  msgid "Hook reference"
37.11178  msgstr "钩子参考"
37.11179  
37.11180  #. type: Content of: <book><chapter><sect1><sect2><title>
37.11181 -#: ../en/ch10-hook.xml:1504
37.11182 +#: ../en/ch09-hook.xml:1474
37.11183  msgid ""
37.11184  "<literal role=\"hook\">changegroup</literal>&emdash;after remote changesets "
37.11185  "added"
37.11186  msgstr "<literal role=\"hook\">changegroup</literal>&emdash;增加远程修改集之后"
37.11187  
37.11188  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11189 -#: ../en/ch10-hook.xml:1507
37.11190 +#: ../en/ch09-hook.xml:1477
37.11191  msgid ""
37.11192  "This hook is run after a group of pre-existing changesets has been added to "
37.11193  "the repository, for example via a <command role=\"hg-cmd\">hg pull</command> "
37.11194 @@ -11970,7 +11056,7 @@
37.11195  msgstr ""
37.11196  
37.11197  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11198 -#: ../en/ch10-hook.xml:1517
37.11199 +#: ../en/ch09-hook.xml:1487
37.11200  msgid ""
37.11201  "Some possible uses for this hook include kicking off an automated build or "
37.11202  "test of the added changesets, updating a bug database, or notifying "
37.11203 @@ -11978,42 +11064,41 @@
37.11204  msgstr ""
37.11205  
37.11206  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11207 -#: ../en/ch10-hook.xml:1523 ../en/ch10-hook.xml:1564 ../en/ch10-hook.xml:1607
37.11208 -#: ../en/ch10-hook.xml:1649 ../en/ch10-hook.xml:1704 ../en/ch10-hook.xml:1744
37.11209 -#: ../en/ch10-hook.xml:1780 ../en/ch10-hook.xml:1815 ../en/ch10-hook.xml:1877
37.11210 -#: ../en/ch10-hook.xml:1935 ../en/ch10-hook.xml:1969 ../en/ch10-hook.xml:1997
37.11211 +#: ../en/ch09-hook.xml:1493 ../en/ch09-hook.xml:1533 ../en/ch09-hook.xml:1576
37.11212 +#: ../en/ch09-hook.xml:1618 ../en/ch09-hook.xml:1673 ../en/ch09-hook.xml:1713
37.11213 +#: ../en/ch09-hook.xml:1749 ../en/ch09-hook.xml:1784 ../en/ch09-hook.xml:1846
37.11214 +#: ../en/ch09-hook.xml:1904 ../en/ch09-hook.xml:1938 ../en/ch09-hook.xml:1966
37.11215  msgid "Parameters to this hook:"
37.11216  msgstr ""
37.11217  
37.11218  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11219 -#: ../en/ch10-hook.xml:1526 ../en/ch10-hook.xml:1880
37.11220 +#: ../en/ch09-hook.xml:1496 ../en/ch09-hook.xml:1849
37.11221  msgid ""
37.11222  "<literal>node</literal>: A changeset ID.  The changeset ID of the first "
37.11223  "changeset in the group that was added.  All changesets between this and "
37.11224 -"\\index{tags!<literal>tip</literal>}<literal>tip</literal>, inclusive, were "
37.11225 -"added by a single <command role=\"hg-cmd\">hg pull</command>, <command role="
37.11226 -"\"hg-cmd\">hg push</command> or <command role=\"hg-cmd\">hg unbundle</"
37.11227 -"command>."
37.11228 +"<literal role=\"tag\">tip</literal>, inclusive, were added by a single "
37.11229 +"<command role=\"hg-cmd\">hg pull</command>, <command role=\"hg-cmd\">hg push</"
37.11230 +"command> or <command role=\"hg-cmd\">hg unbundle</command>."
37.11231  msgstr ""
37.11232  
37.11233  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11234 -#: ../en/ch10-hook.xml:1536 ../en/ch10-hook.xml:1614 ../en/ch10-hook.xml:1707
37.11235 -#: ../en/ch10-hook.xml:1890
37.11236 +#: ../en/ch09-hook.xml:1505 ../en/ch09-hook.xml:1583 ../en/ch09-hook.xml:1676
37.11237 +#: ../en/ch09-hook.xml:1859
37.11238  msgid ""
37.11239  "<literal>source</literal>: A string.  The source of these changes.  See "
37.11240  "section <xref linkend=\"sec.hook.sources\"/> for details."
37.11241  msgstr ""
37.11242  
37.11243  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11244 -#: ../en/ch10-hook.xml:1541 ../en/ch10-hook.xml:1619 ../en/ch10-hook.xml:1670
37.11245 -#: ../en/ch10-hook.xml:1712 ../en/ch10-hook.xml:1794 ../en/ch10-hook.xml:1895
37.11246 +#: ../en/ch09-hook.xml:1510 ../en/ch09-hook.xml:1588 ../en/ch09-hook.xml:1639
37.11247 +#: ../en/ch09-hook.xml:1681 ../en/ch09-hook.xml:1763 ../en/ch09-hook.xml:1864
37.11248  msgid ""
37.11249  "<literal>url</literal>: A URL.  The location of the remote repository, if "
37.11250  "known.  See section <xref linkend=\"sec.hook.url\"/> for more information."
37.11251  msgstr ""
37.11252  
37.11253  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11254 -#: ../en/ch10-hook.xml:1548
37.11255 +#: ../en/ch09-hook.xml:1517
37.11256  msgid ""
37.11257  "See also: <literal role=\"hook\">incoming</literal> (section <xref linkend="
37.11258  "\"sec.hook.incoming\"/>), <literal role=\"hook\">prechangegroup</literal> "
37.11259 @@ -12023,40 +11108,40 @@
37.11260  msgstr ""
37.11261  
37.11262  #. type: Content of: <book><chapter><sect1><sect2><title>
37.11263 -#: ../en/ch10-hook.xml:1558
37.11264 +#: ../en/ch09-hook.xml:1527
37.11265  msgid ""
37.11266  "<literal role=\"hook\">commit</literal>&emdash;after a new changeset is "
37.11267  "created"
37.11268  msgstr "<literal role=\"hook\">commit</literal>&emdash;创建新修改集之后"
37.11269  
37.11270  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11271 -#: ../en/ch10-hook.xml:1561
37.11272 +#: ../en/ch09-hook.xml:1530
37.11273  msgid "This hook is run after a new changeset has been created."
37.11274  msgstr ""
37.11275  
37.11276  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11277 -#: ../en/ch10-hook.xml:1567 ../en/ch10-hook.xml:1938
37.11278 +#: ../en/ch09-hook.xml:1536 ../en/ch09-hook.xml:1907
37.11279  msgid ""
37.11280  "<literal>node</literal>: A changeset ID.  The changeset ID of the newly "
37.11281  "committed changeset."
37.11282  msgstr ""
37.11283  
37.11284  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11285 -#: ../en/ch10-hook.xml:1571 ../en/ch10-hook.xml:1942
37.11286 +#: ../en/ch09-hook.xml:1540 ../en/ch09-hook.xml:1911
37.11287  msgid ""
37.11288  "<literal>parent1</literal>: A changeset ID.  The changeset ID of the first "
37.11289  "parent of the newly committed changeset."
37.11290  msgstr ""
37.11291  
37.11292  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11293 -#: ../en/ch10-hook.xml:1576 ../en/ch10-hook.xml:1947
37.11294 +#: ../en/ch09-hook.xml:1545 ../en/ch09-hook.xml:1916
37.11295  msgid ""
37.11296  "<literal>parent2</literal>: A changeset ID.  The changeset ID of the second "
37.11297  "parent of the newly committed changeset."
37.11298  msgstr ""
37.11299  
37.11300  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11301 -#: ../en/ch10-hook.xml:1582
37.11302 +#: ../en/ch09-hook.xml:1551
37.11303  msgid ""
37.11304  "See also: <literal role=\"hook\">precommit</literal> (section <xref linkend="
37.11305  "\"sec.hook.precommit\"/>), <literal role=\"hook\">pretxncommit</literal> "
37.11306 @@ -12064,14 +11149,14 @@
37.11307  msgstr ""
37.11308  
37.11309  #. type: Content of: <book><chapter><sect1><sect2><title>
37.11310 -#: ../en/ch10-hook.xml:1590
37.11311 +#: ../en/ch09-hook.xml:1559
37.11312  msgid ""
37.11313  "<literal role=\"hook\">incoming</literal>&emdash;after one remote changeset "
37.11314  "is added"
37.11315  msgstr "<literal role=\"hook\">incoming</literal>&emdash;增加远程修改集之后"
37.11316  
37.11317  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11318 -#: ../en/ch10-hook.xml:1593
37.11319 +#: ../en/ch09-hook.xml:1562
37.11320  msgid ""
37.11321  "This hook is run after a pre-existing changeset has been added to the "
37.11322  "repository, for example via a <command role=\"hg-cmd\">hg push</command>.  If "
37.11323 @@ -12080,7 +11165,7 @@
37.11324  msgstr ""
37.11325  
37.11326  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11327 -#: ../en/ch10-hook.xml:1600
37.11328 +#: ../en/ch09-hook.xml:1569
37.11329  msgid ""
37.11330  "You can use this hook for the same purposes as the <literal role=\"hook"
37.11331  "\">changegroup</literal> hook (section <xref linkend=\"sec.hook.changegroup\"/"
37.11332 @@ -12089,13 +11174,13 @@
37.11333  msgstr ""
37.11334  
37.11335  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11336 -#: ../en/ch10-hook.xml:1610
37.11337 +#: ../en/ch09-hook.xml:1579
37.11338  msgid ""
37.11339  "<literal>node</literal>: A changeset ID.  The ID of the newly added changeset."
37.11340  msgstr ""
37.11341  
37.11342  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11343 -#: ../en/ch10-hook.xml:1626
37.11344 +#: ../en/ch09-hook.xml:1595
37.11345  msgid ""
37.11346  "See also: <literal role=\"hook\">changegroup</literal> (section <xref linkend="
37.11347  "\"sec.hook.changegroup\"/>) <literal role=\"hook\">prechangegroup</literal> "
37.11348 @@ -12105,14 +11190,14 @@
37.11349  msgstr ""
37.11350  
37.11351  #. type: Content of: <book><chapter><sect1><sect2><title>
37.11352 -#: ../en/ch10-hook.xml:1636
37.11353 +#: ../en/ch09-hook.xml:1605
37.11354  msgid ""
37.11355  "<literal role=\"hook\">outgoing</literal>&emdash;after changesets are "
37.11356  "propagated"
37.11357  msgstr "<literal role=\"hook\">outgoing</literal>&emdash;传播修改集之后"
37.11358  
37.11359  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11360 -#: ../en/ch10-hook.xml:1639
37.11361 +#: ../en/ch09-hook.xml:1608
37.11362  msgid ""
37.11363  "This hook is run after a group of changesets has been propagated out of this "
37.11364  "repository, for example by a <command role=\"hg-cmd\">hg push</command> or "
37.11365 @@ -12120,21 +11205,21 @@
37.11366  msgstr ""
37.11367  
37.11368  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11369 -#: ../en/ch10-hook.xml:1645
37.11370 +#: ../en/ch09-hook.xml:1614
37.11371  msgid ""
37.11372  "One possible use for this hook is to notify administrators that changes have "
37.11373  "been pulled."
37.11374  msgstr ""
37.11375  
37.11376  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11377 -#: ../en/ch10-hook.xml:1652
37.11378 +#: ../en/ch09-hook.xml:1621
37.11379  msgid ""
37.11380  "<literal>node</literal>: A changeset ID.  The changeset ID of the first "
37.11381  "changeset of the group that was sent."
37.11382  msgstr ""
37.11383  
37.11384  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11385 -#: ../en/ch10-hook.xml:1657
37.11386 +#: ../en/ch09-hook.xml:1626
37.11387  msgid ""
37.11388  "<literal>source</literal>: A string.  The source of the of the operation (see "
37.11389  "section <xref linkend=\"sec.hook.sources\"/>).  If a remote client pulled "
37.11390 @@ -12146,14 +11231,14 @@
37.11391  msgstr ""
37.11392  
37.11393  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11394 -#: ../en/ch10-hook.xml:1677
37.11395 +#: ../en/ch09-hook.xml:1646
37.11396  msgid ""
37.11397  "See also: <literal role=\"hook\">preoutgoing</literal> (section <xref linkend="
37.11398  "\"sec.hook.preoutgoing\"/>)"
37.11399  msgstr ""
37.11400  
37.11401  #. type: Content of: <book><chapter><sect1><sect2><title>
37.11402 -#: ../en/ch10-hook.xml:1683
37.11403 +#: ../en/ch09-hook.xml:1652
37.11404  msgid ""
37.11405  "<literal role=\"hook\">prechangegroup</literal>&emdash;before starting to add "
37.11406  "remote changesets"
37.11407 @@ -12161,14 +11246,14 @@
37.11408  "<literal role=\"hook\">prechangegroup</literal>&emdash;增加远程修改集之前"
37.11409  
37.11410  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11411 -#: ../en/ch10-hook.xml:1687
37.11412 +#: ../en/ch09-hook.xml:1656
37.11413  msgid ""
37.11414  "This controlling hook is run before Mercurial begins to add a group of "
37.11415  "changesets from another repository."
37.11416  msgstr ""
37.11417  
37.11418  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11419 -#: ../en/ch10-hook.xml:1691
37.11420 +#: ../en/ch09-hook.xml:1660
37.11421  msgid ""
37.11422  "This hook does not have any information about the changesets to be added, "
37.11423  "because it is run before transmission of those changesets is allowed to "
37.11424 @@ -12176,7 +11261,7 @@
37.11425  msgstr ""
37.11426  
37.11427  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11428 -#: ../en/ch10-hook.xml:1697
37.11429 +#: ../en/ch09-hook.xml:1666
37.11430  msgid ""
37.11431  "One use for this hook is to prevent external changes from being added to a "
37.11432  "repository.  For example, you could use this to <quote>freeze</quote> a "
37.11433 @@ -12185,7 +11270,7 @@
37.11434  msgstr ""
37.11435  
37.11436  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11437 -#: ../en/ch10-hook.xml:1719
37.11438 +#: ../en/ch09-hook.xml:1688
37.11439  msgid ""
37.11440  "See also: <literal role=\"hook\">changegroup</literal> (section <xref linkend="
37.11441  "\"sec.hook.changegroup\"/>), <literal role=\"hook\">incoming</literal> "
37.11442 @@ -12195,14 +11280,14 @@
37.11443  msgstr ""
37.11444  
37.11445  #. type: Content of: <book><chapter><sect1><sect2><title>
37.11446 -#: ../en/ch10-hook.xml:1729
37.11447 +#: ../en/ch09-hook.xml:1698
37.11448  msgid ""
37.11449  "<literal role=\"hook\">precommit</literal>&emdash;before starting to commit a "
37.11450  "changeset"
37.11451  msgstr "<literal role=\"hook\">precommit</literal>&emdash;提交修改集之前"
37.11452  
37.11453  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11454 -#: ../en/ch10-hook.xml:1732
37.11455 +#: ../en/ch09-hook.xml:1701
37.11456  msgid ""
37.11457  "This hook is run before Mercurial begins to commit a new changeset. It is run "
37.11458  "before Mercurial has any of the metadata for the commit, such as the files to "
37.11459 @@ -12210,7 +11295,7 @@
37.11460  msgstr ""
37.11461  
37.11462  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11463 -#: ../en/ch10-hook.xml:1738
37.11464 +#: ../en/ch09-hook.xml:1707
37.11465  msgid ""
37.11466  "One use for this hook is to disable the ability to commit new changesets, "
37.11467  "while still allowing incoming changesets.  Another is to run a build or test, "
37.11468 @@ -12218,28 +11303,28 @@
37.11469  msgstr ""
37.11470  
37.11471  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11472 -#: ../en/ch10-hook.xml:1747
37.11473 +#: ../en/ch09-hook.xml:1716
37.11474  msgid ""
37.11475  "<literal>parent1</literal>: A changeset ID.  The changeset ID of the first "
37.11476  "parent of the working directory."
37.11477  msgstr ""
37.11478  
37.11479  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11480 -#: ../en/ch10-hook.xml:1752
37.11481 +#: ../en/ch09-hook.xml:1721
37.11482  msgid ""
37.11483  "<literal>parent2</literal>: A changeset ID.  The changeset ID of the second "
37.11484  "parent of the working directory."
37.11485  msgstr ""
37.11486  
37.11487  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11488 -#: ../en/ch10-hook.xml:1757
37.11489 +#: ../en/ch09-hook.xml:1726
37.11490  msgid ""
37.11491  "If the commit proceeds, the parents of the working directory will become the "
37.11492  "parents of the new changeset."
37.11493  msgstr ""
37.11494  
37.11495  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11496 -#: ../en/ch10-hook.xml:1761
37.11497 +#: ../en/ch09-hook.xml:1730
37.11498  msgid ""
37.11499  "See also: <literal role=\"hook\">commit</literal> (section <xref linkend="
37.11500  "\"sec.hook.commit\"/>), <literal role=\"hook\">pretxncommit</literal> "
37.11501 @@ -12247,28 +11332,28 @@
37.11502  msgstr ""
37.11503  
37.11504  #. type: Content of: <book><chapter><sect1><sect2><title>
37.11505 -#: ../en/ch10-hook.xml:1769
37.11506 +#: ../en/ch09-hook.xml:1738
37.11507  msgid ""
37.11508  "<literal role=\"hook\">preoutgoing</literal>&emdash;before starting to "
37.11509  "propagate changesets"
37.11510  msgstr "<literal role=\"hook\">preoutgoing</literal>&emdash;传播修改集之前"
37.11511  
37.11512  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11513 -#: ../en/ch10-hook.xml:1772
37.11514 +#: ../en/ch09-hook.xml:1741
37.11515  msgid ""
37.11516  "This hook is invoked before Mercurial knows the identities of the changesets "
37.11517  "to be transmitted."
37.11518  msgstr ""
37.11519  
37.11520  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11521 -#: ../en/ch10-hook.xml:1776
37.11522 +#: ../en/ch09-hook.xml:1745
37.11523  msgid ""
37.11524  "One use for this hook is to prevent changes from being transmitted to another "
37.11525  "repository."
37.11526  msgstr ""
37.11527  
37.11528  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11529 -#: ../en/ch10-hook.xml:1783
37.11530 +#: ../en/ch09-hook.xml:1752
37.11531  msgid ""
37.11532  "<literal>source</literal>: A string.  The source of the operation that is "
37.11533  "attempting to obtain changes from this repository (see section <xref linkend="
37.11534 @@ -12279,27 +11364,27 @@
37.11535  msgstr ""
37.11536  
37.11537  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11538 -#: ../en/ch10-hook.xml:1801
37.11539 +#: ../en/ch09-hook.xml:1770
37.11540  msgid ""
37.11541  "See also: <literal role=\"hook\">outgoing</literal> (section <xref linkend="
37.11542  "\"sec.hook.outgoing\"/>)"
37.11543  msgstr ""
37.11544  
37.11545  #. type: Content of: <book><chapter><sect1><sect2><title>
37.11546 -#: ../en/ch10-hook.xml:1807
37.11547 +#: ../en/ch09-hook.xml:1776
37.11548  msgid ""
37.11549  "<literal role=\"hook\">pretag</literal>&emdash;before tagging a changeset"
37.11550  msgstr "<literal role=\"hook\">pretag</literal>&emdash;创建标签之前"
37.11551  
37.11552  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11553 -#: ../en/ch10-hook.xml:1810
37.11554 +#: ../en/ch09-hook.xml:1779
37.11555  msgid ""
37.11556  "This controlling hook is run before a tag is created.  If the hook succeeds, "
37.11557  "creation of the tag proceeds.  If the hook fails, the tag is not created."
37.11558  msgstr ""
37.11559  
37.11560  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11561 -#: ../en/ch10-hook.xml:1818
37.11562 +#: ../en/ch09-hook.xml:1787
37.11563  msgid ""
37.11564  "<literal>local</literal>: A boolean.  Whether the tag is local to this "
37.11565  "repository instance (i.e. stored in <filename role=\"special\">.hg/localtags</"
37.11566 @@ -12308,19 +11393,19 @@
37.11567  msgstr ""
37.11568  
37.11569  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11570 -#: ../en/ch10-hook.xml:1825
37.11571 +#: ../en/ch09-hook.xml:1794
37.11572  msgid ""
37.11573  "<literal>node</literal>: A changeset ID.  The ID of the changeset to be "
37.11574  "tagged."
37.11575  msgstr ""
37.11576  
37.11577  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11578 -#: ../en/ch10-hook.xml:1829
37.11579 +#: ../en/ch09-hook.xml:1798
37.11580  msgid "<literal>tag</literal>: A string.  The name of the tag to be created."
37.11581  msgstr ""
37.11582  
37.11583  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11584 -#: ../en/ch10-hook.xml:1834
37.11585 +#: ../en/ch09-hook.xml:1803
37.11586  msgid ""
37.11587  "If the tag to be created is revision-controlled, the <literal role=\"hook"
37.11588  "\">precommit</literal> and <literal role=\"hook\">pretxncommit</literal> "
37.11589 @@ -12329,14 +11414,14 @@
37.11590  msgstr ""
37.11591  
37.11592  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11593 -#: ../en/ch10-hook.xml:1841
37.11594 +#: ../en/ch09-hook.xml:1810
37.11595  msgid ""
37.11596  "See also: <literal role=\"hook\">tag</literal> (section <xref linkend=\"sec."
37.11597  "hook.tag\"/>)"
37.11598  msgstr ""
37.11599  
37.11600  #. type: Content of: <book><chapter><sect1><sect2><title>
37.11601 -#: ../en/ch10-hook.xml:1846
37.11602 +#: ../en/ch09-hook.xml:1815
37.11603  msgid ""
37.11604  "<literal role=\"hook\">pretxnchangegroup</literal>&emdash;before completing "
37.11605  "addition of remote changesets"
37.11606 @@ -12345,7 +11430,7 @@
37.11607  "前"
37.11608  
37.11609  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11610 -#: ../en/ch10-hook.xml:1850
37.11611 +#: ../en/ch09-hook.xml:1819
37.11612  msgid ""
37.11613  "This controlling hook is run before a transaction&emdash;that manages the "
37.11614  "addition of a group of new changesets from outside the repository&emdash;"
37.11615 @@ -12355,7 +11440,7 @@
37.11616  msgstr ""
37.11617  
37.11618  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11619 -#: ../en/ch10-hook.xml:1859
37.11620 +#: ../en/ch09-hook.xml:1828
37.11621  msgid ""
37.11622  "This hook can access the metadata associated with the almost-added "
37.11623  "changesets, but it should not do anything permanent with this data. It must "
37.11624 @@ -12363,7 +11448,7 @@
37.11625  msgstr ""
37.11626  
37.11627  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11628 -#: ../en/ch10-hook.xml:1865
37.11629 +#: ../en/ch09-hook.xml:1834
37.11630  msgid ""
37.11631  "While this hook is running, if other Mercurial processes access this "
37.11632  "repository, they will be able to see the almost-added changesets as if they "
37.11633 @@ -12372,7 +11457,7 @@
37.11634  msgstr ""
37.11635  
37.11636  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11637 -#: ../en/ch10-hook.xml:1872
37.11638 +#: ../en/ch09-hook.xml:1841
37.11639  msgid ""
37.11640  "This hook can be used to automatically vet a group of changesets.  If the "
37.11641  "hook fails, all of the changesets are <quote>rejected</quote> when the "
37.11642 @@ -12380,7 +11465,7 @@
37.11643  msgstr ""
37.11644  
37.11645  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11646 -#: ../en/ch10-hook.xml:1902
37.11647 +#: ../en/ch09-hook.xml:1871
37.11648  msgid ""
37.11649  "See also: <literal role=\"hook\">changegroup</literal> (section <xref linkend="
37.11650  "\"sec.hook.changegroup\"/>), <literal role=\"hook\">incoming</literal> "
37.11651 @@ -12390,14 +11475,14 @@
37.11652  msgstr ""
37.11653  
37.11654  #. type: Content of: <book><chapter><sect1><sect2><title>
37.11655 -#: ../en/ch10-hook.xml:1912
37.11656 +#: ../en/ch09-hook.xml:1881
37.11657  msgid ""
37.11658  "<literal role=\"hook\">pretxncommit</literal>&emdash;before completing commit "
37.11659  "of new changeset"
37.11660  msgstr "<literal role=\"hook\">pretxncommit</literal>&emdash;完成提交之前"
37.11661  
37.11662  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11663 -#: ../en/ch10-hook.xml:1915
37.11664 +#: ../en/ch09-hook.xml:1884
37.11665  msgid ""
37.11666  "This controlling hook is run before a transaction&emdash;that manages a new "
37.11667  "commit&emdash;completes.  If the hook succeeds, the transaction completes and "
37.11668 @@ -12406,7 +11491,7 @@
37.11669  msgstr ""
37.11670  
37.11671  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11672 -#: ../en/ch10-hook.xml:1923
37.11673 +#: ../en/ch09-hook.xml:1892
37.11674  msgid ""
37.11675  "This hook can access the metadata associated with the almost-new changeset, "
37.11676  "but it should not do anything permanent with this data.  It must also not "
37.11677 @@ -12414,7 +11499,7 @@
37.11678  msgstr ""
37.11679  
37.11680  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11681 -#: ../en/ch10-hook.xml:1929
37.11682 +#: ../en/ch09-hook.xml:1898
37.11683  msgid ""
37.11684  "While this hook is running, if other Mercurial processes access this "
37.11685  "repository, they will be able to see the almost-new changeset as if it is "
37.11686 @@ -12423,14 +11508,14 @@
37.11687  msgstr ""
37.11688  
37.11689  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11690 -#: ../en/ch10-hook.xml:1953
37.11691 +#: ../en/ch09-hook.xml:1922
37.11692  msgid ""
37.11693  "See also: <literal role=\"hook\">precommit</literal> (section <xref linkend="
37.11694  "\"sec.hook.precommit\"/>)"
37.11695  msgstr ""
37.11696  
37.11697  #. type: Content of: <book><chapter><sect1><sect2><title>
37.11698 -#: ../en/ch10-hook.xml:1959
37.11699 +#: ../en/ch09-hook.xml:1928
37.11700  msgid ""
37.11701  "<literal role=\"hook\">preupdate</literal>&emdash;before updating or merging "
37.11702  "working directory"
37.11703 @@ -12438,7 +11523,7 @@
37.11704  "<literal role=\"hook\">preupdate</literal>&emdash;更新或合并工作目录之前"
37.11705  
37.11706  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11707 -#: ../en/ch10-hook.xml:1962
37.11708 +#: ../en/ch09-hook.xml:1931
37.11709  msgid ""
37.11710  "This controlling hook is run before an update or merge of the working "
37.11711  "directory begins.  It is run only if Mercurial's normal pre-update checks "
37.11712 @@ -12447,7 +11532,7 @@
37.11713  msgstr ""
37.11714  
37.11715  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11716 -#: ../en/ch10-hook.xml:1972
37.11717 +#: ../en/ch09-hook.xml:1941
37.11718  msgid ""
37.11719  "<literal>parent1</literal>: A changeset ID.  The ID of the parent that the "
37.11720  "working directory is to be updated to.  If the working directory is being "
37.11721 @@ -12455,7 +11540,7 @@
37.11722  msgstr ""
37.11723  
37.11724  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11725 -#: ../en/ch10-hook.xml:1978
37.11726 +#: ../en/ch09-hook.xml:1947
37.11727  msgid ""
37.11728  "<literal>parent2</literal>: A changeset ID.  Only set if the working "
37.11729  "directory is being merged.  The ID of the revision that the working directory "
37.11730 @@ -12463,24 +11548,24 @@
37.11731  msgstr ""
37.11732  
37.11733  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11734 -#: ../en/ch10-hook.xml:1985
37.11735 +#: ../en/ch09-hook.xml:1954
37.11736  msgid ""
37.11737  "See also: <literal role=\"hook\">update</literal> (section <xref linkend="
37.11738  "\"sec.hook.update\"/>)"
37.11739  msgstr ""
37.11740  
37.11741  #. type: Content of: <book><chapter><sect1><sect2><title>
37.11742 -#: ../en/ch10-hook.xml:1991
37.11743 +#: ../en/ch09-hook.xml:1960
37.11744  msgid "<literal role=\"hook\">tag</literal>&emdash;after tagging a changeset"
37.11745  msgstr "<literal role=\"hook\">tag</literal>&emdash;创建标签之后"
37.11746  
37.11747  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11748 -#: ../en/ch10-hook.xml:1994
37.11749 +#: ../en/ch09-hook.xml:1963
37.11750  msgid "This hook is run after a tag has been created."
37.11751  msgstr ""
37.11752  
37.11753  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11754 -#: ../en/ch10-hook.xml:2000
37.11755 +#: ../en/ch09-hook.xml:1969
37.11756  msgid ""
37.11757  "<literal>local</literal>: A boolean.  Whether the new tag is local to this "
37.11758  "repository instance (i.e.  stored in <filename role=\"special\">.hg/"
37.11759 @@ -12489,19 +11574,19 @@
37.11760  msgstr ""
37.11761  
37.11762  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11763 -#: ../en/ch10-hook.xml:2008
37.11764 +#: ../en/ch09-hook.xml:1977
37.11765  msgid ""
37.11766  "<literal>node</literal>: A changeset ID.  The ID of the changeset that was "
37.11767  "tagged."
37.11768  msgstr ""
37.11769  
37.11770  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11771 -#: ../en/ch10-hook.xml:2012
37.11772 +#: ../en/ch09-hook.xml:1981
37.11773  msgid "<literal>tag</literal>: A string.  The name of the tag that was created."
37.11774  msgstr ""
37.11775  
37.11776  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11777 -#: ../en/ch10-hook.xml:2017
37.11778 +#: ../en/ch09-hook.xml:1986
37.11779  msgid ""
37.11780  "If the created tag is revision-controlled, the <literal role=\"hook\">commit</"
37.11781  "literal> hook (section <xref linkend=\"sec.hook.commit\"/>) is run before "
37.11782 @@ -12509,21 +11594,21 @@
37.11783  msgstr ""
37.11784  
37.11785  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11786 -#: ../en/ch10-hook.xml:2022
37.11787 +#: ../en/ch09-hook.xml:1991
37.11788  msgid ""
37.11789  "See also: <literal role=\"hook\">pretag</literal> (section <xref linkend="
37.11790  "\"sec.hook.pretag\"/>)"
37.11791  msgstr ""
37.11792  
37.11793  #. type: Content of: <book><chapter><sect1><sect2><title>
37.11794 -#: ../en/ch10-hook.xml:2028
37.11795 +#: ../en/ch09-hook.xml:1997
37.11796  msgid ""
37.11797  "<literal role=\"hook\">update</literal>&emdash;after updating or merging "
37.11798  "working directory"
37.11799  msgstr "<literal role=\"hook\">update</literal>&emdash;更新或合并工作目录之后"
37.11800  
37.11801  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11802 -#: ../en/ch10-hook.xml:2031
37.11803 +#: ../en/ch09-hook.xml:2000
37.11804  msgid ""
37.11805  "This hook is run after an update or merge of the working directory "
37.11806  "completes.  Since a merge can fail (if the external <command>hgmerge</"
37.11807 @@ -12532,14 +11617,14 @@
37.11808  msgstr ""
37.11809  
37.11810  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11811 -#: ../en/ch10-hook.xml:2039
37.11812 +#: ../en/ch09-hook.xml:2008
37.11813  msgid ""
37.11814  "<literal>error</literal>: A boolean.  Indicates whether the update or merge "
37.11815  "completed successfully."
37.11816  msgstr ""
37.11817  
37.11818  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11819 -#: ../en/ch10-hook.xml:2044
37.11820 +#: ../en/ch09-hook.xml:2013
37.11821  msgid ""
37.11822  "<literal>parent1</literal>: A changeset ID.  The ID of the parent that the "
37.11823  "working directory was updated to.  If the working directory was merged, it "
37.11824 @@ -12547,7 +11632,7 @@
37.11825  msgstr ""
37.11826  
37.11827  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.11828 -#: ../en/ch10-hook.xml:2050
37.11829 +#: ../en/ch09-hook.xml:2019
37.11830  msgid ""
37.11831  "<literal>parent2</literal>: A changeset ID.  Only set if the working "
37.11832  "directory was merged.  The ID of the revision that the working directory was "
37.11833 @@ -12555,19 +11640,19 @@
37.11834  msgstr ""
37.11835  
37.11836  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11837 -#: ../en/ch10-hook.xml:2056
37.11838 +#: ../en/ch09-hook.xml:2025
37.11839  msgid ""
37.11840  "See also: <literal role=\"hook\">preupdate</literal> (section <xref linkend="
37.11841  "\"sec.hook.preupdate\"/>)"
37.11842  msgstr ""
37.11843  
37.11844  #. type: Content of: <book><chapter><title>
37.11845 -#: ../en/ch11-template.xml:5
37.11846 +#: ../en/ch10-template.xml:5
37.11847  msgid "Customising the output of Mercurial"
37.11848  msgstr "定制 Mercurial 的输出"
37.11849  
37.11850  #. type: Content of: <book><chapter><para>
37.11851 -#: ../en/ch11-template.xml:7
37.11852 +#: ../en/ch10-template.xml:7
37.11853  msgid ""
37.11854  "Mercurial provides a powerful mechanism to let you control how it displays "
37.11855  "information.  The mechanism is based on templates.  You can use templates to "
37.11856 @@ -12576,12 +11661,12 @@
37.11857  msgstr ""
37.11858  
37.11859  #. type: Content of: <book><chapter><sect1><title>
37.11860 -#: ../en/ch11-template.xml:14
37.11861 +#: ../en/ch10-template.xml:14
37.11862  msgid "Using precanned output styles"
37.11863  msgstr "使用预定义的输出样式"
37.11864  
37.11865  #. type: Content of: <book><chapter><sect1><para>
37.11866 -#: ../en/ch11-template.xml:16
37.11867 +#: ../en/ch10-template.xml:16
37.11868  msgid ""
37.11869  "Packaged with Mercurial are some output styles that you can use immediately.  "
37.11870  "A style is simply a precanned template that someone wrote and installed "
37.11871 @@ -12589,14 +11674,14 @@
37.11872  msgstr ""
37.11873  
37.11874  #. type: Content of: <book><chapter><sect1><para>
37.11875 -#: ../en/ch11-template.xml:21
37.11876 +#: ../en/ch10-template.xml:21
37.11877  msgid ""
37.11878  "Before we take a look at Mercurial's bundled styles, let's review its normal "
37.11879  "output."
37.11880  msgstr ""
37.11881  
37.11882  #. type: Content of: <book><chapter><sect1><para>
37.11883 -#: ../en/ch11-template.xml:26
37.11884 +#: ../en/ch10-template.xml:26
37.11885  msgid ""
37.11886  "This is somewhat informative, but it takes up a lot of space&emdash;five "
37.11887  "lines of output per changeset.  The <literal>compact</literal> style reduces "
37.11888 @@ -12604,7 +11689,7 @@
37.11889  msgstr ""
37.11890  
37.11891  #. type: Content of: <book><chapter><sect1><para>
37.11892 -#: ../en/ch11-template.xml:33
37.11893 +#: ../en/ch10-template.xml:33
37.11894  msgid ""
37.11895  "The <literal>changelog</literal> style hints at the expressive power of "
37.11896  "Mercurial's templating engine.  This style attempts to follow the GNU "
37.11897 @@ -12612,27 +11697,27 @@
37.11898  msgstr ""
37.11899  
37.11900  #. type: Content of: <book><chapter><sect1><para>
37.11901 -#: ../en/ch11-template.xml:40
37.11902 +#: ../en/ch10-template.xml:40
37.11903  msgid ""
37.11904  "You will not be shocked to learn that Mercurial's default output style is "
37.11905  "named <literal>default</literal>."
37.11906  msgstr ""
37.11907  
37.11908  #. type: Content of: <book><chapter><sect1><sect2><title>
37.11909 -#: ../en/ch11-template.xml:44
37.11910 +#: ../en/ch10-template.xml:44
37.11911  msgid "Setting a default style"
37.11912  msgstr "设置默认样式"
37.11913  
37.11914  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11915 -#: ../en/ch11-template.xml:46
37.11916 +#: ../en/ch10-template.xml:46
37.11917  msgid ""
37.11918  "You can modify the output style that Mercurial will use for every command by "
37.11919 -"editing your <filename role=\"special\"> /.hgrc</filename>\\ file, naming the "
37.11920 +"editing your <filename role=\"special\">~/.hgrc</filename> file, naming the "
37.11921  "style you would prefer to use."
37.11922  msgstr ""
37.11923  
37.11924  #. type: Content of: <book><chapter><sect1><sect2><para>
37.11925 -#: ../en/ch11-template.xml:53
37.11926 +#: ../en/ch10-template.xml:54
37.11927  msgid ""
37.11928  "If you write a style of your own, you can use it by either providing the path "
37.11929  "to your style file, or copying your style file into a location where "
37.11930 @@ -12641,12 +11726,12 @@
37.11931  msgstr ""
37.11932  
37.11933  #. type: Content of: <book><chapter><sect1><title>
37.11934 -#: ../en/ch11-template.xml:62
37.11935 +#: ../en/ch10-template.xml:63
37.11936  msgid "Commands that support styles and templates"
37.11937  msgstr "支持样式和模版的命令"
37.11938  
37.11939  #. type: Content of: <book><chapter><sect1><para>
37.11940 -#: ../en/ch11-template.xml:64
37.11941 +#: ../en/ch10-template.xml:65
37.11942  msgid ""
37.11943  "All of Mercurial's <quote><literal>log</literal>-like</quote> commands let "
37.11944  "you use styles and templates: <command role=\"hg-cmd\">hg incoming</command>, "
37.11945 @@ -12655,7 +11740,7 @@
37.11946  msgstr ""
37.11947  
37.11948  #. type: Content of: <book><chapter><sect1><para>
37.11949 -#: ../en/ch11-template.xml:71
37.11950 +#: ../en/ch10-template.xml:72
37.11951  msgid ""
37.11952  "As I write this manual, these are so far the only commands that support "
37.11953  "styles and templates.  Since these are the most important commands that need "
37.11954 @@ -12664,12 +11749,12 @@
37.11955  msgstr ""
37.11956  
37.11957  #. type: Content of: <book><chapter><sect1><title>
37.11958 -#: ../en/ch11-template.xml:79
37.11959 +#: ../en/ch10-template.xml:80
37.11960  msgid "The basics of templating"
37.11961  msgstr "模版基础"
37.11962  
37.11963  #. type: Content of: <book><chapter><sect1><para>
37.11964 -#: ../en/ch11-template.xml:81
37.11965 +#: ../en/ch10-template.xml:82
37.11966  msgid ""
37.11967  "At its simplest, a Mercurial template is a piece of text.  Some of the text "
37.11968  "never changes, while other parts are <emphasis>expanded</emphasis>, or "
37.11969 @@ -12677,20 +11762,20 @@
37.11970  msgstr ""
37.11971  
37.11972  #. type: Content of: <book><chapter><sect1><para>
37.11973 -#: ../en/ch11-template.xml:86
37.11974 +#: ../en/ch10-template.xml:87
37.11975  msgid ""
37.11976  "Before we continue, let's look again at a simple example of Mercurial's "
37.11977  "normal output."
37.11978  msgstr ""
37.11979  
37.11980  #. type: Content of: <book><chapter><sect1><para>
37.11981 -#: ../en/ch11-template.xml:91
37.11982 +#: ../en/ch10-template.xml:92
37.11983  msgid ""
37.11984  "Now, let's run the same command, but using a template to change its output."
37.11985  msgstr ""
37.11986  
37.11987  #. type: Content of: <book><chapter><sect1><para>
37.11988 -#: ../en/ch11-template.xml:96
37.11989 +#: ../en/ch10-template.xml:97
37.11990  msgid ""
37.11991  "The example above illustrates the simplest possible template; it's just a "
37.11992  "piece of static text, printed once for each changeset.  The <option role=\"hg-"
37.11993 @@ -12700,7 +11785,7 @@
37.11994  msgstr ""
37.11995  
37.11996  #. type: Content of: <book><chapter><sect1><para>
37.11997 -#: ../en/ch11-template.xml:104
37.11998 +#: ../en/ch10-template.xml:105
37.11999  msgid ""
37.12000  "Notice that the template string above ends with the text <quote><literal>\\n</"
37.12001  "literal></quote>.  This is an <emphasis>escape sequence</emphasis>, telling "
37.12002 @@ -12710,14 +11795,14 @@
37.12003  msgstr ""
37.12004  
37.12005  #. type: Content of: <book><chapter><sect1><para>
37.12006 -#: ../en/ch11-template.xml:112
37.12007 +#: ../en/ch10-template.xml:113
37.12008  msgid ""
37.12009  "A template that prints a fixed string of text all the time isn't very useful; "
37.12010  "let's try something a bit more complex."
37.12011  msgstr ""
37.12012  
37.12013  #. type: Content of: <book><chapter><sect1><para>
37.12014 -#: ../en/ch11-template.xml:118
37.12015 +#: ../en/ch10-template.xml:119
37.12016  msgid ""
37.12017  "As you can see, the string <quote><literal>{desc}</literal></quote> in the "
37.12018  "template has been replaced in the output with the description of each "
37.12019 @@ -12729,25 +11814,25 @@
37.12020  msgstr ""
37.12021  
37.12022  #. type: Content of: <book><chapter><sect1><title>
37.12023 -#: ../en/ch11-template.xml:131
37.12024 +#: ../en/ch10-template.xml:132
37.12025  msgid "Common template keywords"
37.12026  msgstr "模版关键字"
37.12027  
37.12028  #. type: Content of: <book><chapter><sect1><para>
37.12029 -#: ../en/ch11-template.xml:133
37.12030 +#: ../en/ch10-template.xml:134
37.12031  msgid ""
37.12032  "You can start writing simple templates immediately using the keywords below."
37.12033  msgstr ""
37.12034  
37.12035  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12036 -#: ../en/ch11-template.xml:137
37.12037 +#: ../en/ch10-template.xml:138
37.12038  msgid ""
37.12039  "<literal role=\"template-keyword\">author</literal>: String.  The unmodified "
37.12040  "author of the changeset."
37.12041  msgstr ""
37.12042  
37.12043  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12044 -#: ../en/ch11-template.xml:141
37.12045 +#: ../en/ch10-template.xml:142
37.12046  msgid ""
37.12047  "<literal role=\"template-keyword\">branches</literal>: String.  The name of "
37.12048  "the branch on which the changeset was committed.  Will be empty if the branch "
37.12049 @@ -12755,7 +11840,7 @@
37.12050  msgstr ""
37.12051  
37.12052  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12053 -#: ../en/ch11-template.xml:147
37.12054 +#: ../en/ch10-template.xml:148
37.12055  msgid ""
37.12056  "<literal role=\"template-keyword\">date</literal>: Date information.  The "
37.12057  "date when the changeset was committed.  This is <emphasis>not</emphasis> "
37.12058 @@ -12767,70 +11852,70 @@
37.12059  msgstr ""
37.12060  
37.12061  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12062 -#: ../en/ch11-template.xml:158
37.12063 +#: ../en/ch10-template.xml:159
37.12064  msgid ""
37.12065  "<literal role=\"template-keyword\">desc</literal>: String.  The text of the "
37.12066  "changeset description."
37.12067  msgstr ""
37.12068  
37.12069  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12070 -#: ../en/ch11-template.xml:161
37.12071 +#: ../en/ch10-template.xml:162
37.12072  msgid ""
37.12073  "<literal role=\"template-keyword\">files</literal>: List of strings.  All "
37.12074  "files modified, added, or removed by this changeset."
37.12075  msgstr ""
37.12076  
37.12077  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12078 -#: ../en/ch11-template.xml:166
37.12079 +#: ../en/ch10-template.xml:167
37.12080  msgid ""
37.12081  "<literal role=\"template-keyword\">file_adds</literal>: List of strings.  "
37.12082  "Files added by this changeset."
37.12083  msgstr ""
37.12084  
37.12085  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12086 -#: ../en/ch11-template.xml:170
37.12087 +#: ../en/ch10-template.xml:171
37.12088  msgid ""
37.12089  "<literal role=\"template-keyword\">file_dels</literal>: List of strings.  "
37.12090  "Files removed by this changeset."
37.12091  msgstr ""
37.12092  
37.12093  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12094 -#: ../en/ch11-template.xml:174
37.12095 +#: ../en/ch10-template.xml:175
37.12096  msgid ""
37.12097  "<literal role=\"template-keyword\">node</literal>: String.  The changeset "
37.12098  "identification hash, as a 40-character hexadecimal string."
37.12099  msgstr ""
37.12100  
37.12101  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12102 -#: ../en/ch11-template.xml:178
37.12103 +#: ../en/ch10-template.xml:179
37.12104  msgid ""
37.12105  "<literal role=\"template-keyword\">parents</literal>: List of strings.  The "
37.12106  "parents of the changeset."
37.12107  msgstr ""
37.12108  
37.12109  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12110 -#: ../en/ch11-template.xml:182
37.12111 +#: ../en/ch10-template.xml:183
37.12112  msgid ""
37.12113  "<literal role=\"template-keyword\">rev</literal>: Integer.  The repository-"
37.12114  "local changeset revision number."
37.12115  msgstr ""
37.12116  
37.12117  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12118 -#: ../en/ch11-template.xml:186
37.12119 +#: ../en/ch10-template.xml:187
37.12120  msgid ""
37.12121  "<literal role=\"template-keyword\">tags</literal>: List of strings.  Any tags "
37.12122  "associated with the changeset."
37.12123  msgstr ""
37.12124  
37.12125  #. type: Content of: <book><chapter><sect1><para>
37.12126 -#: ../en/ch11-template.xml:191
37.12127 +#: ../en/ch10-template.xml:192
37.12128  msgid ""
37.12129  "A few simple experiments will show us what to expect when we use these "
37.12130  "keywords; you can see the results below."
37.12131  msgstr ""
37.12132  
37.12133  #. type: Content of: <book><chapter><sect1><para>
37.12134 -#: ../en/ch11-template.xml:196
37.12135 +#: ../en/ch10-template.xml:197
37.12136  msgid ""
37.12137  "As we noted above, the date keyword does not produce human-readable output, "
37.12138  "so we must treat it specially.  This involves using a <emphasis>filter</"
37.12139 @@ -12839,12 +11924,12 @@
37.12140  msgstr ""
37.12141  
37.12142  #. type: Content of: <book><chapter><sect1><title>
37.12143 -#: ../en/ch11-template.xml:206
37.12144 +#: ../en/ch10-template.xml:207
37.12145  msgid "Escape sequences"
37.12146  msgstr "转义序列"
37.12147  
37.12148  #. type: Content of: <book><chapter><sect1><para>
37.12149 -#: ../en/ch11-template.xml:208
37.12150 +#: ../en/ch10-template.xml:209
37.12151  msgid ""
37.12152  "Mercurial's templating engine recognises the most commonly used escape "
37.12153  "sequences in strings.  When it sees a backslash (<quote><literal>\\</"
37.12154 @@ -12853,48 +11938,48 @@
37.12155  msgstr ""
37.12156  
37.12157  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12158 -#: ../en/ch11-template.xml:215
37.12159 -msgid ""
37.12160 -"<literal>\\textbackslash\\textbackslash</literal>: Backslash, <quote><literal>"
37.12161 -"\\</literal></quote>, ASCII 134."
37.12162 +#: ../en/ch10-template.xml:216
37.12163 +msgid ""
37.12164 +"<literal>\\</literal>: Backslash, <quote><literal>\\</literal></quote>, ASCII "
37.12165 +"134."
37.12166  msgstr ""
37.12167  
37.12168  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12169 -#: ../en/ch11-template.xml:219
37.12170 -msgid "<literal>\\textbackslash n</literal>: Newline, ASCII 12."
37.12171 +#: ../en/ch10-template.xml:220
37.12172 +msgid "<literal>\\n</literal>: Newline, ASCII 12."
37.12173  msgstr ""
37.12174  
37.12175  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12176 -#: ../en/ch11-template.xml:222
37.12177 -msgid "<literal>\\textbackslash r</literal>: Carriage return, ASCII 15."
37.12178 +#: ../en/ch10-template.xml:223
37.12179 +msgid "<literal>\\r</literal>: Carriage return, ASCII 15."
37.12180  msgstr ""
37.12181  
37.12182  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12183 -#: ../en/ch11-template.xml:225
37.12184 -msgid "<literal>\\textbackslash t</literal>: Tab, ASCII 11."
37.12185 +#: ../en/ch10-template.xml:226
37.12186 +msgid "<literal>\\t</literal>: Tab, ASCII 11."
37.12187  msgstr ""
37.12188  
37.12189  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12190 -#: ../en/ch11-template.xml:228
37.12191 -msgid "<literal>\\textbackslash v</literal>: Vertical tab, ASCII 13."
37.12192 +#: ../en/ch10-template.xml:229
37.12193 +msgid "<literal>\\v</literal>: Vertical tab, ASCII 13."
37.12194  msgstr ""
37.12195  
37.12196  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12197 -#: ../en/ch11-template.xml:231
37.12198 -msgid ""
37.12199 -"<literal>\\textbackslash {</literal>: Open curly brace, <quote><literal>{</"
37.12200 -"literal></quote>, ASCII 173."
37.12201 +#: ../en/ch10-template.xml:232
37.12202 +msgid ""
37.12203 +"<literal>{</literal>: Open curly brace, <quote><literal>{</literal></quote>, "
37.12204 +"ASCII 173."
37.12205  msgstr ""
37.12206  
37.12207  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12208 -#: ../en/ch11-template.xml:235
37.12209 -msgid ""
37.12210 -"<literal>\\textbackslash }</literal>: Close curly brace, <quote><literal>}</"
37.12211 -"literal></quote>, ASCII 175."
37.12212 -msgstr ""
37.12213 -
37.12214 -#. type: Content of: <book><chapter><sect1><para>
37.12215 -#: ../en/ch11-template.xml:240
37.12216 +#: ../en/ch10-template.xml:236
37.12217 +msgid ""
37.12218 +"<literal>}</literal>: Close curly brace, <quote><literal>}</literal></quote>, "
37.12219 +"ASCII 175."
37.12220 +msgstr ""
37.12221 +
37.12222 +#. type: Content of: <book><chapter><sect1><para>
37.12223 +#: ../en/ch10-template.xml:241
37.12224  msgid ""
37.12225  "As indicated above, if you want the expansion of a template to contain a "
37.12226  "literal <quote><literal>\\</literal></quote>, <quote><literal>{</literal></"
37.12227 @@ -12902,12 +11987,12 @@
37.12228  msgstr ""
37.12229  
37.12230  #. type: Content of: <book><chapter><sect1><title>
37.12231 -#: ../en/ch11-template.xml:248
37.12232 +#: ../en/ch10-template.xml:249
37.12233  msgid "Filtering keywords to change their results"
37.12234  msgstr "通过过滤关键字来修改输出结果"
37.12235  
37.12236  #. type: Content of: <book><chapter><sect1><para>
37.12237 -#: ../en/ch11-template.xml:250
37.12238 +#: ../en/ch10-template.xml:251
37.12239  msgid ""
37.12240  "Some of the results of template expansion are not immediately easy to use.  "
37.12241  "Mercurial lets you specify an optional chain of <emphasis>filters</emphasis> "
37.12242 @@ -12917,7 +12002,7 @@
37.12243  msgstr ""
37.12244  
37.12245  #. type: Content of: <book><chapter><sect1><para>
37.12246 -#: ../en/ch11-template.xml:257
37.12247 +#: ../en/ch10-template.xml:258
37.12248  msgid ""
37.12249  "Below is a list of the most commonly used filters that Mercurial supports.  "
37.12250  "While some filters can be applied to any text, others can only be used in "
37.12251 @@ -12926,7 +12011,7 @@
37.12252  msgstr ""
37.12253  
37.12254  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12255 -#: ../en/ch11-template.xml:264
37.12256 +#: ../en/ch10-template.xml:265
37.12257  msgid ""
37.12258  "<literal role=\"template-filter\">addbreaks</literal>: Any text. Add an XHTML "
37.12259  "<quote><literal>&lt;br/&gt;</literal></quote> tag before the end of every "
37.12260 @@ -12935,7 +12020,7 @@
37.12261  msgstr ""
37.12262  
37.12263  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12264 -#: ../en/ch11-template.xml:271
37.12265 +#: ../en/ch10-template.xml:272
37.12266  msgid ""
37.12267  "<literal role=\"template-kw-filt-date\">age</literal>: <literal role="
37.12268  "\"template-keyword\">date</literal> keyword.  Render the age of the date, "
37.12269 @@ -12944,7 +12029,7 @@
37.12270  msgstr ""
37.12271  
37.12272  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12273 -#: ../en/ch11-template.xml:278
37.12274 +#: ../en/ch10-template.xml:279
37.12275  msgid ""
37.12276  "<literal role=\"template-filter\">basename</literal>: Any text, but most "
37.12277  "useful for the <literal role=\"template-keyword\">files</literal> keyword and "
37.12278 @@ -12954,7 +12039,7 @@
37.12279  msgstr ""
37.12280  
37.12281  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12282 -#: ../en/ch11-template.xml:287
37.12283 +#: ../en/ch10-template.xml:288
37.12284  msgid ""
37.12285  "<literal role=\"template-kw-filt-date\">date</literal>: <literal role="
37.12286  "\"template-keyword\">date</literal> keyword.  Render a date in a similar "
37.12287 @@ -12964,7 +12049,7 @@
37.12288  msgstr ""
37.12289  
37.12290  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12291 -#: ../en/ch11-template.xml:295
37.12292 +#: ../en/ch10-template.xml:296
37.12293  msgid ""
37.12294  "<literal role=\"template-kw-filt-author\">domain</literal>: Any text, but "
37.12295  "most useful for the <literal role=\"template-keyword\">author</literal> "
37.12296 @@ -12975,7 +12060,7 @@
37.12297  msgstr ""
37.12298  
37.12299  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12300 -#: ../en/ch11-template.xml:305
37.12301 +#: ../en/ch10-template.xml:306
37.12302  msgid ""
37.12303  "<literal role=\"template-kw-filt-author\">email</literal>: Any text, but most "
37.12304  "useful for the <literal role=\"template-keyword\">author</literal> keyword.  "
37.12305 @@ -12985,7 +12070,7 @@
37.12306  msgstr ""
37.12307  
37.12308  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12309 -#: ../en/ch11-template.xml:314
37.12310 +#: ../en/ch10-template.xml:315
37.12311  msgid ""
37.12312  "<literal role=\"template-filter\">escape</literal>: Any text.  Replace the "
37.12313  "special XML/XHTML characters <quote><literal>&amp;</literal></quote>, "
37.12314 @@ -12994,7 +12079,7 @@
37.12315  msgstr ""
37.12316  
37.12317  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12318 -#: ../en/ch11-template.xml:322
37.12319 +#: ../en/ch10-template.xml:323
37.12320  msgid ""
37.12321  "<literal role=\"template-filter\">fill68</literal>: Any text.  Wrap the text "
37.12322  "to fit in 68 columns.  This is useful before you pass text through the "
37.12323 @@ -13003,21 +12088,21 @@
37.12324  msgstr ""
37.12325  
37.12326  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12327 -#: ../en/ch11-template.xml:330
37.12328 +#: ../en/ch10-template.xml:331
37.12329  msgid ""
37.12330  "<literal role=\"template-filter\">fill76</literal>: Any text.  Wrap the text "
37.12331  "to fit in 76 columns."
37.12332  msgstr ""
37.12333  
37.12334  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12335 -#: ../en/ch11-template.xml:334
37.12336 +#: ../en/ch10-template.xml:335
37.12337  msgid ""
37.12338  "<literal role=\"template-filter\">firstline</literal>: Any text.  Yield the "
37.12339  "first line of text, without any trailing newlines."
37.12340  msgstr ""
37.12341  
37.12342  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12343 -#: ../en/ch11-template.xml:339
37.12344 +#: ../en/ch10-template.xml:340
37.12345  msgid ""
37.12346  "<literal role=\"template-kw-filt-date\">hgdate</literal>: <literal role="
37.12347  "\"template-keyword\">date</literal> keyword.  Render the date as a pair of "
37.12348 @@ -13026,7 +12111,7 @@
37.12349  msgstr ""
37.12350  
37.12351  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12352 -#: ../en/ch11-template.xml:346
37.12353 +#: ../en/ch10-template.xml:347
37.12354  msgid ""
37.12355  "<literal role=\"template-kw-filt-date\">isodate</literal>: <literal role="
37.12356  "\"template-keyword\">date</literal> keyword.  Render the date as a text "
37.12357 @@ -13035,7 +12120,7 @@
37.12358  msgstr ""
37.12359  
37.12360  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12361 -#: ../en/ch11-template.xml:353
37.12362 +#: ../en/ch10-template.xml:354
37.12363  msgid ""
37.12364  "<literal role=\"template-filter\">obfuscate</literal>: Any text, but most "
37.12365  "useful for the <literal role=\"template-keyword\">author</literal> keyword.  "
37.12366 @@ -13044,7 +12129,7 @@
37.12367  msgstr ""
37.12368  
37.12369  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12370 -#: ../en/ch11-template.xml:361
37.12371 +#: ../en/ch10-template.xml:362
37.12372  msgid ""
37.12373  "<literal role=\"template-kw-filt-author\">person</literal>: Any text, but "
37.12374  "most useful for the <literal role=\"template-keyword\">author</literal> "
37.12375 @@ -13054,7 +12139,7 @@
37.12376  msgstr ""
37.12377  
37.12378  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12379 -#: ../en/ch11-template.xml:370
37.12380 +#: ../en/ch10-template.xml:371
37.12381  msgid ""
37.12382  "<literal role=\"template-kw-filt-date\">rfc822date</literal>: <literal role="
37.12383  "\"template-keyword\">date</literal> keyword.  Render a date using the same "
37.12384 @@ -13063,7 +12148,7 @@
37.12385  msgstr ""
37.12386  
37.12387  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12388 -#: ../en/ch11-template.xml:377
37.12389 +#: ../en/ch10-template.xml:378
37.12390  msgid ""
37.12391  "<literal role=\"template-kw-filt-node\">short</literal>: Changeset hash.  "
37.12392  "Yield the short form of a changeset hash, i.e. a 12-character hexadecimal "
37.12393 @@ -13071,7 +12156,7 @@
37.12394  msgstr ""
37.12395  
37.12396  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12397 -#: ../en/ch11-template.xml:382
37.12398 +#: ../en/ch10-template.xml:383
37.12399  msgid ""
37.12400  "<literal role=\"template-kw-filt-date\">shortdate</literal>: <literal role="
37.12401  "\"template-keyword\">date</literal> keyword.  Render the year, month, and day "
37.12402 @@ -13080,21 +12165,21 @@
37.12403  msgstr ""
37.12404  
37.12405  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12406 -#: ../en/ch11-template.xml:388
37.12407 +#: ../en/ch10-template.xml:389
37.12408  msgid ""
37.12409  "<literal role=\"template-filter\">strip</literal>: Any text.  Strip all "
37.12410  "leading and trailing whitespace from the string."
37.12411  msgstr ""
37.12412  
37.12413  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12414 -#: ../en/ch11-template.xml:392
37.12415 +#: ../en/ch10-template.xml:393
37.12416  msgid ""
37.12417  "<literal role=\"template-filter\">tabindent</literal>: Any text.  Yield the "
37.12418  "text, with every line except the first starting with a tab character."
37.12419  msgstr ""
37.12420  
37.12421  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12422 -#: ../en/ch11-template.xml:397
37.12423 +#: ../en/ch10-template.xml:398
37.12424  msgid ""
37.12425  "<literal role=\"template-filter\">urlescape</literal>: Any text.  Escape all "
37.12426  "characters that are considered <quote>special</quote> by URL parsers.  For "
37.12427 @@ -13102,7 +12187,7 @@
37.12428  msgstr ""
37.12429  
37.12430  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.12431 -#: ../en/ch11-template.xml:404
37.12432 +#: ../en/ch10-template.xml:405
37.12433  msgid ""
37.12434  "<literal role=\"template-kw-filt-author\">user</literal>: Any text, but most "
37.12435  "useful for the <literal role=\"template-keyword\">author</literal> keyword.  "
37.12436 @@ -13112,7 +12197,7 @@
37.12437  msgstr ""
37.12438  
37.12439  #. type: Content of: <book><chapter><sect1><note><para>
37.12440 -#: ../en/ch11-template.xml:417
37.12441 +#: ../en/ch10-template.xml:418
37.12442  msgid ""
37.12443  "If you try to apply a filter to a piece of data that it cannot process, "
37.12444  "Mercurial will fail and print a Python exception.  For example, trying to run "
37.12445 @@ -13122,12 +12207,12 @@
37.12446  msgstr ""
37.12447  
37.12448  #. type: Content of: <book><chapter><sect1><sect2><title>
37.12449 -#: ../en/ch11-template.xml:426
37.12450 +#: ../en/ch10-template.xml:427
37.12451  msgid "Combining filters"
37.12452  msgstr "组合过滤器"
37.12453  
37.12454  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12455 -#: ../en/ch11-template.xml:428
37.12456 +#: ../en/ch10-template.xml:429
37.12457  msgid ""
37.12458  "It is easy to combine filters to yield output in the form you would like.  "
37.12459  "The following chain of filters tidies up a description, then makes sure that "
37.12460 @@ -13137,7 +12222,7 @@
37.12461  msgstr ""
37.12462  
37.12463  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12464 -#: ../en/ch11-template.xml:437
37.12465 +#: ../en/ch10-template.xml:438
37.12466  msgid ""
37.12467  "Note the use of <quote><literal>\\t</literal></quote> (a tab character) in "
37.12468  "the template to force the first line to be indented; this is necessary since "
37.12469 @@ -13146,7 +12231,7 @@
37.12470  msgstr ""
37.12471  
37.12472  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12473 -#: ../en/ch11-template.xml:443
37.12474 +#: ../en/ch10-template.xml:444
37.12475  msgid ""
37.12476  "Keep in mind that the order of filters in a chain is significant.  The first "
37.12477  "filter is applied to the result of the keyword; the second to the result of "
37.12478 @@ -13156,12 +12241,12 @@
37.12479  msgstr ""
37.12480  
37.12481  #. type: Content of: <book><chapter><sect1><title>
37.12482 -#: ../en/ch11-template.xml:454
37.12483 +#: ../en/ch10-template.xml:455
37.12484  msgid "From templates to styles"
37.12485  msgstr "从模版到样式"
37.12486  
37.12487  #. type: Content of: <book><chapter><sect1><para>
37.12488 -#: ../en/ch11-template.xml:456
37.12489 +#: ../en/ch10-template.xml:457
37.12490  msgid ""
37.12491  "A command line template provides a quick and simple way to format some "
37.12492  "output.  Templates can become verbose, though, and it's useful to be able to "
37.12493 @@ -13170,7 +12255,7 @@
37.12494  msgstr ""
37.12495  
37.12496  #. type: Content of: <book><chapter><sect1><para>
37.12497 -#: ../en/ch11-template.xml:461
37.12498 +#: ../en/ch10-template.xml:462
37.12499  msgid ""
37.12500  "More than that, using a style file unlocks the power of Mercurial's "
37.12501  "templating engine in ways that are not possible using the command line "
37.12502 @@ -13178,49 +12263,49 @@
37.12503  msgstr ""
37.12504  
37.12505  #. type: Content of: <book><chapter><sect1><sect2><title>
37.12506 -#: ../en/ch11-template.xml:467
37.12507 +#: ../en/ch10-template.xml:468
37.12508  msgid "The simplest of style files"
37.12509  msgstr "最简单的样式文件"
37.12510  
37.12511  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12512 -#: ../en/ch11-template.xml:469
37.12513 +#: ../en/ch10-template.xml:470
37.12514  msgid "Our simple style file contains just one line:"
37.12515  msgstr ""
37.12516  
37.12517  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12518 -#: ../en/ch11-template.xml:473
37.12519 +#: ../en/ch10-template.xml:474
37.12520  msgid ""
37.12521  "This tells Mercurial, <quote>if you're printing a changeset, use the text on "
37.12522  "the right as the template</quote>."
37.12523  msgstr ""
37.12524  
37.12525  #. type: Content of: <book><chapter><sect1><sect2><title>
37.12526 -#: ../en/ch11-template.xml:479
37.12527 +#: ../en/ch10-template.xml:480
37.12528  msgid "Style file syntax"
37.12529  msgstr "样式文件语法"
37.12530  
37.12531  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12532 -#: ../en/ch11-template.xml:481
37.12533 +#: ../en/ch10-template.xml:482
37.12534  msgid "The syntax rules for a style file are simple."
37.12535  msgstr ""
37.12536  
37.12537  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.12538 -#: ../en/ch11-template.xml:484
37.12539 +#: ../en/ch10-template.xml:485
37.12540  msgid "The file is processed one line at a time."
37.12541  msgstr ""
37.12542  
37.12543  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.12544 -#: ../en/ch11-template.xml:487
37.12545 +#: ../en/ch10-template.xml:488
37.12546  msgid "Leading and trailing white space are ignored."
37.12547  msgstr ""
37.12548  
37.12549  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.12550 -#: ../en/ch11-template.xml:490
37.12551 +#: ../en/ch10-template.xml:491
37.12552  msgid "Empty lines are skipped."
37.12553  msgstr ""
37.12554  
37.12555  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.12556 -#: ../en/ch11-template.xml:492
37.12557 +#: ../en/ch10-template.xml:493
37.12558  msgid ""
37.12559  "If a line starts with either of the characters <quote><literal>#</literal></"
37.12560  "quote> or <quote><literal>;</literal></quote>, the entire line is treated as "
37.12561 @@ -13228,7 +12313,7 @@
37.12562  msgstr ""
37.12563  
37.12564  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.12565 -#: ../en/ch11-template.xml:497
37.12566 +#: ../en/ch10-template.xml:498
37.12567  msgid ""
37.12568  "A line starts with a keyword.  This must start with an alphabetic character "
37.12569  "or underscore, and can subsequently contain any alphanumeric character or "
37.12570 @@ -13237,21 +12322,21 @@
37.12571  msgstr ""
37.12572  
37.12573  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.12574 -#: ../en/ch11-template.xml:503
37.12575 +#: ../en/ch10-template.xml:504
37.12576  msgid ""
37.12577  "The next element must be an <quote><literal>=</literal></quote> character, "
37.12578  "which can be preceded or followed by an arbitrary amount of white space."
37.12579  msgstr ""
37.12580  
37.12581  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.12582 -#: ../en/ch11-template.xml:508
37.12583 +#: ../en/ch10-template.xml:509
37.12584  msgid ""
37.12585  "If the rest of the line starts and ends with matching quote characters "
37.12586  "(either single or double quote), it is treated as a template body."
37.12587  msgstr ""
37.12588  
37.12589  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.12590 -#: ../en/ch11-template.xml:512
37.12591 +#: ../en/ch10-template.xml:513
37.12592  msgid ""
37.12593  "If the rest of the line <emphasis>does not</emphasis> start with a quote "
37.12594  "character, it is treated as the name of a file; the contents of this file "
37.12595 @@ -13259,12 +12344,12 @@
37.12596  msgstr ""
37.12597  
37.12598  #. type: Content of: <book><chapter><sect1><title>
37.12599 -#: ../en/ch11-template.xml:521
37.12600 +#: ../en/ch10-template.xml:522
37.12601  msgid "Style files by example"
37.12602  msgstr "样式文件例子"
37.12603  
37.12604  #. type: Content of: <book><chapter><sect1><para>
37.12605 -#: ../en/ch11-template.xml:523
37.12606 +#: ../en/ch10-template.xml:524
37.12607  msgid ""
37.12608  "To illustrate how to write a style file, we will construct a few by example.  "
37.12609  "Rather than provide a complete style file and walk through it, we'll mirror "
37.12610 @@ -13273,12 +12358,12 @@
37.12611  msgstr ""
37.12612  
37.12613  #. type: Content of: <book><chapter><sect1><sect2><title>
37.12614 -#: ../en/ch11-template.xml:530
37.12615 +#: ../en/ch10-template.xml:531
37.12616  msgid "Identifying mistakes in style files"
37.12617  msgstr "在样式文件中定位错误"
37.12618  
37.12619  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12620 -#: ../en/ch11-template.xml:532
37.12621 +#: ../en/ch10-template.xml:533
37.12622  msgid ""
37.12623  "If Mercurial encounters a problem in a style file you are working on, it "
37.12624  "prints a terse error message that, once you figure out what it means, is "
37.12625 @@ -13286,7 +12371,7 @@
37.12626  msgstr ""
37.12627  
37.12628  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12629 -#: ../en/ch11-template.xml:538
37.12630 +#: ../en/ch10-template.xml:539
37.12631  msgid ""
37.12632  "Notice that <filename>broken.style</filename> attempts to define a "
37.12633  "<literal>changeset</literal> keyword, but forgets to give any content for it. "
37.12634 @@ -13294,35 +12379,35 @@
37.12635  msgstr ""
37.12636  
37.12637  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12638 -#: ../en/ch11-template.xml:545
37.12639 +#: ../en/ch10-template.xml:546
37.12640  msgid "This error message looks intimidating, but it is not too hard to follow."
37.12641  msgstr ""
37.12642  
37.12643  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.12644 -#: ../en/ch11-template.xml:549
37.12645 +#: ../en/ch10-template.xml:550
37.12646  msgid ""
37.12647  "The first component is simply Mercurial's way of saying <quote>I am giving "
37.12648  "up</quote>."
37.12649  msgstr ""
37.12650  
37.12651  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.12652 -#: ../en/ch11-template.xml:554
37.12653 +#: ../en/ch10-template.xml:554
37.12654  msgid "Next comes the name of the style file that contains the error."
37.12655  msgstr ""
37.12656  
37.12657  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.12658 -#: ../en/ch11-template.xml:560
37.12659 +#: ../en/ch10-template.xml:558
37.12660  msgid ""
37.12661  "Following the file name is the line number where the error was encountered."
37.12662  msgstr ""
37.12663  
37.12664  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.12665 -#: ../en/ch11-template.xml:565
37.12666 +#: ../en/ch10-template.xml:562
37.12667  msgid "Finally, a description of what went wrong."
37.12668  msgstr ""
37.12669  
37.12670  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.12671 -#: ../en/ch11-template.xml:570
37.12672 +#: ../en/ch10-template.xml:566
37.12673  msgid ""
37.12674  "The description of the problem is not always clear (as in this case), but "
37.12675  "even when it is cryptic, it is almost always trivial to visually inspect the "
37.12676 @@ -13330,12 +12415,12 @@
37.12677  msgstr ""
37.12678  
37.12679  #. type: Content of: <book><chapter><sect1><sect2><title>
37.12680 -#: ../en/ch11-template.xml:578
37.12681 +#: ../en/ch10-template.xml:574
37.12682  msgid "Uniquely identifying a repository"
37.12683  msgstr "版本库的唯一标识"
37.12684  
37.12685  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12686 -#: ../en/ch11-template.xml:580
37.12687 +#: ../en/ch10-template.xml:576
37.12688  msgid ""
37.12689  "If you would like to be able to identify a Mercurial repository <quote>fairly "
37.12690  "uniquely</quote> using a short string as an identifier, you can use the first "
37.12691 @@ -13343,21 +12428,21 @@
37.12692  msgstr ""
37.12693  
37.12694  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12695 -#: ../en/ch11-template.xml:587
37.12696 +#: ../en/ch10-template.xml:583
37.12697  msgid ""
37.12698  "This is not guaranteed to be unique, but it is nevertheless useful in many "
37.12699  "cases."
37.12700  msgstr ""
37.12701  
37.12702  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.12703 -#: ../en/ch11-template.xml:590
37.12704 +#: ../en/ch10-template.xml:586
37.12705  msgid ""
37.12706  "It will not work in a completely empty repository, because such a repository "
37.12707  "does not have a revision zero."
37.12708  msgstr ""
37.12709  
37.12710  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.12711 -#: ../en/ch11-template.xml:594
37.12712 +#: ../en/ch10-template.xml:590
37.12713  msgid ""
37.12714  "Neither will it work in the (extremely rare)  case where a repository is a "
37.12715  "merge of two or more formerly independent repositories, and you still have "
37.12716 @@ -13365,18 +12450,18 @@
37.12717  msgstr ""
37.12718  
37.12719  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12720 -#: ../en/ch11-template.xml:599
37.12721 +#: ../en/ch10-template.xml:595
37.12722  msgid "Here are some uses to which you could put this identifier:"
37.12723  msgstr ""
37.12724  
37.12725  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.12726 -#: ../en/ch11-template.xml:602
37.12727 +#: ../en/ch10-template.xml:598
37.12728  msgid ""
37.12729  "As a key into a table for a database that manages repositories on a server."
37.12730  msgstr ""
37.12731  
37.12732  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.12733 -#: ../en/ch11-template.xml:605
37.12734 +#: ../en/ch10-template.xml:601
37.12735  msgid ""
37.12736  "As half of a {<emphasis>repository ID</emphasis>, <emphasis>revision ID</"
37.12737  "emphasis>} tuple.  Save this information away when you run an automated build "
37.12738 @@ -13385,13 +12470,13 @@
37.12739  msgstr ""
37.12740  
37.12741  #. type: Content of: <book><chapter><sect1><sect2><title>
37.12742 -#: ../en/ch11-template.xml:614
37.12743 +#: ../en/ch10-template.xml:610
37.12744  msgid "Mimicking Subversion's output"
37.12745  msgstr "模仿 Subversion 的输出"
37.12746  
37.12747  #
37.12748  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12749 -#: ../en/ch11-template.xml:616
37.12750 +#: ../en/ch10-template.xml:612
37.12751  msgid ""
37.12752  "Let's try to emulate the default output format used by another revision "
37.12753  "control tool, Subversion."
37.12754 @@ -13399,7 +12484,7 @@
37.12755  
37.12756  #
37.12757  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12758 -#: ../en/ch11-template.xml:621
37.12759 +#: ../en/ch10-template.xml:617
37.12760  msgid ""
37.12761  "Since Subversion's output style is fairly simple, it is easy to copy-and-"
37.12762  "paste a hunk of its output into a file, and replace the text produced above "
37.12763 @@ -13407,14 +12492,14 @@
37.12764  msgstr ""
37.12765  
37.12766  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12767 -#: ../en/ch11-template.xml:628
37.12768 +#: ../en/ch10-template.xml:624
37.12769  msgid ""
37.12770  "There are a few small ways in which this template deviates from the output "
37.12771  "produced by Subversion."
37.12772  msgstr ""
37.12773  
37.12774  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.12775 -#: ../en/ch11-template.xml:631
37.12776 +#: ../en/ch10-template.xml:627
37.12777  msgid ""
37.12778  "Subversion prints a <quote>readable</quote> date (the <quote><literal>Wed, 27 "
37.12779  "Sep 2006</literal></quote> in the example output above) in parentheses.  "
37.12780 @@ -13423,7 +12508,7 @@
37.12781  msgstr ""
37.12782  
37.12783  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.12784 -#: ../en/ch11-template.xml:638
37.12785 +#: ../en/ch10-template.xml:634
37.12786  msgid ""
37.12787  "We emulate Subversion's printing of <quote>separator</quote> lines full of "
37.12788  "<quote><literal>-</literal></quote> characters by ending the template with "
37.12789 @@ -13433,7 +12518,7 @@
37.12790  msgstr ""
37.12791  
37.12792  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.12793 -#: ../en/ch11-template.xml:647
37.12794 +#: ../en/ch10-template.xml:643
37.12795  msgid ""
37.12796  "Subversion's output includes a count in the header of the number of lines in "
37.12797  "the commit message.  We cannot replicate this in Mercurial; the templating "
37.12798 @@ -13443,7 +12528,7 @@
37.12799  
37.12800  #
37.12801  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12802 -#: ../en/ch11-template.xml:653
37.12803 +#: ../en/ch10-template.xml:649
37.12804  msgid ""
37.12805  "It took me no more than a minute or two of work to replace literal text from "
37.12806  "an example of Subversion's output with some keywords and filters to give the "
37.12807 @@ -13451,7 +12536,7 @@
37.12808  msgstr ""
37.12809  
37.12810  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12811 -#: ../en/ch11-template.xml:660
37.12812 +#: ../en/ch10-template.xml:656
37.12813  msgid ""
37.12814  "We could have included the text of the template file directly in the style "
37.12815  "file by enclosing it in quotes and replacing the newlines with "
37.12816 @@ -13464,17 +12549,17 @@
37.12817  msgstr ""
37.12818  
37.12819  #. type: Content of: <book><chapter><title>
37.12820 -#: ../en/ch12-mq.xml:5
37.12821 +#: ../en/ch11-mq.xml:5
37.12822  msgid "Managing change with Mercurial Queues"
37.12823  msgstr "使用 MQ 管理修改"
37.12824  
37.12825  #. type: Content of: <book><chapter><sect1><title>
37.12826 -#: ../en/ch12-mq.xml:8
37.12827 +#: ../en/ch11-mq.xml:8
37.12828  msgid "The patch management problem"
37.12829  msgstr "补丁的管理问题"
37.12830  
37.12831  #. type: Content of: <book><chapter><sect1><para>
37.12832 -#: ../en/ch12-mq.xml:10
37.12833 +#: ../en/ch11-mq.xml:10
37.12834  msgid ""
37.12835  "Here is a common scenario: you need to install a software package from "
37.12836  "source, but you find a bug that you must fix in the source before you can "
37.12837 @@ -13486,7 +12571,7 @@
37.12838  msgstr ""
37.12839  
37.12840  #. type: Content of: <book><chapter><sect1><para>
37.12841 -#: ../en/ch12-mq.xml:20
37.12842 +#: ../en/ch11-mq.xml:20
37.12843  msgid ""
37.12844  "This is a simple case of the <quote>patch management</quote> problem.  You "
37.12845  "have an <quote>upstream</quote> source tree that you can't change; you need "
37.12846 @@ -13496,7 +12581,7 @@
37.12847  msgstr ""
37.12848  
37.12849  #. type: Content of: <book><chapter><sect1><para>
37.12850 -#: ../en/ch12-mq.xml:27
37.12851 +#: ../en/ch11-mq.xml:27
37.12852  msgid ""
37.12853  "The patch management problem arises in many situations.  Probably the most "
37.12854  "visible is that a user of an open source software project will contribute a "
37.12855 @@ -13504,7 +12589,7 @@
37.12856  msgstr ""
37.12857  
37.12858  #. type: Content of: <book><chapter><sect1><para>
37.12859 -#: ../en/ch12-mq.xml:32
37.12860 +#: ../en/ch11-mq.xml:32
37.12861  msgid ""
37.12862  "Distributors of operating systems that include open source software often "
37.12863  "need to make changes to the packages they distribute so that they will build "
37.12864 @@ -13512,7 +12597,7 @@
37.12865  msgstr ""
37.12866  
37.12867  #. type: Content of: <book><chapter><sect1><para>
37.12868 -#: ../en/ch12-mq.xml:37
37.12869 +#: ../en/ch11-mq.xml:37
37.12870  msgid ""
37.12871  "When you have few changes to maintain, it is easy to manage a single patch "
37.12872  "using the standard <command>diff</command> and <command>patch</command> "
37.12873 @@ -13529,7 +12614,7 @@
37.12874  msgstr ""
37.12875  
37.12876  #. type: Content of: <book><chapter><sect1><para>
37.12877 -#: ../en/ch12-mq.xml:52
37.12878 +#: ../en/ch11-mq.xml:52
37.12879  msgid ""
37.12880  "Maintaining a single patch against an upstream tree is a little tedious and "
37.12881  "error-prone, but not difficult.  However, the complexity of the problem grows "
37.12882 @@ -13539,7 +12624,7 @@
37.12883  msgstr ""
37.12884  
37.12885  #. type: Content of: <book><chapter><sect1><para>
37.12886 -#: ../en/ch12-mq.xml:59
37.12887 +#: ../en/ch11-mq.xml:59
37.12888  msgid ""
37.12889  "Fortunately, Mercurial includes a powerful extension, Mercurial Queues (or "
37.12890  "simply <quote>MQ</quote>), that massively simplifies the patch management "
37.12891 @@ -13547,12 +12632,12 @@
37.12892  msgstr ""
37.12893  
37.12894  #. type: Content of: <book><chapter><sect1><title>
37.12895 -#: ../en/ch12-mq.xml:65
37.12896 +#: ../en/ch11-mq.xml:65
37.12897  msgid "The prehistory of Mercurial Queues"
37.12898  msgstr "MQ 的历史"
37.12899  
37.12900  #. type: Content of: <book><chapter><sect1><para>
37.12901 -#: ../en/ch12-mq.xml:67
37.12902 +#: ../en/ch11-mq.xml:67
37.12903  msgid ""
37.12904  "During the late 1990s, several Linux kernel developers started to maintain "
37.12905  "<quote>patch series</quote> that modified the behaviour of the Linux kernel.  "
37.12906 @@ -13561,7 +12646,7 @@
37.12907  msgstr ""
37.12908  
37.12909  #. type: Content of: <book><chapter><sect1><para>
37.12910 -#: ../en/ch12-mq.xml:73
37.12911 +#: ../en/ch11-mq.xml:73
37.12912  msgid ""
37.12913  "The sizes of these patch series grew rapidly.  In 2002, Andrew Morton "
37.12914  "published some shell scripts he had been using to automate the task of "
37.12915 @@ -13570,12 +12655,12 @@
37.12916  msgstr ""
37.12917  
37.12918  #. type: Content of: <book><chapter><sect1><sect2><title>
37.12919 -#: ../en/ch12-mq.xml:80
37.12920 +#: ../en/ch11-mq.xml:80
37.12921  msgid "A patchwork quilt"
37.12922  msgstr ""
37.12923  
37.12924  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12925 -#: ../en/ch12-mq.xml:82
37.12926 +#: ../en/ch11-mq.xml:82
37.12927  msgid ""
37.12928  "In early 2003, Andreas Gruenbacher and Martin Quinson borrowed the approach "
37.12929  "of Andrew's scripts and published a tool called <quote>patchwork quilt</"
37.12930 @@ -13586,7 +12671,7 @@
37.12931  msgstr ""
37.12932  
37.12933  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12934 -#: ../en/ch12-mq.xml:91
37.12935 +#: ../en/ch11-mq.xml:91
37.12936  msgid ""
37.12937  "Quilt manages a <emphasis>stack of patches</emphasis> on top of a directory "
37.12938  "tree. To begin, you tell quilt to manage a directory tree, and tell it which "
37.12939 @@ -13596,7 +12681,7 @@
37.12940  msgstr ""
37.12941  
37.12942  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12943 -#: ../en/ch12-mq.xml:99
37.12944 +#: ../en/ch11-mq.xml:99
37.12945  msgid ""
37.12946  "The refresh step causes quilt to scan the directory tree; it updates the "
37.12947  "patch with all of the changes you have made.  You can create another patch on "
37.12948 @@ -13606,7 +12691,7 @@
37.12949  msgstr ""
37.12950  
37.12951  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12952 -#: ../en/ch12-mq.xml:106
37.12953 +#: ../en/ch11-mq.xml:106
37.12954  msgid ""
37.12955  "You can <emphasis>change</emphasis> which patches are applied to the tree.  "
37.12956  "If you <quote>pop</quote> a patch, the changes made by that patch will vanish "
37.12957 @@ -13620,19 +12705,19 @@
37.12958  msgstr ""
37.12959  
37.12960  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12961 -#: ../en/ch12-mq.xml:118
37.12962 +#: ../en/ch11-mq.xml:118
37.12963  msgid ""
37.12964  "Quilt knows nothing about revision control tools, so it works equally well on "
37.12965  "top of an unpacked tarball or a Subversion working copy."
37.12966  msgstr ""
37.12967  
37.12968  #. type: Content of: <book><chapter><sect1><sect2><title>
37.12969 -#: ../en/ch12-mq.xml:124
37.12970 +#: ../en/ch11-mq.xml:124
37.12971  msgid "From patchwork quilt to Mercurial Queues"
37.12972  msgstr "从 patchwork quilt 到 MQ"
37.12973  
37.12974  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12975 -#: ../en/ch12-mq.xml:126
37.12976 +#: ../en/ch11-mq.xml:126
37.12977  msgid ""
37.12978  "In mid-2005, Chris Mason took the features of quilt and wrote an extension "
37.12979  "that he called Mercurial Queues, which added quilt-like behaviour to "
37.12980 @@ -13640,7 +12725,7 @@
37.12981  msgstr ""
37.12982  
37.12983  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12984 -#: ../en/ch12-mq.xml:130
37.12985 +#: ../en/ch11-mq.xml:130
37.12986  msgid ""
37.12987  "The key difference between quilt and MQ is that quilt knows nothing about "
37.12988  "revision control systems, while MQ is <emphasis>integrated</emphasis> into "
37.12989 @@ -13649,7 +12734,7 @@
37.12990  msgstr ""
37.12991  
37.12992  #. type: Content of: <book><chapter><sect1><sect2><para>
37.12993 -#: ../en/ch12-mq.xml:136
37.12994 +#: ../en/ch11-mq.xml:136
37.12995  msgid ""
37.12996  "Because quilt does not care about revision control tools, it is still a "
37.12997  "tremendously useful piece of software to know about for situations where you "
37.12998 @@ -13657,19 +12742,19 @@
37.12999  msgstr ""
37.13000  
37.13001  #. type: Content of: <book><chapter><sect1><title>
37.13002 -#: ../en/ch12-mq.xml:144
37.13003 +#: ../en/ch11-mq.xml:144
37.13004  msgid "The huge advantage of MQ"
37.13005  msgstr "MQ 的巨大优势"
37.13006  
37.13007  #. type: Content of: <book><chapter><sect1><para>
37.13008 -#: ../en/ch12-mq.xml:146
37.13009 +#: ../en/ch11-mq.xml:146
37.13010  msgid ""
37.13011  "I cannot overstate the value that MQ offers through the unification of "
37.13012  "patches and revision control."
37.13013  msgstr ""
37.13014  
37.13015  #. type: Content of: <book><chapter><sect1><para>
37.13016 -#: ../en/ch12-mq.xml:149
37.13017 +#: ../en/ch11-mq.xml:149
37.13018  msgid ""
37.13019  "A major reason that patches have persisted in the free software and open "
37.13020  "source world&emdash;in spite of the availability of increasingly capable "
37.13021 @@ -13678,7 +12763,7 @@
37.13022  msgstr ""
37.13023  
37.13024  #. type: Content of: <book><chapter><sect1><para>
37.13025 -#: ../en/ch12-mq.xml:155
37.13026 +#: ../en/ch11-mq.xml:155
37.13027  msgid ""
37.13028  "Traditional revision control tools make a permanent, irreversible record of "
37.13029  "everything that you do.  While this has great value, it's also somewhat "
37.13030 @@ -13689,7 +12774,7 @@
37.13031  msgstr ""
37.13032  
37.13033  #. type: Content of: <book><chapter><sect1><para>
37.13034 -#: ../en/ch12-mq.xml:163
37.13035 +#: ../en/ch11-mq.xml:163
37.13036  msgid ""
37.13037  "By contrast, MQ's marriage of distributed revision control with patches makes "
37.13038  "it much easier to isolate your work.  Your patches live on top of normal "
37.13039 @@ -13700,7 +12785,7 @@
37.13040  msgstr ""
37.13041  
37.13042  #. type: Content of: <book><chapter><sect1><para>
37.13043 -#: ../en/ch12-mq.xml:171
37.13044 +#: ../en/ch11-mq.xml:171
37.13045  msgid ""
37.13046  "As an example, the integration of patches with revision control makes "
37.13047  "understanding patches and debugging their effects&emdash;and their interplay "
37.13048 @@ -13715,19 +12800,19 @@
37.13049  msgstr ""
37.13050  
37.13051  #. type: Content of: <book><chapter><sect1><title>
37.13052 -#: ../en/ch12-mq.xml:187
37.13053 +#: ../en/ch11-mq.xml:187
37.13054  msgid "Understanding patches"
37.13055  msgstr "理解补丁"
37.13056  
37.13057  #. type: Content of: <book><chapter><sect1><para>
37.13058 -#: ../en/ch12-mq.xml:189
37.13059 +#: ../en/ch11-mq.xml:189
37.13060  msgid ""
37.13061  "Because MQ doesn't hide its patch-oriented nature, it is helpful to "
37.13062  "understand what patches are, and a little about the tools that work with them."
37.13063  msgstr ""
37.13064  
37.13065  #. type: Content of: <book><chapter><sect1><para>
37.13066 -#: ../en/ch12-mq.xml:193
37.13067 +#: ../en/ch11-mq.xml:193
37.13068  msgid ""
37.13069  "The traditional Unix <command>diff</command> command compares two files, and "
37.13070  "prints a list of differences between them. The <command>patch</command> "
37.13071 @@ -13737,7 +12822,7 @@
37.13072  msgstr ""
37.13073  
37.13074  #. type: Content of: <book><chapter><sect1><para>
37.13075 -#: ../en/ch12-mq.xml:202
37.13076 +#: ../en/ch11-mq.xml:202
37.13077  msgid ""
37.13078  "The type of file that <command>diff</command> generates (and <command>patch</"
37.13079  "command> takes as input) is called a <quote>patch</quote> or a <quote>diff</"
37.13080 @@ -13746,7 +12831,7 @@
37.13081  msgstr ""
37.13082  
37.13083  #. type: Content of: <book><chapter><sect1><para>
37.13084 -#: ../en/ch12-mq.xml:208
37.13085 +#: ../en/ch11-mq.xml:208
37.13086  msgid ""
37.13087  "A patch file can start with arbitrary text; the <command>patch</command> "
37.13088  "command ignores this text, but MQ uses it as the commit message when creating "
37.13089 @@ -13756,7 +12841,7 @@
37.13090  msgstr ""
37.13091  
37.13092  #. type: Content of: <book><chapter><sect1><para>
37.13093 -#: ../en/ch12-mq.xml:215
37.13094 +#: ../en/ch11-mq.xml:215
37.13095  msgid ""
37.13096  "MQ works with <emphasis>unified</emphasis> diffs (<command>patch</command> "
37.13097  "can accept several other diff formats, but MQ doesn't).  A unified diff "
37.13098 @@ -13767,7 +12852,7 @@
37.13099  msgstr ""
37.13100  
37.13101  #. type: Content of: <book><chapter><sect1><para>
37.13102 -#: ../en/ch12-mq.xml:223
37.13103 +#: ../en/ch11-mq.xml:223
37.13104  msgid ""
37.13105  "After the file header comes a series of <emphasis>hunks</emphasis>.  Each "
37.13106  "hunk starts with a header; this identifies the range of line numbers within "
37.13107 @@ -13780,7 +12865,7 @@
37.13108  msgstr ""
37.13109  
37.13110  #. type: Content of: <book><chapter><sect1><para>
37.13111 -#: ../en/ch12-mq.xml:235
37.13112 +#: ../en/ch11-mq.xml:235
37.13113  msgid ""
37.13114  "Each line of context begins with a space character.  Within the hunk, a line "
37.13115  "that begins with <quote><literal>-</literal></quote> means <quote>remove this "
37.13116 @@ -13790,7 +12875,7 @@
37.13117  msgstr ""
37.13118  
37.13119  #. type: Content of: <book><chapter><sect1><para>
37.13120 -#: ../en/ch12-mq.xml:243
37.13121 +#: ../en/ch11-mq.xml:243
37.13122  msgid ""
37.13123  "We will return to some of the more subtle aspects of patches later (in "
37.13124  "section <xref linkend=\"sec.mq.adv-patch\"/>), but you should have enough "
37.13125 @@ -13798,12 +12883,12 @@
37.13126  msgstr ""
37.13127  
37.13128  #. type: Content of: <book><chapter><sect1><title>
37.13129 -#: ../en/ch12-mq.xml:250
37.13130 +#: ../en/ch11-mq.xml:250
37.13131  msgid "Getting started with Mercurial Queues"
37.13132  msgstr "开始使用 MQ"
37.13133  
37.13134  #. type: Content of: <book><chapter><sect1><para>
37.13135 -#: ../en/ch12-mq.xml:252
37.13136 +#: ../en/ch11-mq.xml:252
37.13137  msgid ""
37.13138  "Because MQ is implemented as an extension, you must explicitly enable before "
37.13139  "you can use it.  (You don't need to download anything; MQ ships with the "
37.13140 @@ -13812,7 +12897,7 @@
37.13141  msgstr ""
37.13142  
37.13143  #. type: Content of: <book><chapter><sect1><para>
37.13144 -#: ../en/ch12-mq.xml:261
37.13145 +#: ../en/ch11-mq.xml:262
37.13146  msgid ""
37.13147  "Once the extension is enabled, it will make a number of new commands "
37.13148  "available.  To verify that the extension is working, you can use <command "
37.13149 @@ -13821,7 +12906,7 @@
37.13150  msgstr ""
37.13151  
37.13152  #. type: Content of: <book><chapter><sect1><para>
37.13153 -#: ../en/ch12-mq.xml:269
37.13154 +#: ../en/ch11-mq.xml:270
37.13155  msgid ""
37.13156  "You can use MQ with <emphasis>any</emphasis> Mercurial repository, and its "
37.13157  "commands only operate within that repository.  To get started, simply prepare "
37.13158 @@ -13829,7 +12914,7 @@
37.13159  msgstr ""
37.13160  
37.13161  #. type: Content of: <book><chapter><sect1><para>
37.13162 -#: ../en/ch12-mq.xml:276
37.13163 +#: ../en/ch11-mq.xml:277
37.13164  msgid ""
37.13165  "This command creates an empty directory called <filename role=\"special\" "
37.13166  "class=\"directory\">.hg/patches</filename>, where MQ will keep its metadata.  "
37.13167 @@ -13838,12 +12923,12 @@
37.13168  msgstr ""
37.13169  
37.13170  #. type: Content of: <book><chapter><sect1><sect2><title>
37.13171 -#: ../en/ch12-mq.xml:283
37.13172 +#: ../en/ch11-mq.xml:284
37.13173  msgid "Creating a new patch"
37.13174  msgstr "创建新补丁"
37.13175  
37.13176  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13177 -#: ../en/ch12-mq.xml:285
37.13178 +#: ../en/ch11-mq.xml:286
37.13179  msgid ""
37.13180  "To begin work on a new patch, use the <command role=\"hg-ext-mq\">qnew</"
37.13181  "command> command.  This command takes one argument, the name of the patch to "
37.13182 @@ -13851,14 +12936,14 @@
37.13183  msgstr ""
37.13184  
37.13185  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13186 -#: ../en/ch12-mq.xml:289
37.13187 +#: ../en/ch11-mq.xml:290
37.13188  msgid ""
37.13189  "MQ will use this as the name of an actual file in the <filename role=\"special"
37.13190  "\" class=\"directory\">.hg/patches</filename> directory, as you can see below."
37.13191  msgstr ""
37.13192  
37.13193  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13194 -#: ../en/ch12-mq.xml:296
37.13195 +#: ../en/ch11-mq.xml:297
37.13196  msgid ""
37.13197  "Also newly present in the <filename role=\"special\" class=\"directory\">.hg/"
37.13198  "patches</filename> directory are two other files, <filename role=\"special"
37.13199 @@ -13871,7 +12956,7 @@
37.13200  msgstr ""
37.13201  
37.13202  #. type: Content of: <book><chapter><sect1><sect2><note><para>
37.13203 -#: ../en/ch12-mq.xml:308
37.13204 +#: ../en/ch11-mq.xml:309
37.13205  msgid ""
37.13206  "You may sometimes want to edit the <filename role=\"special\">series</"
37.13207  "filename> file by hand; for example, to change the sequence in which some "
37.13208 @@ -13881,7 +12966,7 @@
37.13209  msgstr ""
37.13210  
37.13211  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13212 -#: ../en/ch12-mq.xml:317
37.13213 +#: ../en/ch11-mq.xml:318
37.13214  msgid ""
37.13215  "Once you have created your new patch, you can edit files in the working "
37.13216  "directory as you usually would.  All of the normal Mercurial commands, such "
37.13217 @@ -13890,12 +12975,12 @@
37.13218  msgstr ""
37.13219  
37.13220  #. type: Content of: <book><chapter><sect1><sect2><title>
37.13221 -#: ../en/ch12-mq.xml:325
37.13222 +#: ../en/ch11-mq.xml:326
37.13223  msgid "Refreshing a patch"
37.13224  msgstr "刷新补丁"
37.13225  
37.13226  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13227 -#: ../en/ch12-mq.xml:327
37.13228 +#: ../en/ch11-mq.xml:328
37.13229  msgid ""
37.13230  "When you reach a point where you want to save your work, use the <command "
37.13231  "role=\"hg-ext-mq\">qrefresh</command> command to update the patch you are "
37.13232 @@ -13903,14 +12988,14 @@
37.13233  msgstr ""
37.13234  
37.13235  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13236 -#: ../en/ch12-mq.xml:333
37.13237 +#: ../en/ch11-mq.xml:334
37.13238  msgid ""
37.13239  "This command folds the changes you have made in the working directory into "
37.13240  "your patch, and updates its corresponding changeset to contain those changes."
37.13241  msgstr ""
37.13242  
37.13243  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13244 -#: ../en/ch12-mq.xml:337
37.13245 +#: ../en/ch11-mq.xml:338
37.13246  msgid ""
37.13247  "You can run <command role=\"hg-ext-mq\">qrefresh</command> as often as you "
37.13248  "like, so it's a good way to <quote>checkpoint</quote> your work.  Refresh "
37.13249 @@ -13920,12 +13005,12 @@
37.13250  msgstr ""
37.13251  
37.13252  #. type: Content of: <book><chapter><sect1><sect2><title>
37.13253 -#: ../en/ch12-mq.xml:348
37.13254 +#: ../en/ch11-mq.xml:349
37.13255  msgid "Stacking and tracking patches"
37.13256  msgstr "堆叠和跟踪补丁"
37.13257  
37.13258  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13259 -#: ../en/ch12-mq.xml:350
37.13260 +#: ../en/ch11-mq.xml:351
37.13261  msgid ""
37.13262  "Once you have finished working on a patch, or need to work on another, you "
37.13263  "can use the <command role=\"hg-ext-mq\">qnew</command> command again to "
37.13264 @@ -13934,7 +13019,7 @@
37.13265  msgstr ""
37.13266  
37.13267  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13268 -#: ../en/ch12-mq.xml:357
37.13269 +#: ../en/ch11-mq.xml:358
37.13270  msgid ""
37.13271  "Notice that the patch contains the changes in our prior patch as part of its "
37.13272  "context (you can see this more clearly in the output of <command role=\"hg-cmd"
37.13273 @@ -13942,7 +13027,7 @@
37.13274  msgstr ""
37.13275  
37.13276  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13277 -#: ../en/ch12-mq.xml:362
37.13278 +#: ../en/ch11-mq.xml:363
37.13279  msgid ""
37.13280  "So far, with the exception of <command role=\"hg-ext-mq\">qnew</command> and "
37.13281  "<command role=\"hg-ext-mq\">qrefresh</command>, we've been careful to only "
37.13282 @@ -13951,7 +13036,7 @@
37.13283  msgstr ""
37.13284  
37.13285  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.13286 -#: ../en/ch12-mq.xml:372
37.13287 +#: ../en/ch11-mq.xml:373
37.13288  msgid ""
37.13289  "The <command role=\"hg-ext-mq\">qseries</command> command lists every patch "
37.13290  "that MQ knows about in this repository, from oldest to newest (most recently "
37.13291 @@ -13959,7 +13044,7 @@
37.13292  msgstr ""
37.13293  
37.13294  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.13295 -#: ../en/ch12-mq.xml:378
37.13296 +#: ../en/ch11-mq.xml:379
37.13297  msgid ""
37.13298  "The <command role=\"hg-ext-mq\">qapplied</command> command lists every patch "
37.13299  "that MQ has <emphasis>applied</emphasis> in this repository, again from "
37.13300 @@ -13967,12 +13052,12 @@
37.13301  msgstr ""
37.13302  
37.13303  #. type: Content of: <book><chapter><sect1><sect2><title>
37.13304 -#: ../en/ch12-mq.xml:387
37.13305 +#: ../en/ch11-mq.xml:388
37.13306  msgid "Manipulating the patch stack"
37.13307  msgstr "操作补丁堆栈"
37.13308  
37.13309  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13310 -#: ../en/ch12-mq.xml:389
37.13311 +#: ../en/ch11-mq.xml:390
37.13312  msgid ""
37.13313  "The previous discussion implied that there must be a difference between "
37.13314  "<quote>known</quote> and <quote>applied</quote> patches, and there is.  MQ "
37.13315 @@ -13980,7 +13065,7 @@
37.13316  msgstr ""
37.13317  
37.13318  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13319 -#: ../en/ch12-mq.xml:394
37.13320 +#: ../en/ch11-mq.xml:395
37.13321  msgid ""
37.13322  "An <emphasis>applied</emphasis> patch has a corresponding changeset in the "
37.13323  "repository, and the effects of the patch and changeset are visible in the "
37.13324 @@ -13994,17 +13079,17 @@
37.13325  msgstr ""
37.13326  
37.13327  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
37.13328 -#: ../en/ch12-mq.xml:408
37.13329 +#: ../en/ch11-mq.xml:409
37.13330  msgid "<imageobject><imagedata fileref=\"images/mq-stack.png\"/></imageobject>"
37.13331  msgstr ""
37.13332  
37.13333  #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
37.13334 -#: ../en/ch12-mq.xml:410
37.13335 +#: ../en/ch11-mq.xml:411
37.13336  msgid "Applied and unapplied patches in the MQ patch stack"
37.13337  msgstr ""
37.13338  
37.13339  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13340 -#: ../en/ch12-mq.xml:415
37.13341 +#: ../en/ch11-mq.xml:416
37.13342  msgid ""
37.13343  "You can reapply an unapplied, or popped, patch using the <command role=\"hg-"
37.13344  "ext-mq\">qpush</command> command.  This creates a new changeset to correspond "
37.13345 @@ -14014,7 +13099,7 @@
37.13346  msgstr ""
37.13347  
37.13348  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13349 -#: ../en/ch12-mq.xml:424
37.13350 +#: ../en/ch11-mq.xml:425
37.13351  msgid ""
37.13352  "Notice that once we have popped a patch or two patches, the output of "
37.13353  "<command role=\"hg-ext-mq\">qseries</command> remains the same, while that of "
37.13354 @@ -14022,12 +13107,12 @@
37.13355  msgstr ""
37.13356  
37.13357  #. type: Content of: <book><chapter><sect1><sect2><title>
37.13358 -#: ../en/ch12-mq.xml:432
37.13359 +#: ../en/ch11-mq.xml:433
37.13360  msgid "Pushing and popping many patches"
37.13361  msgstr "压入或弹出多个补丁"
37.13362  
37.13363  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13364 -#: ../en/ch12-mq.xml:434
37.13365 +#: ../en/ch11-mq.xml:435
37.13366  msgid ""
37.13367  "While <command role=\"hg-ext-mq\">qpush</command> and <command role=\"hg-ext-"
37.13368  "mq\">qpop</command> each operate on a single patch at a time by default, you "
37.13369 @@ -14040,12 +13125,12 @@
37.13370  msgstr ""
37.13371  
37.13372  #. type: Content of: <book><chapter><sect1><sect2><title>
37.13373 -#: ../en/ch12-mq.xml:451
37.13374 +#: ../en/ch11-mq.xml:452
37.13375  msgid "Safety checks, and overriding them"
37.13376  msgstr "安全的检查,然后覆盖它们"
37.13377  
37.13378  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13379 -#: ../en/ch12-mq.xml:453
37.13380 +#: ../en/ch11-mq.xml:454
37.13381  msgid ""
37.13382  "Several MQ commands check the working directory before they do anything, and "
37.13383  "fail if they find any modifications.  They do this to ensure that you won't "
37.13384 @@ -14057,7 +13142,7 @@
37.13385  msgstr ""
37.13386  
37.13387  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13388 -#: ../en/ch12-mq.xml:465
37.13389 +#: ../en/ch11-mq.xml:466
37.13390  msgid ""
37.13391  "Commands that check the working directory all take an <quote>I know what I'm "
37.13392  "doing</quote> option, which is always named <option>-f</option>.  The exact "
37.13393 @@ -14071,12 +13156,12 @@
37.13394  msgstr ""
37.13395  
37.13396  #. type: Content of: <book><chapter><sect1><sect2><title>
37.13397 -#: ../en/ch12-mq.xml:480
37.13398 +#: ../en/ch11-mq.xml:481
37.13399  msgid "Working on several patches at once"
37.13400  msgstr "同时处理多个补丁"
37.13401  
37.13402  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13403 -#: ../en/ch12-mq.xml:482
37.13404 +#: ../en/ch11-mq.xml:483
37.13405  msgid ""
37.13406  "The <command role=\"hg-ext-mq\">qrefresh</command> command always refreshes "
37.13407  "the <emphasis>topmost</emphasis> applied patch.  This means that you can "
37.13408 @@ -14085,7 +13170,7 @@
37.13409  msgstr ""
37.13410  
37.13411  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13412 -#: ../en/ch12-mq.xml:489
37.13413 +#: ../en/ch11-mq.xml:490
37.13414  msgid ""
37.13415  "Here's an example that illustrates how you can use this ability. Let's say "
37.13416  "you're developing a new feature as two patches.  The first is a change to the "
37.13417 @@ -14101,12 +13186,12 @@
37.13418  msgstr ""
37.13419  
37.13420  #. type: Content of: <book><chapter><sect1><title>
37.13421 -#: ../en/ch12-mq.xml:506
37.13422 +#: ../en/ch11-mq.xml:507
37.13423  msgid "More about patches"
37.13424  msgstr "关于补丁的更多信息"
37.13425  
37.13426  #. type: Content of: <book><chapter><sect1><para>
37.13427 -#: ../en/ch12-mq.xml:508
37.13428 +#: ../en/ch11-mq.xml:509
37.13429  msgid ""
37.13430  "MQ uses the GNU <command>patch</command> command to apply patches, so it's "
37.13431  "helpful to know a few more detailed aspects of how <command>patch</command> "
37.13432 @@ -14114,12 +13199,12 @@
37.13433  msgstr ""
37.13434  
37.13435  #. type: Content of: <book><chapter><sect1><sect2><title>
37.13436 -#: ../en/ch12-mq.xml:514
37.13437 +#: ../en/ch11-mq.xml:515
37.13438  msgid "The strip count"
37.13439  msgstr "修剪计数"
37.13440  
37.13441  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13442 -#: ../en/ch12-mq.xml:516
37.13443 +#: ../en/ch11-mq.xml:517
37.13444  msgid ""
37.13445  "If you look at the file headers in a patch, you will notice that the "
37.13446  "pathnames usually have an extra component on the front that isn't present in "
37.13447 @@ -14129,7 +13214,7 @@
37.13448  msgstr ""
37.13449  
37.13450  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13451 -#: ../en/ch12-mq.xml:523
37.13452 +#: ../en/ch11-mq.xml:524
37.13453  msgid ""
37.13454  "Alice would unpack a tarball, edit her files, then decide that she wanted to "
37.13455  "create a patch.  So she'd rename her working directory, unpack the tarball "
37.13456 @@ -14143,7 +13228,7 @@
37.13457  msgstr ""
37.13458  
37.13459  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13460 -#: ../en/ch12-mq.xml:536
37.13461 +#: ../en/ch11-mq.xml:537
37.13462  msgid ""
37.13463  "Since someone receiving a patch from the Alices of the net would be unlikely "
37.13464  "to have unmodified and modified directories with exactly the same names, the "
37.13465 @@ -14154,7 +13239,7 @@
37.13466  msgstr ""
37.13467  
37.13468  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13469 -#: ../en/ch12-mq.xml:544
37.13470 +#: ../en/ch11-mq.xml:545
37.13471  msgid ""
37.13472  "An option of <quote><literal>-p1</literal></quote> means <quote>use a strip "
37.13473  "count of one</quote>.  If <command>patch</command> sees a file name "
37.13474 @@ -14168,7 +13253,7 @@
37.13475  msgstr ""
37.13476  
37.13477  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13478 -#: ../en/ch12-mq.xml:557
37.13479 +#: ../en/ch11-mq.xml:558
37.13480  msgid ""
37.13481  "The <quote>standard</quote> strip count for patches is one; almost all "
37.13482  "patches contain one leading path name component that needs to be stripped. "
37.13483 @@ -14178,7 +13263,7 @@
37.13484  msgstr ""
37.13485  
37.13486  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13487 -#: ../en/ch12-mq.xml:565
37.13488 +#: ../en/ch11-mq.xml:566
37.13489  msgid ""
37.13490  "If you receive a patch from someone that you want to add to your patch queue, "
37.13491  "and the patch needs a strip count other than one, you cannot just <command "
37.13492 @@ -14195,12 +13280,12 @@
37.13493  msgstr ""
37.13494  
37.13495  #. type: Content of: <book><chapter><sect1><sect2><title>
37.13496 -#: ../en/ch12-mq.xml:584
37.13497 +#: ../en/ch11-mq.xml:585
37.13498  msgid "Strategies for applying a patch"
37.13499  msgstr "应用补丁的策略"
37.13500  
37.13501  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13502 -#: ../en/ch12-mq.xml:586
37.13503 +#: ../en/ch11-mq.xml:587
37.13504  msgid ""
37.13505  "When <command>patch</command> applies a hunk, it tries a handful of "
37.13506  "successively less accurate strategies to try to make the hunk apply. This "
37.13507 @@ -14210,7 +13295,7 @@
37.13508  msgstr ""
37.13509  
37.13510  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13511 -#: ../en/ch12-mq.xml:593
37.13512 +#: ../en/ch11-mq.xml:594
37.13513  msgid ""
37.13514  "First, <command>patch</command> tries an exact match, where the line numbers, "
37.13515  "the context, and the text to be modified must apply exactly.  If it cannot "
37.13516 @@ -14221,7 +13306,7 @@
37.13517  msgstr ""
37.13518  
37.13519  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13520 -#: ../en/ch12-mq.xml:602
37.13521 +#: ../en/ch11-mq.xml:603
37.13522  msgid ""
37.13523  "If a context-only match fails, <command>patch</command> removes the first and "
37.13524  "last lines of the context, and tries a <emphasis>reduced</emphasis> context-"
37.13525 @@ -14232,7 +13317,7 @@
37.13526  msgstr ""
37.13527  
37.13528  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13529 -#: ../en/ch12-mq.xml:611
37.13530 +#: ../en/ch11-mq.xml:612
37.13531  msgid ""
37.13532  "When neither of these techniques works, <command>patch</command> prints a "
37.13533  "message saying that the hunk in question was rejected.  It saves rejected "
37.13534 @@ -14249,33 +13334,33 @@
37.13535  msgstr ""
37.13536  
37.13537  #. type: Content of: <book><chapter><sect1><sect2><title>
37.13538 -#: ../en/ch12-mq.xml:629
37.13539 +#: ../en/ch11-mq.xml:630
37.13540  msgid "Some quirks of patch representation"
37.13541  msgstr "补丁的一些特性"
37.13542  
37.13543  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13544 -#: ../en/ch12-mq.xml:631
37.13545 +#: ../en/ch11-mq.xml:632
37.13546  msgid ""
37.13547  "There are a few useful things to know about how <command>patch</command> "
37.13548  "works with files."
37.13549  msgstr ""
37.13550  
37.13551  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.13552 -#: ../en/ch12-mq.xml:634
37.13553 +#: ../en/ch11-mq.xml:635
37.13554  msgid ""
37.13555  "This should already be obvious, but <command>patch</command> cannot handle "
37.13556  "binary files."
37.13557  msgstr ""
37.13558  
37.13559  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.13560 -#: ../en/ch12-mq.xml:638
37.13561 +#: ../en/ch11-mq.xml:639
37.13562  msgid ""
37.13563  "Neither does it care about the executable bit; it creates new files as "
37.13564  "readable, but not executable."
37.13565  msgstr ""
37.13566  
37.13567  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.13568 -#: ../en/ch12-mq.xml:642
37.13569 +#: ../en/ch11-mq.xml:643
37.13570  msgid ""
37.13571  "<command>patch</command> treats the removal of a file as a diff between the "
37.13572  "file to be removed and the empty file.  So your idea of <quote>I deleted this "
37.13573 @@ -14284,7 +13369,7 @@
37.13574  msgstr ""
37.13575  
37.13576  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.13577 -#: ../en/ch12-mq.xml:648
37.13578 +#: ../en/ch11-mq.xml:649
37.13579  msgid ""
37.13580  "It treats the addition of a file as a diff between the empty file and the "
37.13581  "file to be added.  So in a patch, your idea of <quote>I added this file</"
37.13582 @@ -14292,7 +13377,7 @@
37.13583  msgstr ""
37.13584  
37.13585  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.13586 -#: ../en/ch12-mq.xml:654
37.13587 +#: ../en/ch11-mq.xml:655
37.13588  msgid ""
37.13589  "It treats a renamed file as the removal of the old name, and the addition of "
37.13590  "the new name.  This means that renamed files have a big footprint in "
37.13591 @@ -14301,7 +13386,7 @@
37.13592  msgstr ""
37.13593  
37.13594  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.13595 -#: ../en/ch12-mq.xml:660
37.13596 +#: ../en/ch11-mq.xml:661
37.13597  msgid ""
37.13598  "<command>patch</command> cannot represent empty files, so you cannot use a "
37.13599  "patch to represent the notion <quote>I added this empty file to the tree</"
37.13600 @@ -14309,12 +13394,12 @@
37.13601  msgstr ""
37.13602  
37.13603  #. type: Content of: <book><chapter><sect1><sect2><title>
37.13604 -#: ../en/ch12-mq.xml:667
37.13605 +#: ../en/ch11-mq.xml:668
37.13606  msgid "Beware the fuzz"
37.13607  msgstr "当心毛刺"
37.13608  
37.13609  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13610 -#: ../en/ch12-mq.xml:669
37.13611 +#: ../en/ch11-mq.xml:670
37.13612  msgid ""
37.13613  "While applying a hunk at an offset, or with a fuzz factor, will often be "
37.13614  "completely successful, these inexact techniques naturally leave open the "
37.13615 @@ -14326,7 +13411,7 @@
37.13616  msgstr ""
37.13617  
37.13618  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13619 -#: ../en/ch12-mq.xml:679
37.13620 +#: ../en/ch11-mq.xml:680
37.13621  msgid ""
37.13622  "It's often a good idea to refresh a patch that has applied with an offset or "
37.13623  "fuzz factor; refreshing the patch generates new context information that will "
37.13624 @@ -14339,12 +13424,12 @@
37.13625  msgstr ""
37.13626  
37.13627  #. type: Content of: <book><chapter><sect1><sect2><title>
37.13628 -#: ../en/ch12-mq.xml:692
37.13629 +#: ../en/ch11-mq.xml:693
37.13630  msgid "Handling rejection"
37.13631  msgstr "处理拒绝"
37.13632  
37.13633  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13634 -#: ../en/ch12-mq.xml:694
37.13635 +#: ../en/ch11-mq.xml:695
37.13636  msgid ""
37.13637  "If <command role=\"hg-ext-mq\">qpush</command> fails to apply a patch, it "
37.13638  "will print an error message and exit.  If it has left <filename role=\"special"
37.13639 @@ -14353,7 +13438,7 @@
37.13640  msgstr ""
37.13641  
37.13642  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13643 -#: ../en/ch12-mq.xml:700
37.13644 +#: ../en/ch11-mq.xml:701
37.13645  msgid ""
37.13646  "If your patch <emphasis>used to</emphasis> apply cleanly, and no longer does "
37.13647  "because you've changed the underlying code that your patches are based on, "
37.13648 @@ -14362,7 +13447,7 @@
37.13649  msgstr ""
37.13650  
37.13651  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13652 -#: ../en/ch12-mq.xml:706
37.13653 +#: ../en/ch11-mq.xml:707
37.13654  msgid ""
37.13655  "Unfortunately, there aren't any great techniques for dealing with rejected "
37.13656  "hunks.  Most often, you'll need to view the <filename role=\"special\">.rej</"
37.13657 @@ -14370,7 +13455,7 @@
37.13658  msgstr ""
37.13659  
37.13660  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13661 -#: ../en/ch12-mq.xml:711
37.13662 +#: ../en/ch11-mq.xml:712
37.13663  msgid ""
37.13664  "If you're feeling adventurous, Neil Brown, a Linux kernel hacker, wrote a "
37.13665  "tool called <command>wiggle</command> <citation>web:wiggle</citation>, which "
37.13666 @@ -14379,7 +13464,7 @@
37.13667  msgstr ""
37.13668  
37.13669  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13670 -#: ../en/ch12-mq.xml:717
37.13671 +#: ../en/ch11-mq.xml:718
37.13672  msgid ""
37.13673  "Another Linux kernel hacker, Chris Mason (the author of Mercurial Queues), "
37.13674  "wrote a similar tool called <command>mpatch</command> <citation>web:mpatch</"
37.13675 @@ -14389,31 +13474,31 @@
37.13676  msgstr ""
37.13677  
37.13678  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.13679 -#: ../en/ch12-mq.xml:726
37.13680 +#: ../en/ch11-mq.xml:727
37.13681  msgid "The context in the middle of a hunk has changed."
37.13682  msgstr ""
37.13683  
37.13684  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.13685 -#: ../en/ch12-mq.xml:729
37.13686 +#: ../en/ch11-mq.xml:730
37.13687  msgid "A hunk is missing some context at the beginning or end."
37.13688  msgstr ""
37.13689  
37.13690  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.13691 -#: ../en/ch12-mq.xml:732
37.13692 +#: ../en/ch11-mq.xml:733
37.13693  msgid ""
37.13694  "A large hunk might apply better&emdash;either entirely or in part&emdash;if "
37.13695  "it was broken up into smaller hunks."
37.13696  msgstr ""
37.13697  
37.13698  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.13699 -#: ../en/ch12-mq.xml:736
37.13700 +#: ../en/ch11-mq.xml:737
37.13701  msgid ""
37.13702  "A hunk removes lines with slightly different content than those currently "
37.13703  "present in the file."
37.13704  msgstr ""
37.13705  
37.13706  #. type: Content of: <book><chapter><sect1><sect2><para>
37.13707 -#: ../en/ch12-mq.xml:740
37.13708 +#: ../en/ch11-mq.xml:741
37.13709  msgid ""
37.13710  "If you use <command>wiggle</command> or <command>mpatch</command>, you should "
37.13711  "be doubly careful to check your results when you're done.  In fact, "
37.13712 @@ -14423,12 +13508,12 @@
37.13713  msgstr ""
37.13714  
37.13715  #. type: Content of: <book><chapter><sect1><title>
37.13716 -#: ../en/ch12-mq.xml:752
37.13717 +#: ../en/ch11-mq.xml:753
37.13718  msgid "Getting the best performance out of MQ"
37.13719  msgstr "MQ 的性能"
37.13720  
37.13721  #. type: Content of: <book><chapter><sect1><para>
37.13722 -#: ../en/ch12-mq.xml:754
37.13723 +#: ../en/ch11-mq.xml:755
37.13724  msgid ""
37.13725  "MQ is very efficient at handling a large number of patches.  I ran some "
37.13726  "performance experiments in mid-2006 for a talk that I gave at the 2006 "
37.13727 @@ -14439,7 +13524,7 @@
37.13728  msgstr ""
37.13729  
37.13730  #. type: Content of: <book><chapter><sect1><para>
37.13731 -#: ../en/ch12-mq.xml:763
37.13732 +#: ../en/ch11-mq.xml:764
37.13733  msgid ""
37.13734  "On my old, slow laptop, I was able to <command role=\"hg-cmd\">hg qpush "
37.13735  "<option role=\"hg-ext-mq-cmd-qpush-opt\">hg -a</option></command> all 1,738 "
37.13736 @@ -14451,14 +13536,14 @@
37.13737  msgstr ""
37.13738  
37.13739  #. type: Content of: <book><chapter><sect1><para>
37.13740 -#: ../en/ch12-mq.xml:774
37.13741 +#: ../en/ch11-mq.xml:775
37.13742  msgid ""
37.13743  "Clearly, MQ is well suited to working in large trees, but there are a few "
37.13744  "tricks you can use to get the best performance of it."
37.13745  msgstr ""
37.13746  
37.13747  #. type: Content of: <book><chapter><sect1><para>
37.13748 -#: ../en/ch12-mq.xml:778
37.13749 +#: ../en/ch11-mq.xml:779
37.13750  msgid ""
37.13751  "First of all, try to <quote>batch</quote> operations together.  Every time "
37.13752  "you run <command role=\"hg-ext-mq\">qpush</command> or <command role=\"hg-ext-"
37.13753 @@ -14470,7 +13555,7 @@
37.13754  msgstr ""
37.13755  
37.13756  #. type: Content of: <book><chapter><sect1><para>
37.13757 -#: ../en/ch12-mq.xml:789
37.13758 +#: ../en/ch11-mq.xml:790
37.13759  msgid ""
37.13760  "The <command role=\"hg-ext-mq\">qpush</command> and <command role=\"hg-ext-mq"
37.13761  "\">qpop</command> commands allow you to push and pop multiple patches at a "
37.13762 @@ -14482,7 +13567,7 @@
37.13763  msgstr ""
37.13764  
37.13765  #. type: Content of: <book><chapter><sect1><para>
37.13766 -#: ../en/ch12-mq.xml:799
37.13767 +#: ../en/ch11-mq.xml:800
37.13768  msgid ""
37.13769  "You can identify a destination patch using either the name of the patch, or "
37.13770  "by number.  If you use numeric addressing, patches are counted from zero; "
37.13771 @@ -14490,12 +13575,12 @@
37.13772  msgstr ""
37.13773  
37.13774  #. type: Content of: <book><chapter><sect1><title>
37.13775 -#: ../en/ch12-mq.xml:806
37.13776 +#: ../en/ch11-mq.xml:807
37.13777  msgid "Updating your patches when the underlying code changes"
37.13778  msgstr "当基础代码改变时,更新补丁的方法"
37.13779  
37.13780  #. type: Content of: <book><chapter><sect1><para>
37.13781 -#: ../en/ch12-mq.xml:809
37.13782 +#: ../en/ch11-mq.xml:810
37.13783  msgid ""
37.13784  "It's common to have a stack of patches on top of an underlying repository "
37.13785  "that you don't modify directly.  If you're working on changes to third-party "
37.13786 @@ -14506,7 +13591,7 @@
37.13787  msgstr ""
37.13788  
37.13789  #. type: Content of: <book><chapter><sect1><para>
37.13790 -#: ../en/ch12-mq.xml:818
37.13791 +#: ../en/ch11-mq.xml:819
37.13792  msgid ""
37.13793  "The simplest way to do this is to <command role=\"hg-cmd\">hg qpop <option "
37.13794  "role=\"hg-ext-mq-cmd-qpop-opt\">hg -a</option></command> your patches, then "
37.13795 @@ -14520,7 +13605,7 @@
37.13796  msgstr ""
37.13797  
37.13798  #. type: Content of: <book><chapter><sect1><para>
37.13799 -#: ../en/ch12-mq.xml:830
37.13800 +#: ../en/ch11-mq.xml:831
37.13801  msgid ""
37.13802  "This approach is easy to use and works well if you don't expect changes to "
37.13803  "the underlying code to affect how well your patches apply. If your patch "
37.13804 @@ -14530,7 +13615,7 @@
37.13805  msgstr ""
37.13806  
37.13807  #. type: Content of: <book><chapter><sect1><para>
37.13808 -#: ../en/ch12-mq.xml:837
37.13809 +#: ../en/ch11-mq.xml:838
37.13810  msgid ""
37.13811  "It's possible to partially automate the rebasing process.  If your patches "
37.13812  "apply cleanly against some revision of the underlying repo, MQ can use this "
37.13813 @@ -14539,19 +13624,19 @@
37.13814  msgstr ""
37.13815  
37.13816  #. type: Content of: <book><chapter><sect1><para>
37.13817 -#: ../en/ch12-mq.xml:843
37.13818 +#: ../en/ch11-mq.xml:844
37.13819  msgid "The process is a little involved."
37.13820  msgstr ""
37.13821  
37.13822  #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
37.13823 -#: ../en/ch12-mq.xml:845
37.13824 +#: ../en/ch11-mq.xml:846
37.13825  msgid ""
37.13826  "To begin, <command role=\"hg-cmd\">hg qpush -a</command> all of your patches "
37.13827  "on top of the revision where you know that they apply cleanly."
37.13828  msgstr ""
37.13829  
37.13830  #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
37.13831 -#: ../en/ch12-mq.xml:849
37.13832 +#: ../en/ch11-mq.xml:850
37.13833  msgid ""
37.13834  "Save a backup copy of your patch directory using <command role=\"hg-cmd\">hg "
37.13835  "qsave <option role=\"hg-ext-mq-cmd-qsave-opt\">hg -e</option> <option role="
37.13836 @@ -14566,7 +13651,7 @@
37.13837  msgstr ""
37.13838  
37.13839  #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
37.13840 -#: ../en/ch12-mq.xml:863
37.13841 +#: ../en/ch11-mq.xml:864
37.13842  msgid ""
37.13843  "Use <command role=\"hg-cmd\">hg pull</command> to bring new changes into the "
37.13844  "underlying repository.  (Don't run <command role=\"hg-cmd\">hg pull -u</"
37.13845 @@ -14574,7 +13659,7 @@
37.13846  msgstr ""
37.13847  
37.13848  #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
37.13849 -#: ../en/ch12-mq.xml:868
37.13850 +#: ../en/ch11-mq.xml:869
37.13851  msgid ""
37.13852  "Update to the new tip revision, using <command role=\"hg-cmd\">hg update "
37.13853  "<option role=\"hg-opt-update\">-C</option></command> to override the patches "
37.13854 @@ -14582,17 +13667,16 @@
37.13855  msgstr ""
37.13856  
37.13857  #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
37.13858 -#: ../en/ch12-mq.xml:873
37.13859 -msgid ""
37.13860 -"Merge all patches using \\hgcmdargs{qpush}{<option role=\"hg-ext-mq-cmd-qpush-"
37.13861 -"opt\">hg -m</option> <option role=\"hg-ext-mq-cmd-qpush-opt\">hg -a</"
37.13862 -"option>}.  The <option role=\"hg-ext-mq-cmd-qpush-opt\">hg -m</option> option "
37.13863 -"to <command role=\"hg-ext-mq\">qpush</command> tells MQ to perform a three-"
37.13864 -"way merge if the patch fails to apply."
37.13865 -msgstr ""
37.13866 -
37.13867 -#. type: Content of: <book><chapter><sect1><para>
37.13868 -#: ../en/ch12-mq.xml:883
37.13869 +#: ../en/ch11-mq.xml:874
37.13870 +msgid ""
37.13871 +"Merge all patches using <command>hg qpush -m -a</command>.  The <option role="
37.13872 +"\"hg-ext-mq-cmd-qpush-opt\">-m</option> option to <command role=\"hg-ext-mq"
37.13873 +"\">qpush</command> tells MQ to perform a three-way merge if the patch fails "
37.13874 +"to apply."
37.13875 +msgstr ""
37.13876 +
37.13877 +#. type: Content of: <book><chapter><sect1><para>
37.13878 +#: ../en/ch11-mq.xml:882
37.13879  msgid ""
37.13880  "During the <command role=\"hg-cmd\">hg qpush <option role=\"hg-ext-mq-cmd-"
37.13881  "qpush-opt\">hg -m</option></command>, each patch in the <filename role="
37.13882 @@ -14604,14 +13688,14 @@
37.13883  msgstr ""
37.13884  
37.13885  #. type: Content of: <book><chapter><sect1><para>
37.13886 -#: ../en/ch12-mq.xml:893
37.13887 +#: ../en/ch11-mq.xml:892
37.13888  msgid ""
37.13889  "When you finish resolving the effects of a patch, MQ refreshes your patch "
37.13890  "based on the result of the merge."
37.13891  msgstr ""
37.13892  
37.13893  #. type: Content of: <book><chapter><sect1><para>
37.13894 -#: ../en/ch12-mq.xml:896
37.13895 +#: ../en/ch11-mq.xml:895
37.13896  msgid ""
37.13897  "At the end of this process, your repository will have one extra head from the "
37.13898  "old patch queue, and a copy of the old patch queue will be in <filename role="
37.13899 @@ -14623,12 +13707,12 @@
37.13900  msgstr ""
37.13901  
37.13902  #. type: Content of: <book><chapter><sect1><title>
37.13903 -#: ../en/ch12-mq.xml:908
37.13904 +#: ../en/ch11-mq.xml:907
37.13905  msgid "Identifying patches"
37.13906  msgstr "标识补丁"
37.13907  
37.13908  #. type: Content of: <book><chapter><sect1><para>
37.13909 -#: ../en/ch12-mq.xml:910
37.13910 +#: ../en/ch11-mq.xml:909
37.13911  msgid ""
37.13912  "MQ commands that work with patches let you refer to a patch either by using "
37.13913  "its name or by a number.  By name is obvious enough; pass the name "
37.13914 @@ -14638,7 +13722,7 @@
37.13915  msgstr ""
37.13916  
37.13917  #. type: Content of: <book><chapter><sect1><para>
37.13918 -#: ../en/ch12-mq.xml:917
37.13919 +#: ../en/ch11-mq.xml:916
37.13920  msgid ""
37.13921  "As a shortcut, you can refer to a patch using both a name and a numeric "
37.13922  "offset; <literal>foo.patch-2</literal> means <quote>two patches before "
37.13923 @@ -14647,7 +13731,7 @@
37.13924  msgstr ""
37.13925  
37.13926  #. type: Content of: <book><chapter><sect1><para>
37.13927 -#: ../en/ch12-mq.xml:923
37.13928 +#: ../en/ch11-mq.xml:922
37.13929  msgid ""
37.13930  "Referring to a patch by index isn't much different.  The first patch printed "
37.13931  "in the output of <command role=\"hg-ext-mq\">qseries</command> is patch zero "
37.13932 @@ -14656,51 +13740,45 @@
37.13933  msgstr ""
37.13934  
37.13935  #. type: Content of: <book><chapter><sect1><para>
37.13936 -#: ../en/ch12-mq.xml:929
37.13937 +#: ../en/ch11-mq.xml:928
37.13938  msgid ""
37.13939  "MQ also makes it easy to work with patches when you are using normal "
37.13940  "Mercurial commands.  Every command that accepts a changeset ID will also "
37.13941  "accept the name of an applied patch.  MQ augments the tags normally in the "
37.13942  "repository with an eponymous one for each applied patch.  In addition, the "
37.13943 -"special tags \\index{tags!special tag names!<literal>qbase</literal>}"
37.13944 -"<literal>qbase</literal> and \\index{tags!special tag names!<literal>qtip</"
37.13945 -"literal>}<literal>qtip</literal> identify the <quote>bottom-most</quote> and "
37.13946 -"topmost applied patches, respectively."
37.13947 -msgstr ""
37.13948 -
37.13949 -#. type: Content of: <book><chapter><sect1><para>
37.13950 -#: ../en/ch12-mq.xml:941
37.13951 +"special tags <literal role=\"tag\">qbase</literal> and <literal role=\"tag"
37.13952 +"\">qtip</literal> identify the <quote>bottom-most</quote> and topmost applied "
37.13953 +"patches, respectively."
37.13954 +msgstr ""
37.13955 +
37.13956 +#. type: Content of: <book><chapter><sect1><para>
37.13957 +#: ../en/ch11-mq.xml:938
37.13958  msgid ""
37.13959  "These additions to Mercurial's normal tagging capabilities make dealing with "
37.13960  "patches even more of a breeze."
37.13961  msgstr ""
37.13962  
37.13963  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.13964 -#: ../en/ch12-mq.xml:944
37.13965 +#: ../en/ch11-mq.xml:941
37.13966  msgid "Want to patchbomb a mailing list with your latest series of changes?"
37.13967  msgstr ""
37.13968  
37.13969  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.13970 -#: ../en/ch12-mq.xml:948
37.13971 +#: ../en/ch11-mq.xml:944
37.13972  msgid ""
37.13973  "(Don't know what <quote>patchbombing</quote> is? See section <xref linkend="
37.13974  "\"sec.hgext.patchbomb\"/>.)"
37.13975  msgstr ""
37.13976  
37.13977  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.13978 -#: ../en/ch12-mq.xml:951
37.13979 +#: ../en/ch11-mq.xml:947
37.13980  msgid ""
37.13981  "Need to see all of the patches since <literal>foo.patch</literal> that have "
37.13982  "touched files in a subdirectory of your tree?"
37.13983  msgstr ""
37.13984  
37.13985 -#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><programlisting><emphasis>
37.13986 -#: ../en/ch12-mq.xml:955
37.13987 -msgid "subdir"
37.13988 -msgstr ""
37.13989 -
37.13990 -#. type: Content of: <book><chapter><sect1><para>
37.13991 -#: ../en/ch12-mq.xml:960
37.13992 +#. type: Content of: <book><chapter><sect1><para>
37.13993 +#: ../en/ch11-mq.xml:954
37.13994  msgid ""
37.13995  "Because MQ makes the names of patches available to the rest of Mercurial "
37.13996  "through its normal internal tag machinery, you don't need to type in the "
37.13997 @@ -14708,7 +13786,7 @@
37.13998  msgstr ""
37.13999  
37.14000  #. type: Content of: <book><chapter><sect1><para>
37.14001 -#: ../en/ch12-mq.xml:965
37.14002 +#: ../en/ch11-mq.xml:959
37.14003  msgid ""
37.14004  "Another nice consequence of representing patch names as tags is that when you "
37.14005  "run the <command role=\"hg-cmd\">hg log</command> command, it will display a "
37.14006 @@ -14719,19 +13797,19 @@
37.14007  msgstr ""
37.14008  
37.14009  #. type: Content of: <book><chapter><sect1><title>
37.14010 -#: ../en/ch12-mq.xml:978
37.14011 +#: ../en/ch11-mq.xml:972
37.14012  msgid "Useful things to know about"
37.14013  msgstr "其它需要了解的东西"
37.14014  
37.14015  #. type: Content of: <book><chapter><sect1><para>
37.14016 -#: ../en/ch12-mq.xml:980
37.14017 +#: ../en/ch11-mq.xml:974
37.14018  msgid ""
37.14019  "There are a number of aspects of MQ usage that don't fit tidily into sections "
37.14020  "of their own, but that are good to know.  Here they are, in one place."
37.14021  msgstr ""
37.14022  
37.14023  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.14024 -#: ../en/ch12-mq.xml:985
37.14025 +#: ../en/ch11-mq.xml:979
37.14026  msgid ""
37.14027  "Normally, when you <command role=\"hg-ext-mq\">qpop</command> a patch and "
37.14028  "<command role=\"hg-ext-mq\">qpush</command> it again, the changeset that "
37.14029 @@ -14742,7 +13820,7 @@
37.14030  msgstr ""
37.14031  
37.14032  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.14033 -#: ../en/ch12-mq.xml:994
37.14034 +#: ../en/ch11-mq.xml:988
37.14035  msgid ""
37.14036  "It's not a good idea to <command role=\"hg-cmd\">hg merge</command> changes "
37.14037  "from another branch with a patch changeset, at least if you want to maintain "
37.14038 @@ -14752,12 +13830,12 @@
37.14039  msgstr ""
37.14040  
37.14041  #. type: Content of: <book><chapter><sect1><title>
37.14042 -#: ../en/ch12-mq.xml:1005
37.14043 +#: ../en/ch11-mq.xml:999
37.14044  msgid "Managing patches in a repository"
37.14045  msgstr "在版本库管理补丁"
37.14046  
37.14047  #. type: Content of: <book><chapter><sect1><para>
37.14048 -#: ../en/ch12-mq.xml:1007
37.14049 +#: ../en/ch11-mq.xml:1001
37.14050  msgid ""
37.14051  "Because MQ's <filename role=\"special\" class=\"directory\">.hg/patches</"
37.14052  "filename> directory resides outside a Mercurial repository's working "
37.14053 @@ -14766,7 +13844,7 @@
37.14054  msgstr ""
37.14055  
37.14056  #. type: Content of: <book><chapter><sect1><para>
37.14057 -#: ../en/ch12-mq.xml:1013
37.14058 +#: ../en/ch11-mq.xml:1007
37.14059  msgid ""
37.14060  "This presents the interesting possibility of managing the contents of the "
37.14061  "patch directory as a Mercurial repository in its own right.  This can be a "
37.14062 @@ -14777,7 +13855,7 @@
37.14063  msgstr ""
37.14064  
37.14065  #. type: Content of: <book><chapter><sect1><para>
37.14066 -#: ../en/ch12-mq.xml:1022
37.14067 +#: ../en/ch11-mq.xml:1016
37.14068  msgid ""
37.14069  "You can then share different versions of the same patch stack among multiple "
37.14070  "underlying repositories.  I use this when I am developing a Linux kernel "
37.14071 @@ -14789,7 +13867,7 @@
37.14072  msgstr ""
37.14073  
37.14074  #. type: Content of: <book><chapter><sect1><para>
37.14075 -#: ../en/ch12-mq.xml:1032
37.14076 +#: ../en/ch11-mq.xml:1026
37.14077  msgid ""
37.14078  "Managing patches in a repository makes it possible for multiple developers to "
37.14079  "work on the same patch series without colliding with each other, all on top "
37.14080 @@ -14797,12 +13875,12 @@
37.14081  msgstr ""
37.14082  
37.14083  #. type: Content of: <book><chapter><sect1><sect2><title>
37.14084 -#: ../en/ch12-mq.xml:1038
37.14085 +#: ../en/ch11-mq.xml:1032
37.14086  msgid "MQ support for patch repositories"
37.14087  msgstr "MQ 支持补丁版本库"
37.14088  
37.14089  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14090 -#: ../en/ch12-mq.xml:1040
37.14091 +#: ../en/ch11-mq.xml:1034
37.14092  msgid ""
37.14093  "MQ helps you to work with the <filename role=\"special\" class=\"directory\">."
37.14094  "hg/patches</filename> directory as a repository; when you prepare a "
37.14095 @@ -14813,7 +13891,7 @@
37.14096  msgstr ""
37.14097  
37.14098  #. type: Content of: <book><chapter><sect1><sect2><note><para>
37.14099 -#: ../en/ch12-mq.xml:1050
37.14100 +#: ../en/ch11-mq.xml:1044
37.14101  msgid ""
37.14102  "If you forget to use the <option role=\"hg-ext-mq-cmd-qinit-opt\">hg -c</"
37.14103  "option> option, you can simply go into the <filename role=\"special\" class="
37.14104 @@ -14824,7 +13902,7 @@
37.14105  msgstr ""
37.14106  
37.14107  #. type: Content of: <book><chapter><sect1><sect2><note><para>
37.14108 -#: ../en/ch12-mq.xml:1059
37.14109 +#: ../en/ch11-mq.xml:1053
37.14110  msgid ""
37.14111  "(<command role=\"hg-cmd\">hg qinit <option role=\"hg-ext-mq-cmd-qinit-opt"
37.14112  "\">hg -c</option></command> does this for you automatically); you "
37.14113 @@ -14833,7 +13911,7 @@
37.14114  msgstr ""
37.14115  
37.14116  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14117 -#: ../en/ch12-mq.xml:1066
37.14118 +#: ../en/ch11-mq.xml:1060
37.14119  msgid ""
37.14120  "As a convenience, if MQ notices that the <filename class=\"directory\">.hg/"
37.14121  "patches</filename> directory is a repository, it will automatically <command "
37.14122 @@ -14841,7 +13919,7 @@
37.14123  msgstr ""
37.14124  
37.14125  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14126 -#: ../en/ch12-mq.xml:1071
37.14127 +#: ../en/ch11-mq.xml:1065
37.14128  msgid ""
37.14129  "MQ provides a shortcut command, <command role=\"hg-ext-mq\">qcommit</"
37.14130  "command>, that runs <command role=\"hg-cmd\">hg commit</command> in the "
37.14131 @@ -14850,7 +13928,7 @@
37.14132  msgstr ""
37.14133  
37.14134  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14135 -#: ../en/ch12-mq.xml:1077
37.14136 +#: ../en/ch11-mq.xml:1071
37.14137  msgid ""
37.14138  "Finally, as a convenience to manage the patch directory, you can define the "
37.14139  "alias <command>mq</command> on Unix systems. For example, on Linux systems "
37.14140 @@ -14859,26 +13937,26 @@
37.14141  msgstr ""
37.14142  
37.14143  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14144 -#: ../en/ch12-mq.xml:1087
37.14145 +#: ../en/ch11-mq.xml:1080
37.14146  msgid ""
37.14147  "You can then issue commands of the form <command>mq pull</command> from the "
37.14148  "main repository."
37.14149  msgstr ""
37.14150  
37.14151  #. type: Content of: <book><chapter><sect1><sect2><title>
37.14152 -#: ../en/ch12-mq.xml:1092
37.14153 +#: ../en/ch11-mq.xml:1085
37.14154  msgid "A few things to watch out for"
37.14155  msgstr "需要注意的事情"
37.14156  
37.14157  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14158 -#: ../en/ch12-mq.xml:1094
37.14159 +#: ../en/ch11-mq.xml:1087
37.14160  msgid ""
37.14161  "MQ's support for working with a repository full of patches is limited in a "
37.14162  "few small respects."
37.14163  msgstr ""
37.14164  
37.14165  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14166 -#: ../en/ch12-mq.xml:1097
37.14167 +#: ../en/ch11-mq.xml:1090
37.14168  msgid ""
37.14169  "MQ cannot automatically detect changes that you make to the patch directory.  "
37.14170  "If you <command role=\"hg-cmd\">hg pull</command>, manually edit, or <command "
37.14171 @@ -14892,12 +13970,12 @@
37.14172  msgstr ""
37.14173  
37.14174  #. type: Content of: <book><chapter><sect1><title>
37.14175 -#: ../en/ch12-mq.xml:1113
37.14176 +#: ../en/ch11-mq.xml:1106
37.14177  msgid "Third party tools for working with patches"
37.14178  msgstr "操作补丁的第三方工具"
37.14179  
37.14180  #. type: Content of: <book><chapter><sect1><para>
37.14181 -#: ../en/ch12-mq.xml:1115
37.14182 +#: ../en/ch11-mq.xml:1108
37.14183  msgid ""
37.14184  "Once you've been working with patches for a while, you'll find yourself "
37.14185  "hungry for tools that will help you to understand and manipulate the patches "
37.14186 @@ -14905,7 +13983,7 @@
37.14187  msgstr ""
37.14188  
37.14189  #. type: Content of: <book><chapter><sect1><para>
37.14190 -#: ../en/ch12-mq.xml:1119
37.14191 +#: ../en/ch11-mq.xml:1112
37.14192  msgid ""
37.14193  "The <command>diffstat</command> command <citation>web:diffstat</citation> "
37.14194  "generates a histogram of the modifications made to each file in a patch.  It "
37.14195 @@ -14918,7 +13996,7 @@
37.14196  msgstr ""
37.14197  
37.14198  #. type: Content of: <book><chapter><sect1><para>
37.14199 -#: ../en/ch12-mq.xml:1133
37.14200 +#: ../en/ch11-mq.xml:1126
37.14201  msgid ""
37.14202  "The <literal role=\"package\">patchutils</literal> package <citation>web:"
37.14203  "patchutils</citation> is invaluable. It provides a set of small utilities "
37.14204 @@ -14933,12 +14011,12 @@
37.14205  msgstr ""
37.14206  
37.14207  #. type: Content of: <book><chapter><sect1><title>
37.14208 -#: ../en/ch12-mq.xml:1149
37.14209 +#: ../en/ch11-mq.xml:1142
37.14210  msgid "Good ways to work with patches"
37.14211  msgstr "操作补丁的好习惯"
37.14212  
37.14213  #. type: Content of: <book><chapter><sect1><para>
37.14214 -#: ../en/ch12-mq.xml:1151
37.14215 +#: ../en/ch11-mq.xml:1144
37.14216  msgid ""
37.14217  "Whether you are working on a patch series to submit to a free software or "
37.14218  "open source project, or a series that you intend to treat as a sequence of "
37.14219 @@ -14947,7 +14025,7 @@
37.14220  msgstr ""
37.14221  
37.14222  #. type: Content of: <book><chapter><sect1><para>
37.14223 -#: ../en/ch12-mq.xml:1157
37.14224 +#: ../en/ch11-mq.xml:1150
37.14225  msgid ""
37.14226  "Give your patches descriptive names.  A good name for a patch might be "
37.14227  "<filename>rework-device-alloc.patch</filename>, because it will immediately "
37.14228 @@ -14961,7 +14039,7 @@
37.14229  msgstr ""
37.14230  
37.14231  #. type: Content of: <book><chapter><sect1><para>
37.14232 -#: ../en/ch12-mq.xml:1169
37.14233 +#: ../en/ch11-mq.xml:1162
37.14234  msgid ""
37.14235  "Be aware of what patch you're working on.  Use the <command role=\"hg-ext-mq"
37.14236  "\">qtop</command> command and skim over the text of your patches "
37.14237 @@ -14974,7 +14052,7 @@
37.14238  msgstr ""
37.14239  
37.14240  #. type: Content of: <book><chapter><sect1><para>
37.14241 -#: ../en/ch12-mq.xml:1179
37.14242 +#: ../en/ch11-mq.xml:1172
37.14243  msgid ""
37.14244  "For this reason, it is very much worth investing a little time to learn how "
37.14245  "to use some of the third-party tools I described in section <xref linkend="
37.14246 @@ -14985,17 +14063,17 @@
37.14247  msgstr ""
37.14248  
37.14249  #. type: Content of: <book><chapter><sect1><title>
37.14250 -#: ../en/ch12-mq.xml:1190
37.14251 +#: ../en/ch11-mq.xml:1183
37.14252  msgid "MQ cookbook"
37.14253  msgstr "MQ 手册"
37.14254  
37.14255  #. type: Content of: <book><chapter><sect1><sect2><title>
37.14256 -#: ../en/ch12-mq.xml:1193
37.14257 +#: ../en/ch11-mq.xml:1186
37.14258  msgid "Manage <quote>trivial</quote> patches"
37.14259  msgstr "管理<quote>琐碎的</quote>补丁"
37.14260  
37.14261  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14262 -#: ../en/ch12-mq.xml:1195
37.14263 +#: ../en/ch11-mq.xml:1188
37.14264  msgid ""
37.14265  "Because the overhead of dropping files into a new Mercurial repository is so "
37.14266  "low, it makes a lot of sense to manage patches this way even if you simply "
37.14267 @@ -15004,26 +14082,26 @@
37.14268  
37.14269  #
37.14270  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14271 -#: ../en/ch12-mq.xml:1200
37.14272 +#: ../en/ch11-mq.xml:1193
37.14273  msgid ""
37.14274  "Begin by downloading and unpacking the source tarball, and turning it into a "
37.14275  "Mercurial repository."
37.14276  msgstr ""
37.14277  
37.14278  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14279 -#: ../en/ch12-mq.xml:1205
37.14280 +#: ../en/ch11-mq.xml:1198
37.14281  msgid "Continue by creating a patch stack and making your changes."
37.14282  msgstr ""
37.14283  
37.14284  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14285 -#: ../en/ch12-mq.xml:1210
37.14286 +#: ../en/ch11-mq.xml:1203
37.14287  msgid ""
37.14288  "Let's say a few weeks or months pass, and your package author releases a new "
37.14289  "version.  First, bring their changes into the repository."
37.14290  msgstr ""
37.14291  
37.14292  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14293 -#: ../en/ch12-mq.xml:1216
37.14294 +#: ../en/ch11-mq.xml:1209
37.14295  msgid ""
37.14296  "The pipeline starting with <command role=\"hg-cmd\">hg locate</command> above "
37.14297  "deletes all files in the working directory, so that <command role=\"hg-cmd"
37.14298 @@ -15033,17 +14111,17 @@
37.14299  msgstr ""
37.14300  
37.14301  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14302 -#: ../en/ch12-mq.xml:1224
37.14303 +#: ../en/ch11-mq.xml:1217
37.14304  msgid "Finally, you can apply your patches on top of the new tree."
37.14305  msgstr ""
37.14306  
37.14307  #. type: Content of: <book><chapter><sect1><sect2><title>
37.14308 -#: ../en/ch12-mq.xml:1231
37.14309 +#: ../en/ch11-mq.xml:1224
37.14310  msgid "Combining entire patches"
37.14311  msgstr "组合全部的补丁"
37.14312  
37.14313  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14314 -#: ../en/ch12-mq.xml:1233
37.14315 +#: ../en/ch11-mq.xml:1226
37.14316  msgid ""
37.14317  "MQ provides a command, <command role=\"hg-ext-mq\">qfold</command> that lets "
37.14318  "you combine entire patches.  This <quote>folds</quote> the patches you name, "
37.14319 @@ -15053,7 +14131,7 @@
37.14320  msgstr ""
37.14321  
37.14322  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14323 -#: ../en/ch12-mq.xml:1241
37.14324 +#: ../en/ch11-mq.xml:1234
37.14325  msgid ""
37.14326  "The order in which you fold patches matters.  If your topmost applied patch "
37.14327  "is <literal>foo</literal>, and you <command role=\"hg-ext-mq\">qfold</"
37.14328 @@ -15064,19 +14142,19 @@
37.14329  msgstr ""
37.14330  
37.14331  #. type: Content of: <book><chapter><sect1><sect2><title>
37.14332 -#: ../en/ch12-mq.xml:1252
37.14333 +#: ../en/ch11-mq.xml:1245
37.14334  msgid "Merging part of one patch into another"
37.14335  msgstr "合并补丁的部分内容到其它补丁"
37.14336  
37.14337  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14338 -#: ../en/ch12-mq.xml:1254
37.14339 +#: ../en/ch11-mq.xml:1247
37.14340  msgid ""
37.14341  "Merging <emphasis>part</emphasis> of one patch into another is more difficult "
37.14342  "than combining entire patches."
37.14343  msgstr ""
37.14344  
37.14345  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14346 -#: ../en/ch12-mq.xml:1258
37.14347 +#: ../en/ch11-mq.xml:1251
37.14348  msgid ""
37.14349  "If you want to move changes to entire files, you can use <command>filterdiff</"
37.14350  "command>'s <option role=\"cmd-opt-filterdiff\">-i</option> and <option role="
37.14351 @@ -15090,7 +14168,7 @@
37.14352  msgstr ""
37.14353  
37.14354  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14355 -#: ../en/ch12-mq.xml:1271
37.14356 +#: ../en/ch11-mq.xml:1264
37.14357  msgid ""
37.14358  "If you have a patch that has multiple hunks modifying a file, and you only "
37.14359  "want to move a few of those hunks, the job becomes more messy, but you can "
37.14360 @@ -15099,32 +14177,32 @@
37.14361  msgstr ""
37.14362  
37.14363  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14364 -#: ../en/ch12-mq.xml:1279
37.14365 +#: ../en/ch11-mq.xml:1272
37.14366  msgid "This command prints three different kinds of number:"
37.14367  msgstr ""
37.14368  
37.14369  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.14370 -#: ../en/ch12-mq.xml:1282
37.14371 +#: ../en/ch11-mq.xml:1275
37.14372  msgid ""
37.14373  "(in the first column) a <emphasis>file number</emphasis> to identify each "
37.14374  "file modified in the patch;"
37.14375  msgstr ""
37.14376  
37.14377  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.14378 -#: ../en/ch12-mq.xml:1286
37.14379 +#: ../en/ch11-mq.xml:1279
37.14380  msgid ""
37.14381  "(on the next line, indented) the line number within a modified file where a "
37.14382  "hunk starts; and"
37.14383  msgstr ""
37.14384  
37.14385  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.14386 -#: ../en/ch12-mq.xml:1289
37.14387 +#: ../en/ch11-mq.xml:1282
37.14388  msgid ""
37.14389  "(on the same line) a <emphasis>hunk number</emphasis> to identify that hunk."
37.14390  msgstr ""
37.14391  
37.14392  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14393 -#: ../en/ch12-mq.xml:1293
37.14394 +#: ../en/ch11-mq.xml:1286
37.14395  msgid ""
37.14396  "You'll have to use some visual inspection, and reading of the patch, to "
37.14397  "identify the file and hunk numbers you'll want, but you can then pass them to "
37.14398 @@ -15134,7 +14212,7 @@
37.14399  msgstr ""
37.14400  
37.14401  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14402 -#: ../en/ch12-mq.xml:1301
37.14403 +#: ../en/ch11-mq.xml:1294
37.14404  msgid ""
37.14405  "Once you have this hunk, you can concatenate it onto the end of your "
37.14406  "destination patch and continue with the remainder of section <xref linkend="
37.14407 @@ -15142,19 +14220,19 @@
37.14408  msgstr ""
37.14409  
37.14410  #. type: Content of: <book><chapter><sect1><title>
37.14411 -#: ../en/ch12-mq.xml:1308
37.14412 +#: ../en/ch11-mq.xml:1301
37.14413  msgid "Differences between quilt and MQ"
37.14414  msgstr "MQ 与 quilt 的区别"
37.14415  
37.14416  #. type: Content of: <book><chapter><sect1><para>
37.14417 -#: ../en/ch12-mq.xml:1310
37.14418 +#: ../en/ch11-mq.xml:1303
37.14419  msgid ""
37.14420  "If you are already familiar with quilt, MQ provides a similar command set.  "
37.14421  "There are a few differences in the way that it works."
37.14422  msgstr ""
37.14423  
37.14424  #. type: Content of: <book><chapter><sect1><para>
37.14425 -#: ../en/ch12-mq.xml:1314
37.14426 +#: ../en/ch11-mq.xml:1307
37.14427  msgid ""
37.14428  "You will already have noticed that most quilt commands have MQ counterparts "
37.14429  "that simply begin with a <quote><literal>q</literal></quote>.  The exceptions "
37.14430 @@ -15166,12 +14244,12 @@
37.14431  msgstr ""
37.14432  
37.14433  #. type: Content of: <book><chapter><title>
37.14434 -#: ../en/ch13-mq-collab.xml:5
37.14435 +#: ../en/ch12-mq-collab.xml:5
37.14436  msgid "Advanced uses of Mercurial Queues"
37.14437  msgstr "MQ 的高级用法"
37.14438  
37.14439  #. type: Content of: <book><chapter><para>
37.14440 -#: ../en/ch13-mq-collab.xml:7
37.14441 +#: ../en/ch12-mq-collab.xml:7
37.14442  msgid ""
37.14443  "While it's easy to pick up straightforward uses of Mercurial Queues, use of a "
37.14444  "little discipline and some of MQ's less frequently used capabilities makes it "
37.14445 @@ -15179,7 +14257,7 @@
37.14446  msgstr ""
37.14447  
37.14448  #. type: Content of: <book><chapter><para>
37.14449 -#: ../en/ch13-mq-collab.xml:12
37.14450 +#: ../en/ch12-mq-collab.xml:12
37.14451  msgid ""
37.14452  "In this chapter, I will use as an example a technique I have used to manage "
37.14453  "the development of an Infiniband device driver for the Linux kernel.  The "
37.14454 @@ -15189,7 +14267,7 @@
37.14455  msgstr ""
37.14456  
37.14457  #. type: Content of: <book><chapter><para>
37.14458 -#: ../en/ch13-mq-collab.xml:18
37.14459 +#: ../en/ch12-mq-collab.xml:18
37.14460  msgid ""
37.14461  "While much of the material in this chapter is specific to Linux, the same "
37.14462  "principles apply to any code base for which you're not the primary owner, and "
37.14463 @@ -15197,12 +14275,12 @@
37.14464  msgstr ""
37.14465  
37.14466  #. type: Content of: <book><chapter><sect1><title>
37.14467 -#: ../en/ch13-mq-collab.xml:24
37.14468 +#: ../en/ch12-mq-collab.xml:24
37.14469  msgid "The problem of many targets"
37.14470  msgstr "多个目标的问题"
37.14471  
37.14472  #. type: Content of: <book><chapter><sect1><para>
37.14473 -#: ../en/ch13-mq-collab.xml:26
37.14474 +#: ../en/ch12-mq-collab.xml:26
37.14475  msgid ""
37.14476  "The Linux kernel changes rapidly, and has never been internally stable; "
37.14477  "developers frequently make drastic changes between releases. This means that "
37.14478 @@ -15212,14 +14290,14 @@
37.14479  msgstr ""
37.14480  
37.14481  #. type: Content of: <book><chapter><sect1><para>
37.14482 -#: ../en/ch13-mq-collab.xml:33
37.14483 +#: ../en/ch12-mq-collab.xml:33
37.14484  msgid ""
37.14485  "To maintain a driver, we have to keep a number of distinct versions of Linux "
37.14486  "in mind."
37.14487  msgstr ""
37.14488  
37.14489  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.14490 -#: ../en/ch13-mq-collab.xml:36
37.14491 +#: ../en/ch12-mq-collab.xml:36
37.14492  msgid ""
37.14493  "One target is the main Linux kernel development tree. Maintenance of the code "
37.14494  "is in this case partly shared by other developers in the kernel community, "
37.14495 @@ -15228,7 +14306,7 @@
37.14496  msgstr ""
37.14497  
37.14498  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.14499 -#: ../en/ch13-mq-collab.xml:42
37.14500 +#: ../en/ch12-mq-collab.xml:42
37.14501  msgid ""
37.14502  "We also maintain a number of <quote>backports</quote> to older versions of "
37.14503  "the Linux kernel, to support the needs of customers who are running older "
37.14504 @@ -15239,7 +14317,7 @@
37.14505  msgstr ""
37.14506  
37.14507  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.14508 -#: ../en/ch13-mq-collab.xml:50
37.14509 +#: ../en/ch12-mq-collab.xml:50
37.14510  msgid ""
37.14511  "Finally, we make software releases on a schedule that is necessarily not "
37.14512  "aligned with those used by Linux distributors and kernel developers, so that "
37.14513 @@ -15248,19 +14326,19 @@
37.14514  msgstr ""
37.14515  
37.14516  #. type: Content of: <book><chapter><sect1><sect2><title>
37.14517 -#: ../en/ch13-mq-collab.xml:58
37.14518 +#: ../en/ch12-mq-collab.xml:58
37.14519  msgid "Tempting approaches that don't work well"
37.14520  msgstr "工作不好的诱人方法"
37.14521  
37.14522  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14523 -#: ../en/ch13-mq-collab.xml:60
37.14524 +#: ../en/ch12-mq-collab.xml:60
37.14525  msgid ""
37.14526  "There are two <quote>standard</quote> ways to maintain a piece of software "
37.14527  "that has to target many different environments."
37.14528  msgstr ""
37.14529  
37.14530  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14531 -#: ../en/ch13-mq-collab.xml:64
37.14532 +#: ../en/ch12-mq-collab.xml:64
37.14533  msgid ""
37.14534  "The first is to maintain a number of branches, each intended for a single "
37.14535  "target.  The trouble with this approach is that you must maintain iron "
37.14536 @@ -15272,7 +14350,7 @@
37.14537  msgstr ""
37.14538  
37.14539  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14540 -#: ../en/ch13-mq-collab.xml:74
37.14541 +#: ../en/ch12-mq-collab.xml:74
37.14542  msgid ""
37.14543  "The second is to maintain a single source tree filled with conditional "
37.14544  "statements that turn chunks of code on or off depending on the intended "
37.14545 @@ -15284,7 +14362,7 @@
37.14546  msgstr ""
37.14547  
37.14548  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14549 -#: ../en/ch13-mq-collab.xml:83
37.14550 +#: ../en/ch12-mq-collab.xml:83
37.14551  msgid ""
37.14552  "Neither of these approaches is well suited to a situation where you don't "
37.14553  "<quote>own</quote> the canonical copy of a source tree.  In the case of a "
37.14554 @@ -15296,14 +14374,14 @@
37.14555  msgstr ""
37.14556  
37.14557  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14558 -#: ../en/ch13-mq-collab.xml:93
37.14559 +#: ../en/ch12-mq-collab.xml:93
37.14560  msgid ""
37.14561  "These approaches have the added weakness of making it difficult to generate "
37.14562  "well-formed patches to submit upstream."
37.14563  msgstr ""
37.14564  
37.14565  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14566 -#: ../en/ch13-mq-collab.xml:97
37.14567 +#: ../en/ch12-mq-collab.xml:97
37.14568  msgid ""
37.14569  "In principle, Mercurial Queues seems like a good candidate to manage a "
37.14570  "development scenario such as the above.  While this is indeed the case, MQ "
37.14571 @@ -15311,12 +14389,12 @@
37.14572  msgstr ""
37.14573  
37.14574  #. type: Content of: <book><chapter><sect1><title>
37.14575 -#: ../en/ch13-mq-collab.xml:105
37.14576 +#: ../en/ch12-mq-collab.xml:105
37.14577  msgid "Conditionally applying patches with guards"
37.14578  msgstr "有条件的应用补丁"
37.14579  
37.14580  #. type: Content of: <book><chapter><sect1><para>
37.14581 -#: ../en/ch13-mq-collab.xml:107
37.14582 +#: ../en/ch12-mq-collab.xml:107
37.14583  msgid ""
37.14584  "Perhaps the best way to maintain sanity with so many targets is to be able to "
37.14585  "choose specific patches to apply for a given situation.  MQ provides a "
37.14586 @@ -15326,14 +14404,14 @@
37.14587  msgstr ""
37.14588  
37.14589  #. type: Content of: <book><chapter><sect1><para>
37.14590 -#: ../en/ch13-mq-collab.xml:116
37.14591 +#: ../en/ch12-mq-collab.xml:116
37.14592  msgid ""
37.14593  "This gives us a tiny repository that contains two patches that don't have any "
37.14594  "dependencies on each other, because they touch different files."
37.14595  msgstr ""
37.14596  
37.14597  #. type: Content of: <book><chapter><sect1><para>
37.14598 -#: ../en/ch13-mq-collab.xml:120
37.14599 +#: ../en/ch12-mq-collab.xml:120
37.14600  msgid ""
37.14601  "The idea behind conditional application is that you can <quote>tag</quote> a "
37.14602  "patch with a <emphasis>guard</emphasis>, which is simply a text string of "
37.14603 @@ -15343,7 +14421,7 @@
37.14604  msgstr ""
37.14605  
37.14606  #. type: Content of: <book><chapter><sect1><para>
37.14607 -#: ../en/ch13-mq-collab.xml:127
37.14608 +#: ../en/ch12-mq-collab.xml:127
37.14609  msgid ""
37.14610  "A patch can have an arbitrary number of guards; each one is "
37.14611  "<emphasis>positive</emphasis> (<quote>apply this patch if this guard is "
37.14612 @@ -15352,12 +14430,12 @@
37.14613  msgstr ""
37.14614  
37.14615  #. type: Content of: <book><chapter><sect1><title>
37.14616 -#: ../en/ch13-mq-collab.xml:135
37.14617 +#: ../en/ch12-mq-collab.xml:135
37.14618  msgid "Controlling the guards on a patch"
37.14619  msgstr "控制补丁的应用条件"
37.14620  
37.14621  #. type: Content of: <book><chapter><sect1><para>
37.14622 -#: ../en/ch13-mq-collab.xml:137
37.14623 +#: ../en/ch12-mq-collab.xml:137
37.14624  msgid ""
37.14625  "The <command role=\"hg-ext-mq\">qguard</command> command lets you determine "
37.14626  "which guards should apply to a patch, or display the guards that are already "
37.14627 @@ -15366,21 +14444,21 @@
37.14628  msgstr ""
37.14629  
37.14630  #. type: Content of: <book><chapter><sect1><para>
37.14631 -#: ../en/ch13-mq-collab.xml:144
37.14632 +#: ../en/ch12-mq-collab.xml:144
37.14633  msgid ""
37.14634  "To set a positive guard on a patch, prefix the name of the guard with a "
37.14635  "<quote><literal>+</literal></quote>."
37.14636  msgstr ""
37.14637  
37.14638  #. type: Content of: <book><chapter><sect1><para>
37.14639 -#: ../en/ch13-mq-collab.xml:149
37.14640 +#: ../en/ch12-mq-collab.xml:149
37.14641  msgid ""
37.14642  "To set a negative guard on a patch, prefix the name of the guard with a "
37.14643  "<quote><literal>-</literal></quote>."
37.14644  msgstr ""
37.14645  
37.14646  #. type: Content of: <book><chapter><sect1><note><para>
37.14647 -#: ../en/ch13-mq-collab.xml:156
37.14648 +#: ../en/ch12-mq-collab.xml:156
37.14649  msgid ""
37.14650  "The <command role=\"hg-ext-mq\">qguard</command> command <emphasis>sets</"
37.14651  "emphasis> the guards on a patch; it doesn't <emphasis>modify</emphasis> "
37.14652 @@ -15392,7 +14470,7 @@
37.14653  
37.14654  #
37.14655  #. type: Content of: <book><chapter><sect1><para>
37.14656 -#: ../en/ch13-mq-collab.xml:165
37.14657 +#: ../en/ch12-mq-collab.xml:165
37.14658  msgid ""
37.14659  "Mercurial stores guards in the <filename role=\"special\">series</filename> "
37.14660  "file; the form in which they are stored is easy both to understand and to "
37.14661 @@ -15402,12 +14480,12 @@
37.14662  msgstr ""
37.14663  
37.14664  #. type: Content of: <book><chapter><sect1><title>
37.14665 -#: ../en/ch13-mq-collab.xml:177
37.14666 +#: ../en/ch12-mq-collab.xml:177
37.14667  msgid "Selecting the guards to use"
37.14668  msgstr "选择使用的条件"
37.14669  
37.14670  #. type: Content of: <book><chapter><sect1><para>
37.14671 -#: ../en/ch13-mq-collab.xml:179
37.14672 +#: ../en/ch12-mq-collab.xml:179
37.14673  msgid ""
37.14674  "The <command role=\"hg-ext-mq\">qselect</command> command determines which "
37.14675  "guards are active at a given time.  The effect of this is to determine which "
37.14676 @@ -15417,7 +14495,7 @@
37.14677  msgstr ""
37.14678  
37.14679  #. type: Content of: <book><chapter><sect1><para>
37.14680 -#: ../en/ch13-mq-collab.xml:186
37.14681 +#: ../en/ch12-mq-collab.xml:186
37.14682  msgid ""
37.14683  "With no arguments, the <command role=\"hg-ext-mq\">qselect</command> command "
37.14684  "lists the guards currently in effect, one per line of output.  Each argument "
37.14685 @@ -15425,21 +14503,21 @@
37.14686  msgstr ""
37.14687  
37.14688  #. type: Content of: <book><chapter><sect1><para>
37.14689 -#: ../en/ch13-mq-collab.xml:193
37.14690 +#: ../en/ch12-mq-collab.xml:193
37.14691  msgid ""
37.14692  "In case you're interested, the currently selected guards are stored in the "
37.14693  "<filename role=\"special\">guards</filename> file."
37.14694  msgstr ""
37.14695  
37.14696  #. type: Content of: <book><chapter><sect1><para>
37.14697 -#: ../en/ch13-mq-collab.xml:198
37.14698 +#: ../en/ch12-mq-collab.xml:198
37.14699  msgid ""
37.14700  "We can see the effect the selected guards have when we run <command role=\"hg-"
37.14701  "ext-mq\">qpush</command>."
37.14702  msgstr ""
37.14703  
37.14704  #. type: Content of: <book><chapter><sect1><para>
37.14705 -#: ../en/ch13-mq-collab.xml:203
37.14706 +#: ../en/ch12-mq-collab.xml:203
37.14707  msgid ""
37.14708  "A guard cannot start with a <quote><literal>+</literal></quote> or "
37.14709  "<quote><literal>-</literal></quote> character.  The name of a guard must not "
37.14710 @@ -15448,61 +14526,61 @@
37.14711  msgstr ""
37.14712  
37.14713  #. type: Content of: <book><chapter><sect1><para>
37.14714 -#: ../en/ch13-mq-collab.xml:212
37.14715 +#: ../en/ch12-mq-collab.xml:212
37.14716  msgid "Changing the selected guards changes the patches that are applied."
37.14717  msgstr ""
37.14718  
37.14719  #. type: Content of: <book><chapter><sect1><para>
37.14720 -#: ../en/ch13-mq-collab.xml:217
37.14721 +#: ../en/ch12-mq-collab.xml:217
37.14722  msgid ""
37.14723  "You can see in the example below that negative guards take precedence over "
37.14724  "positive guards."
37.14725  msgstr ""
37.14726  
37.14727  #. type: Content of: <book><chapter><sect1><title>
37.14728 -#: ../en/ch13-mq-collab.xml:224
37.14729 +#: ../en/ch12-mq-collab.xml:224
37.14730  msgid "MQ's rules for applying patches"
37.14731  msgstr "MQ 应用补丁的规则"
37.14732  
37.14733  #. type: Content of: <book><chapter><sect1><para>
37.14734 -#: ../en/ch13-mq-collab.xml:226
37.14735 +#: ../en/ch12-mq-collab.xml:226
37.14736  msgid ""
37.14737  "The rules that MQ uses when deciding whether to apply a patch are as follows."
37.14738  msgstr ""
37.14739  
37.14740  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.14741 -#: ../en/ch13-mq-collab.xml:229
37.14742 +#: ../en/ch12-mq-collab.xml:229
37.14743  msgid "A patch that has no guards is always applied."
37.14744  msgstr ""
37.14745  
37.14746  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.14747 -#: ../en/ch13-mq-collab.xml:232
37.14748 +#: ../en/ch12-mq-collab.xml:232
37.14749  msgid ""
37.14750  "If the patch has any negative guard that matches any currently selected "
37.14751  "guard, the patch is skipped."
37.14752  msgstr ""
37.14753  
37.14754  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.14755 -#: ../en/ch13-mq-collab.xml:235
37.14756 +#: ../en/ch12-mq-collab.xml:235
37.14757  msgid ""
37.14758  "If the patch has any positive guard that matches any currently selected "
37.14759  "guard, the patch is applied."
37.14760  msgstr ""
37.14761  
37.14762  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.14763 -#: ../en/ch13-mq-collab.xml:238
37.14764 +#: ../en/ch12-mq-collab.xml:238
37.14765  msgid ""
37.14766  "If the patch has positive or negative guards, but none matches any currently "
37.14767  "selected guard, the patch is skipped."
37.14768  msgstr ""
37.14769  
37.14770  #. type: Content of: <book><chapter><sect1><title>
37.14771 -#: ../en/ch13-mq-collab.xml:245
37.14772 +#: ../en/ch12-mq-collab.xml:245
37.14773  msgid "Trimming the work environment"
37.14774  msgstr "修剪工作环境"
37.14775  
37.14776  #. type: Content of: <book><chapter><sect1><para>
37.14777 -#: ../en/ch13-mq-collab.xml:247
37.14778 +#: ../en/ch12-mq-collab.xml:247
37.14779  msgid ""
37.14780  "In working on the device driver I mentioned earlier, I don't apply the "
37.14781  "patches to a normal Linux kernel tree.  Instead, I use a repository that "
37.14782 @@ -15512,7 +14590,7 @@
37.14783  msgstr ""
37.14784  
37.14785  #. type: Content of: <book><chapter><sect1><para>
37.14786 -#: ../en/ch13-mq-collab.xml:254
37.14787 +#: ../en/ch12-mq-collab.xml:254
37.14788  msgid ""
37.14789  "I then choose a <quote>base</quote> version on top of which the patches are "
37.14790  "applied.  This is a snapshot of the Linux kernel tree as of a revision of my "
37.14791 @@ -15524,7 +14602,7 @@
37.14792  msgstr ""
37.14793  
37.14794  #. type: Content of: <book><chapter><sect1><para>
37.14795 -#: ../en/ch13-mq-collab.xml:263
37.14796 +#: ../en/ch12-mq-collab.xml:263
37.14797  msgid ""
37.14798  "Normally, the base tree atop which the patches apply should be a snapshot of "
37.14799  "a very recent upstream tree.  This best facilitates the development of "
37.14800 @@ -15532,12 +14610,12 @@
37.14801  msgstr ""
37.14802  
37.14803  #. type: Content of: <book><chapter><sect1><title>
37.14804 -#: ../en/ch13-mq-collab.xml:270
37.14805 +#: ../en/ch12-mq-collab.xml:270
37.14806  msgid "Dividing up the <filename role=\"special\">series</filename> file"
37.14807  msgstr "分类补丁<filename role=\"special\">系列</filename>"
37.14808  
37.14809  #. type: Content of: <book><chapter><sect1><para>
37.14810 -#: ../en/ch13-mq-collab.xml:273
37.14811 +#: ../en/ch12-mq-collab.xml:273
37.14812  msgid ""
37.14813  "I categorise the patches in the <filename role=\"special\">series</filename> "
37.14814  "file into a number of logical groups.  Each section of like patches begins "
37.14815 @@ -15546,14 +14624,14 @@
37.14816  msgstr ""
37.14817  
37.14818  #. type: Content of: <book><chapter><sect1><para>
37.14819 -#: ../en/ch13-mq-collab.xml:279
37.14820 +#: ../en/ch12-mq-collab.xml:279
37.14821  msgid ""
37.14822  "The sequence of patch groups that I maintain follows.  The ordering of these "
37.14823  "groups is important; I'll describe why after I introduce the groups."
37.14824  msgstr ""
37.14825  
37.14826  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.14827 -#: ../en/ch13-mq-collab.xml:283
37.14828 +#: ../en/ch12-mq-collab.xml:283
37.14829  msgid ""
37.14830  "The <quote>accepted</quote> group.  Patches that the development team has "
37.14831  "submitted to the maintainer of the Infiniband subsystem, and which he has "
37.14832 @@ -15564,14 +14642,14 @@
37.14833  msgstr ""
37.14834  
37.14835  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.14836 -#: ../en/ch13-mq-collab.xml:291
37.14837 +#: ../en/ch12-mq-collab.xml:291
37.14838  msgid ""
37.14839  "The <quote>rework</quote> group.  Patches that I have submitted, but that the "
37.14840  "upstream maintainer has requested modifications to before he will accept them."
37.14841  msgstr ""
37.14842  
37.14843  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.14844 -#: ../en/ch13-mq-collab.xml:296
37.14845 +#: ../en/ch12-mq-collab.xml:296
37.14846  msgid ""
37.14847  "The <quote>pending</quote> group.  Patches that I have not yet submitted to "
37.14848  "the upstream maintainer, but which we have finished working on. These will be "
37.14849 @@ -15582,21 +14660,21 @@
37.14850  msgstr ""
37.14851  
37.14852  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.14853 -#: ../en/ch13-mq-collab.xml:305
37.14854 +#: ../en/ch12-mq-collab.xml:305
37.14855  msgid ""
37.14856  "The <quote>in progress</quote> group.  Patches that are actively being "
37.14857  "developed, and should not be submitted anywhere yet."
37.14858  msgstr ""
37.14859  
37.14860  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.14861 -#: ../en/ch13-mq-collab.xml:309
37.14862 +#: ../en/ch12-mq-collab.xml:309
37.14863  msgid ""
37.14864  "The <quote>backport</quote> group.  Patches that adapt the source tree to "
37.14865  "older versions of the kernel tree."
37.14866  msgstr ""
37.14867  
37.14868  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.14869 -#: ../en/ch13-mq-collab.xml:313
37.14870 +#: ../en/ch12-mq-collab.xml:313
37.14871  msgid ""
37.14872  "The <quote>do not ship</quote> group.  Patches that for some reason should "
37.14873  "never be submitted upstream.  For example, one such patch might change "
37.14874 @@ -15606,7 +14684,7 @@
37.14875  msgstr ""
37.14876  
37.14877  #. type: Content of: <book><chapter><sect1><para>
37.14878 -#: ../en/ch13-mq-collab.xml:321
37.14879 +#: ../en/ch12-mq-collab.xml:321
37.14880  msgid ""
37.14881  "Now to return to the reasons for ordering groups of patches in this way.  We "
37.14882  "would like the lowest patches in the stack to be as stable as possible, so "
37.14883 @@ -15616,7 +14694,7 @@
37.14884  msgstr ""
37.14885  
37.14886  #. type: Content of: <book><chapter><sect1><para>
37.14887 -#: ../en/ch13-mq-collab.xml:329
37.14888 +#: ../en/ch12-mq-collab.xml:329
37.14889  msgid ""
37.14890  "We would also like the patches that we know we'll need to modify to be "
37.14891  "applied on top of a source tree that resembles the upstream tree as closely "
37.14892 @@ -15624,7 +14702,7 @@
37.14893  msgstr ""
37.14894  
37.14895  #. type: Content of: <book><chapter><sect1><para>
37.14896 -#: ../en/ch13-mq-collab.xml:334
37.14897 +#: ../en/ch12-mq-collab.xml:334
37.14898  msgid ""
37.14899  "The <quote>backport</quote> and <quote>do not ship</quote> patches float at "
37.14900  "the end of the <filename role=\"special\">series</filename> file.  The "
37.14901 @@ -15633,19 +14711,19 @@
37.14902  msgstr ""
37.14903  
37.14904  #. type: Content of: <book><chapter><sect1><title>
37.14905 -#: ../en/ch13-mq-collab.xml:343
37.14906 +#: ../en/ch12-mq-collab.xml:343
37.14907  msgid "Maintaining the patch series"
37.14908  msgstr "维护补丁系列"
37.14909  
37.14910  #. type: Content of: <book><chapter><sect1><para>
37.14911 -#: ../en/ch13-mq-collab.xml:345
37.14912 +#: ../en/ch12-mq-collab.xml:345
37.14913  msgid ""
37.14914  "In my work, I use a number of guards to control which patches are to be "
37.14915  "applied."
37.14916  msgstr ""
37.14917  
37.14918  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.14919 -#: ../en/ch13-mq-collab.xml:349
37.14920 +#: ../en/ch12-mq-collab.xml:349
37.14921  msgid ""
37.14922  "<quote>Accepted</quote> patches are guarded with <literal>accepted</"
37.14923  "literal>.  I enable this guard most of the time.  When I'm applying the "
37.14924 @@ -15654,7 +14732,7 @@
37.14925  msgstr ""
37.14926  
37.14927  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.14928 -#: ../en/ch13-mq-collab.xml:356
37.14929 +#: ../en/ch12-mq-collab.xml:356
37.14930  msgid ""
37.14931  "Patches that are <quote>finished</quote>, but not yet submitted, have no "
37.14932  "guards.  If I'm applying the patch stack to a copy of the upstream tree, I "
37.14933 @@ -15662,21 +14740,21 @@
37.14934  msgstr ""
37.14935  
37.14936  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.14937 -#: ../en/ch13-mq-collab.xml:362
37.14938 +#: ../en/ch12-mq-collab.xml:362
37.14939  msgid ""
37.14940  "Those patches that need reworking before being resubmitted are guarded with "
37.14941  "<literal>rework</literal>."
37.14942  msgstr ""
37.14943  
37.14944  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.14945 -#: ../en/ch13-mq-collab.xml:366
37.14946 +#: ../en/ch12-mq-collab.xml:366
37.14947  msgid ""
37.14948  "For those patches that are still under development, I use <literal>devel</"
37.14949  "literal>."
37.14950  msgstr ""
37.14951  
37.14952  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.14953 -#: ../en/ch13-mq-collab.xml:369
37.14954 +#: ../en/ch12-mq-collab.xml:369
37.14955  msgid ""
37.14956  "A backport patch may have several guards, one for each version of the kernel "
37.14957  "to which it applies.  For example, a patch that backports a piece of code to "
37.14958 @@ -15684,7 +14762,7 @@
37.14959  msgstr ""
37.14960  
37.14961  #. type: Content of: <book><chapter><sect1><para>
37.14962 -#: ../en/ch13-mq-collab.xml:374
37.14963 +#: ../en/ch12-mq-collab.xml:374
37.14964  msgid ""
37.14965  "This variety of guards gives me considerable flexibility in determining what "
37.14966  "kind of source tree I want to end up with.  For most situations, the "
37.14967 @@ -15693,12 +14771,12 @@
37.14968  msgstr ""
37.14969  
37.14970  #. type: Content of: <book><chapter><sect1><sect2><title>
37.14971 -#: ../en/ch13-mq-collab.xml:381
37.14972 +#: ../en/ch12-mq-collab.xml:381
37.14973  msgid "The art of writing backport patches"
37.14974  msgstr "编写向后移植补丁的艺术"
37.14975  
37.14976  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14977 -#: ../en/ch13-mq-collab.xml:383
37.14978 +#: ../en/ch12-mq-collab.xml:383
37.14979  msgid ""
37.14980  "Using MQ, writing a backport patch is a simple process.  All such a patch has "
37.14981  "to do is modify a piece of code that uses a kernel feature not present in the "
37.14982 @@ -15707,7 +14785,7 @@
37.14983  msgstr ""
37.14984  
37.14985  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14986 -#: ../en/ch13-mq-collab.xml:389
37.14987 +#: ../en/ch12-mq-collab.xml:389
37.14988  msgid ""
37.14989  "A useful goal when writing a good backport patch is to make your code look as "
37.14990  "if it was written for the older version of the kernel you're targeting.  The "
37.14991 @@ -15721,7 +14799,7 @@
37.14992  msgstr ""
37.14993  
37.14994  #. type: Content of: <book><chapter><sect1><sect2><para>
37.14995 -#: ../en/ch13-mq-collab.xml:402
37.14996 +#: ../en/ch12-mq-collab.xml:402
37.14997  msgid ""
37.14998  "There are two reasons to divide backport patches into a distinct group, away "
37.14999  "from the <quote>regular</quote> patches whose effects they modify. The first "
37.15000 @@ -15734,17 +14812,17 @@
37.15001  msgstr ""
37.15002  
37.15003  #. type: Content of: <book><chapter><sect1><title>
37.15004 -#: ../en/ch13-mq-collab.xml:417
37.15005 +#: ../en/ch12-mq-collab.xml:417
37.15006  msgid "Useful tips for developing with MQ"
37.15007  msgstr "使用 MQ 开发的技巧"
37.15008  
37.15009  #. type: Content of: <book><chapter><sect1><sect2><title>
37.15010 -#: ../en/ch13-mq-collab.xml:420
37.15011 +#: ../en/ch12-mq-collab.xml:420
37.15012  msgid "Organising patches in directories"
37.15013  msgstr "将补丁放到几个目录中"
37.15014  
37.15015  #. type: Content of: <book><chapter><sect1><sect2><para>
37.15016 -#: ../en/ch13-mq-collab.xml:422
37.15017 +#: ../en/ch12-mq-collab.xml:422
37.15018  msgid ""
37.15019  "If you're working on a substantial project with MQ, it's not difficult to "
37.15020  "accumulate a large number of patches.  For example, I have one patch "
37.15021 @@ -15752,7 +14830,7 @@
37.15022  msgstr ""
37.15023  
37.15024  #. type: Content of: <book><chapter><sect1><sect2><para>
37.15025 -#: ../en/ch13-mq-collab.xml:427
37.15026 +#: ../en/ch12-mq-collab.xml:427
37.15027  msgid ""
37.15028  "If you can group these patches into separate logical categories, you can if "
37.15029  "you like store them in different directories; MQ has no problems with patch "
37.15030 @@ -15760,12 +14838,12 @@
37.15031  msgstr ""
37.15032  
37.15033  #. type: Content of: <book><chapter><sect1><sect2><title>
37.15034 -#: ../en/ch13-mq-collab.xml:434
37.15035 +#: ../en/ch12-mq-collab.xml:434
37.15036  msgid "Viewing the history of a patch"
37.15037  msgstr "察看补丁的历史"
37.15038  
37.15039  #. type: Content of: <book><chapter><sect1><sect2><para>
37.15040 -#: ../en/ch13-mq-collab.xml:436
37.15041 +#: ../en/ch12-mq-collab.xml:436
37.15042  msgid ""
37.15043  "If you're developing a set of patches over a long time, it's a good idea to "
37.15044  "maintain them in a repository, as discussed in section <xref linkend=\"sec.mq."
37.15045 @@ -15778,7 +14856,7 @@
37.15046  msgstr ""
37.15047  
37.15048  #. type: Content of: <book><chapter><sect1><sect2><para>
37.15049 -#: ../en/ch13-mq-collab.xml:448
37.15050 +#: ../en/ch12-mq-collab.xml:448
37.15051  msgid ""
37.15052  "However, you can use the <literal role=\"hg-ext\">extdiff</literal> "
37.15053  "extension, which is bundled with Mercurial, to turn a diff of two versions of "
37.15054 @@ -15791,18 +14869,18 @@
37.15055  msgstr ""
37.15056  
37.15057  #. type: Content of: <book><chapter><sect1><sect2><para>
37.15058 -#: ../en/ch13-mq-collab.xml:459
37.15059 +#: ../en/ch12-mq-collab.xml:459
37.15060  msgid ""
37.15061  "You can enable the <literal role=\"hg-ext\">extdiff</literal> extension in "
37.15062  "the usual way, by adding a line to the <literal role=\"rc-extensions"
37.15063 -"\">extensions</literal> section of your <filename role=\"special\"> /.hgrc</"
37.15064 +"\">extensions</literal> section of your <filename role=\"special\">~/.hgrc</"
37.15065  "filename>."
37.15066  msgstr ""
37.15067  
37.15068  #
37.15069  #. 	&example.hg-interdiff; 
37.15070  #. type: Content of: <book><chapter><sect1><sect2><para>
37.15071 -#: ../en/ch13-mq-collab.xml:465
37.15072 +#: ../en/ch12-mq-collab.xml:466
37.15073  msgid ""
37.15074  "The <command>interdiff</command> command expects to be passed the names of "
37.15075  "two files, but the <literal role=\"hg-ext\">extdiff</literal> extension "
37.15076 @@ -15815,7 +14893,7 @@
37.15077  msgstr ""
37.15078  
37.15079  #. type: Content of: <book><chapter><sect1><sect2><para>
37.15080 -#: ../en/ch13-mq-collab.xml:477
37.15081 +#: ../en/ch12-mq-collab.xml:478
37.15082  msgid ""
37.15083  "With the <filename role=\"special\">hg-interdiff</filename> program in your "
37.15084  "shell's search path, you can run it as follows, from inside an MQ patch "
37.15085 @@ -15823,16 +14901,16 @@
37.15086  msgstr ""
37.15087  
37.15088  #. type: Content of: <book><chapter><sect1><sect2><para>
37.15089 -#: ../en/ch13-mq-collab.xml:482
37.15090 +#: ../en/ch12-mq-collab.xml:482
37.15091  msgid ""
37.15092  "Since you'll probably want to use this long-winded command a lot, you can get "
37.15093  "<literal role=\"hg-ext\">hgext</literal> to make it available as a normal "
37.15094 -"Mercurial command, again by editing your <filename role=\"special\"> /.hgrc</"
37.15095 +"Mercurial command, again by editing your <filename role=\"special\">~/.hgrc</"
37.15096  "filename>."
37.15097  msgstr ""
37.15098  
37.15099  #. type: Content of: <book><chapter><sect1><sect2><para>
37.15100 -#: ../en/ch13-mq-collab.xml:489
37.15101 +#: ../en/ch12-mq-collab.xml:489
37.15102  msgid ""
37.15103  "This directs <literal role=\"hg-ext\">hgext</literal> to make an "
37.15104  "<literal>interdiff</literal> command available, so you can now shorten the "
37.15105 @@ -15841,7 +14919,7 @@
37.15106  msgstr ""
37.15107  
37.15108  #. type: Content of: <book><chapter><sect1><sect2><note><para>
37.15109 -#: ../en/ch13-mq-collab.xml:498
37.15110 +#: ../en/ch12-mq-collab.xml:497
37.15111  msgid ""
37.15112  "The <command>interdiff</command> command works well only if the underlying "
37.15113  "files against which versions of a patch are generated remain the same.  If "
37.15114 @@ -15850,7 +14928,7 @@
37.15115  msgstr ""
37.15116  
37.15117  #. type: Content of: <book><chapter><sect1><sect2><para>
37.15118 -#: ../en/ch13-mq-collab.xml:506
37.15119 +#: ../en/ch12-mq-collab.xml:505
37.15120  msgid ""
37.15121  "The <literal role=\"hg-ext\">extdiff</literal> extension is useful for more "
37.15122  "than merely improving the presentation of MQ patches.  To read more about it, "
37.15123 @@ -15858,12 +14936,12 @@
37.15124  msgstr ""
37.15125  
37.15126  #. type: Content of: <book><chapter><title>
37.15127 -#: ../en/ch14-hgext.xml:5
37.15128 +#: ../en/ch13-hgext.xml:5
37.15129  msgid "Adding functionality with extensions"
37.15130  msgstr "使用扩展增加功能"
37.15131  
37.15132  #. type: Content of: <book><chapter><para>
37.15133 -#: ../en/ch14-hgext.xml:7
37.15134 +#: ../en/ch13-hgext.xml:7
37.15135  msgid ""
37.15136  "While the core of Mercurial is quite complete from a functionality "
37.15137  "standpoint, it's deliberately shorn of fancy features.  This approach of "
37.15138 @@ -15872,7 +14950,7 @@
37.15139  msgstr ""
37.15140  
37.15141  #. type: Content of: <book><chapter><para>
37.15142 -#: ../en/ch14-hgext.xml:12
37.15143 +#: ../en/ch13-hgext.xml:12
37.15144  msgid ""
37.15145  "However, Mercurial doesn't box you in with an inflexible command set: you can "
37.15146  "add features to it as <emphasis>extensions</emphasis> (sometimes known as "
37.15147 @@ -15881,7 +14959,7 @@
37.15148  msgstr ""
37.15149  
37.15150  #. type: Content of: <book><chapter><itemizedlist><listitem><para>
37.15151 -#: ../en/ch14-hgext.xml:18
37.15152 +#: ../en/ch13-hgext.xml:18
37.15153  msgid ""
37.15154  "Section <xref linkend=\"sec.tour-merge.fetch\"/> covers the <literal role="
37.15155  "\"hg-ext\">fetch</literal> extension; this combines pulling new changes and "
37.15156 @@ -15890,7 +14968,7 @@
37.15157  msgstr ""
37.15158  
37.15159  #. type: Content of: <book><chapter><itemizedlist><listitem><para>
37.15160 -#: ../en/ch14-hgext.xml:24
37.15161 +#: ../en/ch13-hgext.xml:24
37.15162  msgid ""
37.15163  "In chapter <xref linkend=\"chap.hook\"/>, we covered several extensions that "
37.15164  "are useful for hook-related functionality: <literal role=\"hg-ext\">acl</"
37.15165 @@ -15900,7 +14978,7 @@
37.15166  msgstr ""
37.15167  
37.15168  #. type: Content of: <book><chapter><itemizedlist><listitem><para>
37.15169 -#: ../en/ch14-hgext.xml:33
37.15170 +#: ../en/ch13-hgext.xml:33
37.15171  msgid ""
37.15172  "The Mercurial Queues patch management extension is so invaluable that it "
37.15173  "merits two chapters and an appendix all to itself. Chapter <xref linkend="
37.15174 @@ -15910,7 +14988,7 @@
37.15175  msgstr ""
37.15176  
37.15177  #. type: Content of: <book><chapter><para>
37.15178 -#: ../en/ch14-hgext.xml:43
37.15179 +#: ../en/ch13-hgext.xml:43
37.15180  msgid ""
37.15181  "In this chapter, we'll cover some of the other extensions that are available "
37.15182  "for Mercurial, and briefly touch on some of the machinery you'll need to know "
37.15183 @@ -15918,7 +14996,7 @@
37.15184  msgstr ""
37.15185  
37.15186  #. type: Content of: <book><chapter><itemizedlist><listitem><para>
37.15187 -#: ../en/ch14-hgext.xml:48
37.15188 +#: ../en/ch13-hgext.xml:48
37.15189  msgid ""
37.15190  "In section <xref linkend=\"sec.hgext.inotify\"/>, we'll discuss the "
37.15191  "possibility of <emphasis>huge</emphasis> performance improvements using the "
37.15192 @@ -15926,21 +15004,21 @@
37.15193  msgstr ""
37.15194  
37.15195  #. type: Content of: <book><chapter><sect1><title>
37.15196 -#: ../en/ch14-hgext.xml:55
37.15197 +#: ../en/ch13-hgext.xml:55
37.15198  msgid ""
37.15199  "Improve performance with the <literal role=\"hg-ext\">inotify</literal> "
37.15200  "extension"
37.15201  msgstr "使用扩展 <literal role=\"hg-ext\">inotify</literal> 以提高性能"
37.15202  
37.15203  #. type: Content of: <book><chapter><sect1><para>
37.15204 -#: ../en/ch14-hgext.xml:58
37.15205 +#: ../en/ch13-hgext.xml:58
37.15206  msgid ""
37.15207  "Are you interested in having some of the most common Mercurial operations run "
37.15208  "as much as a hundred times faster? Read on!"
37.15209  msgstr ""
37.15210  
37.15211  #. type: Content of: <book><chapter><sect1><para>
37.15212 -#: ../en/ch14-hgext.xml:62
37.15213 +#: ../en/ch13-hgext.xml:62
37.15214  msgid ""
37.15215  "Mercurial has great performance under normal circumstances.  For example, "
37.15216  "when you run the <command role=\"hg-cmd\">hg status</command> command, "
37.15217 @@ -15952,7 +15030,7 @@
37.15218  msgstr ""
37.15219  
37.15220  #. type: Content of: <book><chapter><sect1><para>
37.15221 -#: ../en/ch14-hgext.xml:72
37.15222 +#: ../en/ch13-hgext.xml:72
37.15223  msgid ""
37.15224  "Because obtaining file status is crucial to good performance, the authors of "
37.15225  "Mercurial have optimised this code to within an inch of its life.  However, "
37.15226 @@ -15964,7 +15042,7 @@
37.15227  msgstr ""
37.15228  
37.15229  #. type: Content of: <book><chapter><sect1><para>
37.15230 -#: ../en/ch14-hgext.xml:82
37.15231 +#: ../en/ch13-hgext.xml:82
37.15232  msgid ""
37.15233  "To put a number on the magnitude of this effect, I created a repository "
37.15234  "containing 150,000 managed files.  I timed <command role=\"hg-cmd\">hg "
37.15235 @@ -15973,7 +15051,7 @@
37.15236  msgstr ""
37.15237  
37.15238  #. type: Content of: <book><chapter><sect1><para>
37.15239 -#: ../en/ch14-hgext.xml:88
37.15240 +#: ../en/ch13-hgext.xml:88
37.15241  msgid ""
37.15242  "Many modern operating systems contain a file notification facility. If a "
37.15243  "program signs up to an appropriate service, the operating system will notify "
37.15244 @@ -15983,7 +15061,7 @@
37.15245  msgstr ""
37.15246  
37.15247  #. type: Content of: <book><chapter><sect1><para>
37.15248 -#: ../en/ch14-hgext.xml:95
37.15249 +#: ../en/ch13-hgext.xml:95
37.15250  msgid ""
37.15251  "Mercurial's <literal role=\"hg-ext\">inotify</literal> extension talks to the "
37.15252  "kernel's <literal>inotify</literal> component to optimise <command role=\"hg-"
37.15253 @@ -15998,7 +15076,7 @@
37.15254  msgstr ""
37.15255  
37.15256  #. type: Content of: <book><chapter><sect1><para>
37.15257 -#: ../en/ch14-hgext.xml:108
37.15258 +#: ../en/ch13-hgext.xml:108
37.15259  msgid ""
37.15260  "Recall the ten seconds that I measured plain Mercurial as taking to run "
37.15261  "<command role=\"hg-cmd\">hg status</command> on a 150,000 file repository.  "
37.15262 @@ -16008,12 +15086,12 @@
37.15263  msgstr ""
37.15264  
37.15265  #. type: Content of: <book><chapter><sect1><para>
37.15266 -#: ../en/ch14-hgext.xml:115
37.15267 +#: ../en/ch13-hgext.xml:115
37.15268  msgid "Before we continue, please pay attention to some caveats."
37.15269  msgstr ""
37.15270  
37.15271  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.15272 -#: ../en/ch14-hgext.xml:118
37.15273 +#: ../en/ch13-hgext.xml:118
37.15274  msgid ""
37.15275  "The <literal role=\"hg-ext\">inotify</literal> extension is Linux-specific.  "
37.15276  "Because it interfaces directly to the Linux kernel's <literal>inotify</"
37.15277 @@ -16021,7 +15099,7 @@
37.15278  msgstr ""
37.15279  
37.15280  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.15281 -#: ../en/ch14-hgext.xml:123
37.15282 +#: ../en/ch13-hgext.xml:123
37.15283  msgid ""
37.15284  "It should work on any Linux distribution that was released after early 2005.  "
37.15285  "Older distributions are likely to have a kernel that lacks <literal>inotify</"
37.15286 @@ -16030,7 +15108,7 @@
37.15287  msgstr ""
37.15288  
37.15289  #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
37.15290 -#: ../en/ch14-hgext.xml:130
37.15291 +#: ../en/ch13-hgext.xml:130
37.15292  msgid ""
37.15293  "Not all filesystems are suitable for use with the <literal role=\"hg-ext"
37.15294  "\">inotify</literal> extension.  Network filesystems such as NFS are a non-"
37.15295 @@ -16042,7 +15120,7 @@
37.15296  msgstr ""
37.15297  
37.15298  #. type: Content of: <book><chapter><sect1><para>
37.15299 -#: ../en/ch14-hgext.xml:141
37.15300 +#: ../en/ch13-hgext.xml:141
37.15301  msgid ""
37.15302  "The <literal role=\"hg-ext\">inotify</literal> extension is not yet shipped "
37.15303  "with Mercurial as of May 2007, so it's a little more involved to set up than "
37.15304 @@ -16050,7 +15128,7 @@
37.15305  msgstr ""
37.15306  
37.15307  #. type: Content of: <book><chapter><sect1><para>
37.15308 -#: ../en/ch14-hgext.xml:146
37.15309 +#: ../en/ch13-hgext.xml:146
37.15310  msgid ""
37.15311  "The extension currently comes in two parts: a set of patches to the Mercurial "
37.15312  "source code, and a library of Python bindings to the <literal>inotify</"
37.15313 @@ -16058,7 +15136,7 @@
37.15314  msgstr ""
37.15315  
37.15316  #. type: Content of: <book><chapter><sect1><note><para>
37.15317 -#: ../en/ch14-hgext.xml:150
37.15318 +#: ../en/ch13-hgext.xml:150
37.15319  msgid ""
37.15320  "There are <emphasis>two</emphasis> Python <literal>inotify</literal> binding "
37.15321  "libraries.  One of them is called <literal>pyinotify</literal>, and is "
37.15322 @@ -16068,14 +15146,14 @@
37.15323  msgstr ""
37.15324  
37.15325  #. type: Content of: <book><chapter><sect1><para>
37.15326 -#: ../en/ch14-hgext.xml:157
37.15327 +#: ../en/ch13-hgext.xml:157
37.15328  msgid ""
37.15329  "To get going, it's best to already have a functioning copy of Mercurial "
37.15330  "installed."
37.15331  msgstr ""
37.15332  
37.15333  #. type: Content of: <book><chapter><sect1><note><para>
37.15334 -#: ../en/ch14-hgext.xml:160
37.15335 +#: ../en/ch13-hgext.xml:160
37.15336  msgid ""
37.15337  "If you follow the instructions below, you'll be <emphasis>replacing</"
37.15338  "emphasis> and overwriting any existing installation of Mercurial that you "
37.15339 @@ -16084,14 +15162,14 @@
37.15340  msgstr ""
37.15341  
37.15342  #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
37.15343 -#: ../en/ch14-hgext.xml:167
37.15344 +#: ../en/ch13-hgext.xml:167
37.15345  msgid ""
37.15346  "Clone the Python <literal>inotify</literal> binding repository.  Build and "
37.15347  "install it."
37.15348  msgstr ""
37.15349  
37.15350  #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
37.15351 -#: ../en/ch14-hgext.xml:175
37.15352 +#: ../en/ch13-hgext.xml:174
37.15353  msgid ""
37.15354  "Clone the <filename class=\"directory\">crew</filename> Mercurial "
37.15355  "repository.  Clone the <literal role=\"hg-ext\">inotify</literal> patch "
37.15356 @@ -16100,7 +15178,7 @@
37.15357  msgstr ""
37.15358  
37.15359  #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
37.15360 -#: ../en/ch14-hgext.xml:188
37.15361 +#: ../en/ch13-hgext.xml:184
37.15362  msgid ""
37.15363  "Make sure that you have the Mercurial Queues extension, <literal role=\"hg-ext"
37.15364  "\">mq</literal>, enabled.  If you've never used MQ, read section <xref "
37.15365 @@ -16108,7 +15186,7 @@
37.15366  msgstr ""
37.15367  
37.15368  #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
37.15369 -#: ../en/ch14-hgext.xml:194
37.15370 +#: ../en/ch13-hgext.xml:190
37.15371  msgid ""
37.15372  "Go into the <filename class=\"directory\">inotify</filename> repo, and apply "
37.15373  "all of the <literal role=\"hg-ext\">inotify</literal> patches using the "
37.15374 @@ -16117,27 +15195,27 @@
37.15375  msgstr ""
37.15376  
37.15377  #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
37.15378 -#: ../en/ch14-hgext.xml:204
37.15379 +#: ../en/ch13-hgext.xml:199
37.15380  msgid ""
37.15381  "If you get an error message from <command role=\"hg-ext-mq\">qpush</command>, "
37.15382  "you should not continue.  Instead, ask for help."
37.15383  msgstr ""
37.15384  
37.15385  #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
37.15386 -#: ../en/ch14-hgext.xml:208
37.15387 +#: ../en/ch13-hgext.xml:203
37.15388  msgid "Build and install the patched version of Mercurial."
37.15389  msgstr ""
37.15390  
37.15391  #. type: Content of: <book><chapter><sect1><para>
37.15392 -#: ../en/ch14-hgext.xml:216
37.15393 +#: ../en/ch13-hgext.xml:209
37.15394  msgid ""
37.15395  "Once you've build a suitably patched version of Mercurial, all you need to do "
37.15396  "to enable the <literal role=\"hg-ext\">inotify</literal> extension is add an "
37.15397 -"entry to your <filename role=\"special\"> /.hgrc</filename>."
37.15398 -msgstr ""
37.15399 -
37.15400 -#. type: Content of: <book><chapter><sect1><para>
37.15401 -#: ../en/ch14-hgext.xml:221
37.15402 +"entry to your <filename role=\"special\">~/.hgrc</filename>."
37.15403 +msgstr ""
37.15404 +
37.15405 +#. type: Content of: <book><chapter><sect1><para>
37.15406 +#: ../en/ch13-hgext.xml:214
37.15407  msgid ""
37.15408  "When the <literal role=\"hg-ext\">inotify</literal> extension is enabled, "
37.15409  "Mercurial will automatically and transparently start the status daemon the "
37.15410 @@ -16146,7 +15224,7 @@
37.15411  msgstr ""
37.15412  
37.15413  #. type: Content of: <book><chapter><sect1><para>
37.15414 -#: ../en/ch14-hgext.xml:227
37.15415 +#: ../en/ch13-hgext.xml:220
37.15416  msgid ""
37.15417  "The status daemon is started silently, and runs in the background.  If you "
37.15418  "look at a list of running processes after you've enabled the <literal role="
37.15419 @@ -16156,7 +15234,7 @@
37.15420  msgstr ""
37.15421  
37.15422  #. type: Content of: <book><chapter><sect1><para>
37.15423 -#: ../en/ch14-hgext.xml:235
37.15424 +#: ../en/ch13-hgext.xml:228
37.15425  msgid ""
37.15426  "The first time you run a Mercurial command in a repository when you have the "
37.15427  "<literal role=\"hg-ext\">inotify</literal> extension enabled, it will run "
37.15428 @@ -16172,7 +15250,7 @@
37.15429  msgstr ""
37.15430  
37.15431  #. type: Content of: <book><chapter><sect1><para>
37.15432 -#: ../en/ch14-hgext.xml:249
37.15433 +#: ../en/ch13-hgext.xml:242
37.15434  msgid ""
37.15435  "If you like, you can manually start a status daemon using the <command role="
37.15436  "\"hg-ext-inotify\">inserve</command> command.  This gives you slightly finer "
37.15437 @@ -16182,7 +15260,7 @@
37.15438  msgstr ""
37.15439  
37.15440  #. type: Content of: <book><chapter><sect1><para>
37.15441 -#: ../en/ch14-hgext.xml:256
37.15442 +#: ../en/ch13-hgext.xml:249
37.15443  msgid ""
37.15444  "When you're using the <literal role=\"hg-ext\">inotify</literal> extension, "
37.15445  "you should notice <emphasis>no difference at all</emphasis> in Mercurial's "
37.15446 @@ -16193,14 +15271,14 @@
37.15447  msgstr ""
37.15448  
37.15449  #. type: Content of: <book><chapter><sect1><title>
37.15450 -#: ../en/ch14-hgext.xml:267
37.15451 +#: ../en/ch13-hgext.xml:260
37.15452  msgid ""
37.15453  "Flexible diff support with the <literal role=\"hg-ext\">extdiff</literal> "
37.15454  "extension"
37.15455  msgstr "使用扩展 <literal role=\"hg-ext\">extdiff</literal> 以扩展差异支持"
37.15456  
37.15457  #. type: Content of: <book><chapter><sect1><para>
37.15458 -#: ../en/ch14-hgext.xml:270
37.15459 +#: ../en/ch13-hgext.xml:263
37.15460  msgid ""
37.15461  "Mercurial's built-in <command role=\"hg-cmd\">hg diff</command> command "
37.15462  "outputs plaintext unified diffs."
37.15463 @@ -16209,7 +15287,7 @@
37.15464  "不同。"
37.15465  
37.15466  #. type: Content of: <book><chapter><sect1><para>
37.15467 -#: ../en/ch14-hgext.xml:275
37.15468 +#: ../en/ch13-hgext.xml:268
37.15469  msgid ""
37.15470  "If you would like to use an external tool to display modifications, you'll "
37.15471  "want to use the <literal role=\"hg-ext\">extdiff</literal> extension.  This "
37.15472 @@ -16217,16 +15295,16 @@
37.15473  msgstr ""
37.15474  
37.15475  #. type: Content of: <book><chapter><sect1><para>
37.15476 -#: ../en/ch14-hgext.xml:280
37.15477 +#: ../en/ch13-hgext.xml:273
37.15478  msgid ""
37.15479  "The <literal role=\"hg-ext\">extdiff</literal> extension is bundled with "
37.15480  "Mercurial, so it's easy to set up.  In the <literal role=\"rc-extensions"
37.15481 -"\">extensions</literal> section of your <filename role=\"special\"> /.hgrc</"
37.15482 +"\">extensions</literal> section of your <filename role=\"special\">~/.hgrc</"
37.15483  "filename>, simply add a one-line entry to enable the extension."
37.15484  msgstr ""
37.15485  
37.15486  #. type: Content of: <book><chapter><sect1><para>
37.15487 -#: ../en/ch14-hgext.xml:286
37.15488 +#: ../en/ch13-hgext.xml:280
37.15489  msgid ""
37.15490  "This introduces a command named <command role=\"hg-ext-extdiff\">extdiff</"
37.15491  "command>, which by default uses your system's <command>diff</command> command "
37.15492 @@ -16235,7 +15313,7 @@
37.15493  msgstr ""
37.15494  
37.15495  #. type: Content of: <book><chapter><sect1><para>
37.15496 -#: ../en/ch14-hgext.xml:294
37.15497 +#: ../en/ch13-hgext.xml:288
37.15498  msgid ""
37.15499  "The result won't be exactly the same as with the built-in <command role=\"hg-"
37.15500  "cmd\">hg diff</command> variations, because the output of <command>diff</"
37.15501 @@ -16243,7 +15321,7 @@
37.15502  msgstr ""
37.15503  
37.15504  #. type: Content of: <book><chapter><sect1><para>
37.15505 -#: ../en/ch14-hgext.xml:299
37.15506 +#: ../en/ch13-hgext.xml:293
37.15507  msgid ""
37.15508  "As the <quote><literal>making snapshot</literal></quote> lines of output "
37.15509  "above imply, the <command role=\"hg-ext-extdiff\">extdiff</command> command "
37.15510 @@ -16257,7 +15335,7 @@
37.15511  msgstr ""
37.15512  
37.15513  #. type: Content of: <book><chapter><sect1><para>
37.15514 -#: ../en/ch14-hgext.xml:312
37.15515 +#: ../en/ch13-hgext.xml:306
37.15516  msgid ""
37.15517  "Snapshot directory names have the same base name as your repository. If your "
37.15518  "repository path is <filename class=\"directory\">/quux/bar/foo</filename>, "
37.15519 @@ -16274,7 +15352,7 @@
37.15520  msgstr ""
37.15521  
37.15522  #. type: Content of: <book><chapter><sect1><para>
37.15523 -#: ../en/ch14-hgext.xml:328
37.15524 +#: ../en/ch13-hgext.xml:322
37.15525  msgid ""
37.15526  "The <command role=\"hg-ext-extdiff\">extdiff</command> command accepts two "
37.15527  "important options. The <option role=\"hg-ext-extdiff-cmd-extdiff-opt\">hg -p</"
37.15528 @@ -16292,7 +15370,7 @@
37.15529  
37.15530  #
37.15531  #. type: Content of: <book><chapter><sect1><para>
37.15532 -#: ../en/ch14-hgext.xml:345
37.15533 +#: ../en/ch13-hgext.xml:339
37.15534  msgid ""
37.15535  "As an example, here's how to run the normal system <command>diff</command> "
37.15536  "command, getting it to generate context diffs (using the <option role=\"cmd-"
37.15537 @@ -16302,14 +15380,14 @@
37.15538  msgstr ""
37.15539  
37.15540  #. type: Content of: <book><chapter><sect1><para>
37.15541 -#: ../en/ch14-hgext.xml:354
37.15542 +#: ../en/ch13-hgext.xml:348
37.15543  msgid ""
37.15544  "Launching a visual diff tool is just as easy.  Here's how to launch the "
37.15545  "<command>kdiff3</command> viewer."
37.15546  msgstr ""
37.15547  
37.15548  #. type: Content of: <book><chapter><sect1><para>
37.15549 -#: ../en/ch14-hgext.xml:358
37.15550 +#: ../en/ch13-hgext.xml:352
37.15551  msgid ""
37.15552  "If your diff viewing command can't deal with directories, you can easily work "
37.15553  "around this with a little scripting.  For an example of such scripting in "
37.15554 @@ -16319,12 +15397,12 @@
37.15555  msgstr ""
37.15556  
37.15557  #. type: Content of: <book><chapter><sect1><sect2><title>
37.15558 -#: ../en/ch14-hgext.xml:366
37.15559 +#: ../en/ch13-hgext.xml:360
37.15560  msgid "Defining command aliases"
37.15561  msgstr "定义命令的别名"
37.15562  
37.15563  #. type: Content of: <book><chapter><sect1><sect2><para>
37.15564 -#: ../en/ch14-hgext.xml:368
37.15565 +#: ../en/ch13-hgext.xml:362
37.15566  msgid ""
37.15567  "It can be cumbersome to remember the options to both the <command role=\"hg-"
37.15568  "ext-extdiff\">extdiff</command> command and the diff viewer you want to use, "
37.15569 @@ -16334,9 +15412,9 @@
37.15570  msgstr ""
37.15571  
37.15572  #. type: Content of: <book><chapter><sect1><sect2><para>
37.15573 -#: ../en/ch14-hgext.xml:375
37.15574 -msgid ""
37.15575 -"All you need to do is edit your <filename role=\"special\"> /.hgrc</"
37.15576 +#: ../en/ch13-hgext.xml:369
37.15577 +msgid ""
37.15578 +"All you need to do is edit your <filename role=\"special\">~/.hgrc</"
37.15579  "filename>, and add a section named <literal role=\"rc-extdiff\">extdiff</"
37.15580  "literal>.  Inside this section, you can define multiple commands.  Here's how "
37.15581  "to add a <literal>kdiff3</literal> command.  Once you've defined this, you "
37.15582 @@ -16346,7 +15424,7 @@
37.15583  msgstr ""
37.15584  
37.15585  #. type: Content of: <book><chapter><sect1><sect2><para>
37.15586 -#: ../en/ch14-hgext.xml:384
37.15587 +#: ../en/ch13-hgext.xml:379
37.15588  msgid ""
37.15589  "If you leave the right hand side of the definition empty, as above, the "
37.15590  "<literal role=\"hg-ext\">extdiff</literal> extension uses the name of the "
37.15591 @@ -16357,7 +15435,7 @@
37.15592  msgstr ""
37.15593  
37.15594  #. type: Content of: <book><chapter><sect1><sect2><para>
37.15595 -#: ../en/ch14-hgext.xml:393
37.15596 +#: ../en/ch13-hgext.xml:389
37.15597  msgid ""
37.15598  "You can also specify the default options that you want to invoke your diff "
37.15599  "viewing program with.  The prefix to use is <quote><literal>opts.</literal></"
37.15600 @@ -16367,19 +15445,19 @@
37.15601  msgstr ""
37.15602  
37.15603  #. type: Content of: <book><chapter><sect1><title>
37.15604 -#: ../en/ch14-hgext.xml:406
37.15605 +#: ../en/ch13-hgext.xml:403
37.15606  msgid ""
37.15607  "Cherrypicking changes with the <literal role=\"hg-ext\">transplant</literal> "
37.15608  "extension"
37.15609  msgstr "使用扩展 <literal role=\"hg-ext\">transplant</literal> 以挑选修改"
37.15610  
37.15611  #. type: Content of: <book><chapter><sect1><para>
37.15612 -#: ../en/ch14-hgext.xml:409
37.15613 +#: ../en/ch13-hgext.xml:406
37.15614  msgid "Need to have a long chat with Brendan about this."
37.15615  msgstr ""
37.15616  
37.15617  #. type: Content of: <book><chapter><sect1><title>
37.15618 -#: ../en/ch14-hgext.xml:413
37.15619 +#: ../en/ch13-hgext.xml:410
37.15620  msgid ""
37.15621  "Send changes via email with the <literal role=\"hg-ext\">patchbomb</literal> "
37.15622  "extension"
37.15623 @@ -16387,7 +15465,7 @@
37.15624  "使用扩展 <literal role=\"hg-ext\">patchbomb</literal> 通过 email 发送修改"
37.15625  
37.15626  #. type: Content of: <book><chapter><sect1><para>
37.15627 -#: ../en/ch14-hgext.xml:416
37.15628 +#: ../en/ch13-hgext.xml:413
37.15629  msgid ""
37.15630  "Many projects have a culture of <quote>change review</quote>, in which people "
37.15631  "send their modifications to a mailing list for others to read and comment on "
37.15632 @@ -16397,7 +15475,7 @@
37.15633  msgstr ""
37.15634  
37.15635  #. type: Content of: <book><chapter><sect1><para>
37.15636 -#: ../en/ch14-hgext.xml:424
37.15637 +#: ../en/ch13-hgext.xml:421
37.15638  msgid ""
37.15639  "Mercurial makes it easy to send changes over email for review or application, "
37.15640  "via its <literal role=\"hg-ext\">patchbomb</literal> extension.  The "
37.15641 @@ -16408,7 +15486,7 @@
37.15642  msgstr ""
37.15643  
37.15644  #. type: Content of: <book><chapter><sect1><para>
37.15645 -#: ../en/ch14-hgext.xml:432
37.15646 +#: ../en/ch13-hgext.xml:429
37.15647  msgid ""
37.15648  "As usual, the basic configuration of the <literal role=\"hg-ext\">patchbomb</"
37.15649  "literal> extension takes just one or two lines in your <filename role="
37.15650 @@ -16416,14 +15494,14 @@
37.15651  msgstr ""
37.15652  
37.15653  #. type: Content of: <book><chapter><sect1><para>
37.15654 -#: ../en/ch14-hgext.xml:437
37.15655 +#: ../en/ch13-hgext.xml:435
37.15656  msgid ""
37.15657  "Once you've enabled the extension, you will have a new command available, "
37.15658  "named <command role=\"hg-ext-patchbomb\">email</command>."
37.15659  msgstr ""
37.15660  
37.15661  #. type: Content of: <book><chapter><sect1><para>
37.15662 -#: ../en/ch14-hgext.xml:441
37.15663 +#: ../en/ch13-hgext.xml:439
37.15664  msgid ""
37.15665  "The safest and best way to invoke the <command role=\"hg-ext-patchbomb"
37.15666  "\">email</command> command is to <emphasis>always</emphasis> run it first "
37.15667 @@ -16436,7 +15514,7 @@
37.15668  msgstr ""
37.15669  
37.15670  #. type: Content of: <book><chapter><sect1><para>
37.15671 -#: ../en/ch14-hgext.xml:452
37.15672 +#: ../en/ch13-hgext.xml:450
37.15673  msgid ""
37.15674  "The <command role=\"hg-ext-patchbomb\">email</command> command accepts the "
37.15675  "same kind of revision syntax as every other Mercurial command.  For example, "
37.15676 @@ -16445,7 +15523,7 @@
37.15677  msgstr ""
37.15678  
37.15679  #. type: Content of: <book><chapter><sect1><para>
37.15680 -#: ../en/ch14-hgext.xml:457
37.15681 +#: ../en/ch13-hgext.xml:455
37.15682  msgid ""
37.15683  "You can also specify a <emphasis>repository</emphasis> to compare with.  If "
37.15684  "you provide a repository but no revisions, the <command role=\"hg-ext-"
37.15685 @@ -16457,7 +15535,7 @@
37.15686  msgstr ""
37.15687  
37.15688  #. type: Content of: <book><chapter><sect1><para>
37.15689 -#: ../en/ch14-hgext.xml:466
37.15690 +#: ../en/ch13-hgext.xml:464
37.15691  msgid ""
37.15692  "It's perfectly safe to run the <command role=\"hg-ext-patchbomb\">email</"
37.15693  "command> command without the names of the people you want to send to: if you "
37.15694 @@ -16468,7 +15546,7 @@
37.15695  msgstr ""
37.15696  
37.15697  #. type: Content of: <book><chapter><sect1><para>
37.15698 -#: ../en/ch14-hgext.xml:474
37.15699 +#: ../en/ch13-hgext.xml:472
37.15700  msgid ""
37.15701  "When you are sending just one revision, the <command role=\"hg-ext-patchbomb"
37.15702  "\">email</command> command will by default use the first line of the "
37.15703 @@ -16476,7 +15554,7 @@
37.15704  msgstr ""
37.15705  
37.15706  #. type: Content of: <book><chapter><sect1><para>
37.15707 -#: ../en/ch14-hgext.xml:479
37.15708 +#: ../en/ch13-hgext.xml:477
37.15709  msgid ""
37.15710  "If you send multiple revisions, the <command role=\"hg-ext-patchbomb\">email</"
37.15711  "command> command will usually send one message per changeset.  It will "
37.15712 @@ -16485,12 +15563,12 @@
37.15713  msgstr ""
37.15714  
37.15715  #. type: Content of: <book><chapter><sect1><sect2><title>
37.15716 -#: ../en/ch14-hgext.xml:486
37.15717 +#: ../en/ch13-hgext.xml:484
37.15718  msgid "Changing the behaviour of patchbombs"
37.15719  msgstr "修改 patchbomb 的行为"
37.15720  
37.15721  #. type: Content of: <book><chapter><sect1><sect2><para>
37.15722 -#: ../en/ch14-hgext.xml:488
37.15723 +#: ../en/ch13-hgext.xml:486
37.15724  msgid ""
37.15725  "Not every project has exactly the same conventions for sending changes in "
37.15726  "email; the <literal role=\"hg-ext\">patchbomb</literal> extension tries to "
37.15727 @@ -16498,7 +15576,7 @@
37.15728  msgstr ""
37.15729  
37.15730  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.15731 -#: ../en/ch14-hgext.xml:494
37.15732 +#: ../en/ch13-hgext.xml:492
37.15733  msgid ""
37.15734  "You can write a subject for the introductory message on the command line "
37.15735  "using the <option role=\"hg-ext-patchbomb-cmd-email-opt\">hg -s</option> "
37.15736 @@ -16506,7 +15584,7 @@
37.15737  msgstr ""
37.15738  
37.15739  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.15740 -#: ../en/ch14-hgext.xml:500
37.15741 +#: ../en/ch13-hgext.xml:498
37.15742  msgid ""
37.15743  "To change the email address from which the messages originate, use the "
37.15744  "<option role=\"hg-ext-patchbomb-cmd-email-opt\">hg -f</option> option.  This "
37.15745 @@ -16514,7 +15592,7 @@
37.15746  msgstr ""
37.15747  
37.15748  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.15749 -#: ../en/ch14-hgext.xml:506
37.15750 +#: ../en/ch13-hgext.xml:504
37.15751  msgid ""
37.15752  "The default behaviour is to send unified diffs (see section <xref linkend="
37.15753  "\"sec.mq.patch\"/> for a description of the format), one per message.  You "
37.15754 @@ -16523,7 +15601,7 @@
37.15755  msgstr ""
37.15756  
37.15757  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.15758 -#: ../en/ch14-hgext.xml:514
37.15759 +#: ../en/ch13-hgext.xml:512
37.15760  msgid ""
37.15761  "Unified diffs are normally prefaced with a metadata header.  You can omit "
37.15762  "this, and send unadorned diffs, with the <option role=\"hg-ext-patchbomb-cmd-"
37.15763 @@ -16531,7 +15609,7 @@
37.15764  msgstr ""
37.15765  
37.15766  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.15767 -#: ../en/ch14-hgext.xml:520
37.15768 +#: ../en/ch13-hgext.xml:518
37.15769  msgid ""
37.15770  "Diffs are normally sent <quote>inline</quote>, in the same body part as the "
37.15771  "description of a patch.  This makes it easiest for the largest number of "
37.15772 @@ -16542,7 +15620,7 @@
37.15773  msgstr ""
37.15774  
37.15775  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.15776 -#: ../en/ch14-hgext.xml:530
37.15777 +#: ../en/ch13-hgext.xml:528
37.15778  msgid ""
37.15779  "Instead of sending mail messages, you can write them to an <literal>mbox</"
37.15780  "literal>-format mail folder using the <option role=\"hg-ext-patchbomb-cmd-"
37.15781 @@ -16551,7 +15629,7 @@
37.15782  msgstr ""
37.15783  
37.15784  #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
37.15785 -#: ../en/ch14-hgext.xml:537
37.15786 +#: ../en/ch13-hgext.xml:535
37.15787  msgid ""
37.15788  "If you would like to add a <command>diffstat</command>-format summary to each "
37.15789  "patch, and one to the introductory message, use the <option role=\"hg-ext-"
37.15790 @@ -16560,3 +15638,60 @@
37.15791  "the number of lines affected, and a histogram showing how much each file is "
37.15792  "modified.  This gives readers a qualitative glance at how complex a patch is."
37.15793  msgstr ""
37.15794 +
37.15795 +#~ msgid "Introduction"
37.15796 +#~ msgstr "简介"
37.15797 +
37.15798 +#~ msgid "About revision control"
37.15799 +#~ msgstr "关于版本控制"
37.15800 +
37.15801 +#~ msgid "Why use revision control?"
37.15802 +#~ msgstr "为什么使用版本控制?"
37.15803 +
37.15804 +#~ msgid "The many names of revision control"
37.15805 +#~ msgstr "版本控制的别名"
37.15806 +
37.15807 +#~ msgid "Revision control (RCS)"
37.15808 +#~ msgstr "版本控制(RCS)"
37.15809 +
37.15810 +#~ msgid "Software configuration management (SCM), or configuration management"
37.15811 +#~ msgstr "软件配置管理(SCM),或配置管理"
37.15812 +
37.15813 +#~ msgid "Source code management"
37.15814 +#~ msgstr "源代码管理"
37.15815 +
37.15816 +#~ msgid "Source code control, or source control"
37.15817 +#~ msgstr "源代码控制,或源控制"
37.15818 +
37.15819 +#~ msgid "Version control (VCS)"
37.15820 +#~ msgstr "版本控制(VCS)"
37.15821 +
37.15822 +#~ msgid "A short history of revision control"
37.15823 +#~ msgstr "版本控制简史"
37.15824 +
37.15825 +#~ msgid "Trends in revision control"
37.15826 +#~ msgstr "版本控制的发展趋势"
37.15827 +
37.15828 +#~ msgid "A few of the advantages of distributed revision control"
37.15829 +#~ msgstr "分布版本控制的优点"
37.15830 +
37.15831 +#~ msgid "Advantages for open source projects"
37.15832 +#~ msgstr "开源项目的优点"
37.15833 +
37.15834 +#~ msgid "Advantages for commercial projects"
37.15835 +#~ msgstr "商业项目的优点"
37.15836 +
37.15837 +#~ msgid "Why choose Mercurial?"
37.15838 +#~ msgstr "为什么选择 Mercurial?"
37.15839 +
37.15840 +#~ msgid "Mercurial compared with other tools"
37.15841 +#~ msgstr "Mercurial 与其它工具的比较"
37.15842 +
37.15843 +#~ msgid "Commercial tools"
37.15844 +#~ msgstr "商业工具"
37.15845 +
37.15846 +#~ msgid "Choosing a revision control tool"
37.15847 +#~ msgstr "选择版本控制工具"
37.15848 +
37.15849 +#~ msgid "Switching from another tool to Mercurial"
37.15850 +#~ msgstr "从其它工具切换到 Mercurial"
    38.1 --- a/web/hgbook/dbutil.py	Fri Mar 20 15:40:06 2009 +0800
    38.2 +++ b/web/hgbook/dbutil.py	Fri Mar 20 16:43:35 2009 +0800
    38.3 @@ -1,4 +1,5 @@
    38.4  import MySQLdb as mysql
    38.5 +import sys
    38.6  
    38.7  def connect():
    38.8      try:
    39.1 --- a/web/hgbook/load_elements.py	Fri Mar 20 15:40:06 2009 +0800
    39.2 +++ b/web/hgbook/load_elements.py	Fri Mar 20 16:43:35 2009 +0800
    39.3 @@ -8,7 +8,7 @@
    39.4  sys.path.append(os.path.dirname(__file__))
    39.5  import dbutil
    39.6  
    39.7 -os.system('make -C ../../en ids')
    39.8 +os.system('make -C ../../en all-ids.dat')
    39.9  
   39.10  conn = dbutil.connect()
   39.11  c = conn.cursor()